Skip to content

Commit afc32d4

Browse files
committed
add TestDownloadTaskLogs
1 parent 9785a49 commit afc32d4

File tree

3 files changed

+124
-29
lines changed

3 files changed

+124
-29
lines changed

tests/integration/actions_job_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestJobWithNeeds(t *testing.T) {
2525
testCases := []struct {
2626
treePath string
2727
fileContent string
28-
execPolicies map[string]*taskExecPolicy
28+
outcomes map[string]*mockTaskOutcome
2929
expectedStatuses map[string]string
3030
}{
3131
{
@@ -46,7 +46,7 @@ jobs:
4646
steps:
4747
- run: echo job2
4848
`,
49-
execPolicies: map[string]*taskExecPolicy{
49+
outcomes: map[string]*mockTaskOutcome{
5050
"job1": {
5151
result: runnerv1.Result_RESULT_SUCCESS,
5252
},
@@ -77,7 +77,7 @@ jobs:
7777
steps:
7878
- run: echo job2
7979
`,
80-
execPolicies: map[string]*taskExecPolicy{
80+
outcomes: map[string]*mockTaskOutcome{
8181
"job1": {
8282
result: runnerv1.Result_RESULT_FAILURE,
8383
},
@@ -106,7 +106,7 @@ jobs:
106106
steps:
107107
- run: echo job2
108108
`,
109-
execPolicies: map[string]*taskExecPolicy{
109+
outcomes: map[string]*mockTaskOutcome{
110110
"job1": {
111111
result: runnerv1.Result_RESULT_FAILURE,
112112
},
@@ -136,12 +136,12 @@ jobs:
136136
fileResp := createWorkflowFile(t, token, user2.Name, apiRepo.Name, tc.treePath, opts)
137137

138138
// fetch and execute task
139-
for i := 0; i < len(tc.execPolicies); i++ {
139+
for i := 0; i < len(tc.outcomes); i++ {
140140
task := runner.fetchTask(t)
141141
jobName := getTaskJobNameByTaskID(t, token, user2.Name, apiRepo.Name, task.Id)
142-
policy := tc.execPolicies[jobName]
143-
assert.NotNil(t, policy)
144-
runner.execTask(t, task, policy)
142+
outcome := tc.outcomes[jobName]
143+
assert.NotNil(t, outcome)
144+
runner.execTask(t, task, outcome)
145145
}
146146

147147
// check result
@@ -169,7 +169,7 @@ func TestJobNeedsMatrix(t *testing.T) {
169169
testCases := []struct {
170170
treePath string
171171
fileContent string
172-
execPolicies map[string]*taskExecPolicy
172+
outcomes map[string]*mockTaskOutcome
173173
expectedTaskNeeds map[string]*runnerv1.TaskNeed // jobID => TaskNeed
174174
}{
175175
{
@@ -201,7 +201,7 @@ jobs:
201201
steps:
202202
- run: echo '${{ toJSON(needs.job1.outputs) }}'
203203
`,
204-
execPolicies: map[string]*taskExecPolicy{
204+
outcomes: map[string]*mockTaskOutcome{
205205
"job1 (1)": {
206206
result: runnerv1.Result_RESULT_SUCCESS,
207207
outputs: map[string]string{
@@ -268,7 +268,7 @@ jobs:
268268
steps:
269269
- run: echo '${{ toJSON(needs.job1.outputs) }}'
270270
`,
271-
execPolicies: map[string]*taskExecPolicy{
271+
outcomes: map[string]*mockTaskOutcome{
272272
"job1 (1)": {
273273
result: runnerv1.Result_RESULT_SUCCESS,
274274
outputs: map[string]string{
@@ -320,12 +320,12 @@ jobs:
320320
opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, fmt.Sprintf("create %s", tc.treePath), tc.fileContent)
321321
createWorkflowFile(t, token, user2.Name, apiRepo.Name, tc.treePath, opts)
322322

323-
for i := 0; i < len(tc.execPolicies); i++ {
323+
for i := 0; i < len(tc.outcomes); i++ {
324324
task := runner.fetchTask(t)
325325
jobName := getTaskJobNameByTaskID(t, token, user2.Name, apiRepo.Name, task.Id)
326-
policy := tc.execPolicies[jobName]
327-
assert.NotNil(t, policy)
328-
runner.execTask(t, task, policy)
326+
outcome := tc.outcomes[jobName]
327+
assert.NotNil(t, outcome)
328+
runner.execTask(t, task, outcome)
329329
}
330330

331331
task := runner.fetchTask(t)

tests/integration/actions_log_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright 2024 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package integration
5+
6+
import (
7+
"fmt"
8+
"net/http"
9+
"net/url"
10+
"strings"
11+
"testing"
12+
"time"
13+
14+
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
15+
auth_model "code.gitea.io/gitea/models/auth"
16+
repo_model "code.gitea.io/gitea/models/repo"
17+
"code.gitea.io/gitea/models/unittest"
18+
user_model "code.gitea.io/gitea/models/user"
19+
"code.gitea.io/gitea/modules/setting"
20+
"code.gitea.io/gitea/modules/storage"
21+
"google.golang.org/protobuf/types/known/timestamppb"
22+
23+
"github.com/stretchr/testify/assert"
24+
)
25+
26+
func TestDownloadTaskLogs(t *testing.T) {
27+
onGiteaRun(t, func(t *testing.T, u *url.URL) {
28+
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
29+
session := loginUser(t, user2.Name)
30+
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
31+
32+
apiRepo := createActionsTestRepo(t, token, "actions-download-task-logs", false)
33+
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
34+
runner := newMockRunner()
35+
runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"})
36+
37+
treePath := ".gitea/workflows/download-task-logs.yml"
38+
fileContent := `name: download-task-logs
39+
on: push
40+
jobs:
41+
job1:
42+
runs-on: ubuntu-latest
43+
steps:
44+
- run: echo job1
45+
`
46+
47+
// create the workflow file
48+
opts := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, fmt.Sprintf("create %s", treePath), fileContent)
49+
createWorkflowFile(t, token, user2.Name, repo.Name, treePath, opts)
50+
51+
now := time.Now()
52+
outcome := &mockTaskOutcome{
53+
result: runnerv1.Result_RESULT_SUCCESS,
54+
logRows: []*runnerv1.LogRow{
55+
{
56+
Time: timestamppb.New(now),
57+
Content: " \U0001F433 docker create image",
58+
},
59+
{
60+
Time: timestamppb.New(now.Add(5 * time.Second)),
61+
Content: "job1",
62+
},
63+
{
64+
Time: timestamppb.New(now.Add(8 * time.Second)),
65+
Content: "\U0001F3C1 Job succeeded",
66+
},
67+
},
68+
}
69+
70+
// fetch and execute task
71+
task := runner.fetchTask(t)
72+
runner.execTask(t, task, outcome)
73+
74+
// check whether the log file exists
75+
logFileName := fmt.Sprintf("%s/%02x/%d.log", repo.FullName(), task.Id%256, task.Id)
76+
if setting.Actions.LogCompression.IsZstd() {
77+
logFileName += ".zst"
78+
}
79+
_, err := storage.Actions.Stat(logFileName)
80+
assert.NoError(t, err)
81+
82+
// download task logs and check content
83+
runIndex := task.Context.GetFields()["run_number"].String()
84+
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/actions/runs/%s/jobs/0/logs", user2.Name, repo.Name, runIndex)).
85+
AddTokenAuth(token)
86+
resp := MakeRequest(t, req, http.StatusOK)
87+
logTextLines := strings.Split(strings.TrimSpace(resp.Body.String()), "\n")
88+
assert.Len(t, logTextLines, len(outcome.logRows))
89+
for idx, lr := range outcome.logRows {
90+
assert.Equal(
91+
t,
92+
fmt.Sprintf("%s %s", lr.Time.AsTime().Format("2006-01-02T15:04:05.0000000Z07:00"), lr.Content),
93+
logTextLines[idx],
94+
)
95+
}
96+
97+
httpContext := NewAPITestContext(t, user2.Name, repo.Name, auth_model.AccessTokenScopeWriteRepository)
98+
doAPIDeleteRepository(httpContext)(t)
99+
})
100+
}

tests/integration/actions_runner_test.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ import (
2424

2525
type mockRunner struct {
2626
client *mockRunnerClient
27-
28-
id int64
29-
name string
3027
}
3128

3229
type mockRunnerClient struct {
@@ -79,8 +76,6 @@ func (r *mockRunner) doRegister(t *testing.T, name, token string, labels []strin
7976
Labels: labels,
8077
}))
8178
assert.NoError(t, err)
82-
r.id = resp.Msg.Runner.Id
83-
r.name = resp.Msg.Runner.Name
8479
r.client = newMockRunnerClient(resp.Msg.Runner.Uuid, resp.Msg.Runner.Token)
8580
}
8681

@@ -118,26 +113,26 @@ func (r *mockRunner) fetchTask(t *testing.T, timeout ...time.Duration) *runnerv1
118113
return task
119114
}
120115

121-
type taskExecPolicy struct {
116+
type mockTaskOutcome struct {
122117
result runnerv1.Result
123118
outputs map[string]string
124119
logRows []*runnerv1.LogRow
125120
execTime time.Duration
126121
}
127122

128-
func (r *mockRunner) execTask(t *testing.T, task *runnerv1.Task, policy *taskExecPolicy) {
129-
for idx, lr := range policy.logRows {
123+
func (r *mockRunner) execTask(t *testing.T, task *runnerv1.Task, outcome *mockTaskOutcome) {
124+
for idx, lr := range outcome.logRows {
130125
resp, err := r.client.runnerServiceClient.UpdateLog(context.Background(), connect.NewRequest(&runnerv1.UpdateLogRequest{
131126
TaskId: task.Id,
132127
Index: int64(idx),
133128
Rows: []*runnerv1.LogRow{lr},
134-
NoMore: idx == len(policy.logRows)-1,
129+
NoMore: idx == len(outcome.logRows)-1,
135130
}))
136131
assert.NoError(t, err)
137132
assert.EqualValues(t, idx+1, resp.Msg.AckIndex)
138133
}
139-
sentOutputKeys := make([]string, 0, len(policy.outputs))
140-
for outputKey, outputValue := range policy.outputs {
134+
sentOutputKeys := make([]string, 0, len(outcome.outputs))
135+
for outputKey, outputValue := range outcome.outputs {
141136
resp, err := r.client.runnerServiceClient.UpdateTask(context.Background(), connect.NewRequest(&runnerv1.UpdateTaskRequest{
142137
State: &runnerv1.TaskState{
143138
Id: task.Id,
@@ -149,14 +144,14 @@ func (r *mockRunner) execTask(t *testing.T, task *runnerv1.Task, policy *taskExe
149144
sentOutputKeys = append(sentOutputKeys, outputKey)
150145
assert.ElementsMatch(t, sentOutputKeys, resp.Msg.SentOutputs)
151146
}
152-
time.Sleep(policy.execTime)
147+
time.Sleep(outcome.execTime)
153148
resp, err := r.client.runnerServiceClient.UpdateTask(context.Background(), connect.NewRequest(&runnerv1.UpdateTaskRequest{
154149
State: &runnerv1.TaskState{
155150
Id: task.Id,
156-
Result: policy.result,
151+
Result: outcome.result,
157152
StoppedAt: timestamppb.Now(),
158153
},
159154
}))
160155
assert.NoError(t, err)
161-
assert.Equal(t, policy.result, resp.Msg.State.Result)
156+
assert.Equal(t, outcome.result, resp.Msg.State.Result)
162157
}

0 commit comments

Comments
 (0)