Skip to content

Commit

Permalink
TestScheduleConcurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
Zettat123 committed Jan 23, 2025
1 parent 3f839ff commit 19d3dcb
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 16 deletions.
86 changes: 72 additions & 14 deletions tests/integration/actions_concurrency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
webhook_module "code.gitea.io/gitea/modules/webhook"
actions_service "code.gitea.io/gitea/services/actions"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -470,7 +472,7 @@ jobs:
"appVersion": "v1.22",
})
session.MakeRequest(t, req, http.StatusSeeOther)
runner.fetchNoTask(t) // cannot fetch task since task2 is not completed
runner.fetchNoTask(t) // cannot fetch task because task2 is not completed

// run the workflow with appVersion=v1.22 and cancel=true
req = NewRequestWithValues(t, "POST", urlStr, map[string]string{
Expand Down Expand Up @@ -499,39 +501,95 @@ func TestScheduleConcurrency(t *testing.T) {

apiRepo := createActionsTestRepo(t, token, "actions-concurrency", false)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
httpContext := NewAPITestContext(t, user2.Name, repo.Name, auth_model.AccessTokenScopeWriteRepository)
defer doAPIDeleteRepository(httpContext)(t)
runner := newMockRunner()
runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"})

// add a variable for test
req := NewRequestWithJSON(t, "POST",
fmt.Sprintf("/api/v1/repos/%s/%s/actions/variables/cancel_schedule", user2.Name, repo.Name), &api.CreateVariableOption{
Value: "false",
}).
AddTokenAuth(token)
MakeRequest(t, req, http.StatusNoContent)

wf1TreePath := ".gitea/workflows/schedule-concurrency.yml"
wf1FileContent := `name: schedule-concurrency
on:
push:
schedule:
- cron: '0/5 * * * *'
- cron: '@every 1m'
concurrency:
group: schedule-concurrency
cancel-in-progress: ${{ vars.cancel_schedule == 'false' }}
cancel-in-progress: ${{ gitea.event_name == 'push' }}
jobs:
job:
runs-on: ubuntu-latest
steps:
- run: echo 'workflow dispatch job'
- run: echo 'schedule workflow'
`

opts1 := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, fmt.Sprintf("create %s", wf1TreePath), wf1FileContent)
createWorkflowFile(t, token, user2.Name, repo.Name, wf1TreePath, opts1)

// fetch the task triggered by push
task1 := runner.fetchTask(t)
_, _, run1 := getTaskAndJobAndRunByTaskID(t, task1.Id)
assert.Equal(t, "schedule-concurrency", run1.ConcurrencyGroup)
assert.True(t, run1.ConcurrencyCancel)
assert.Equal(t, string(webhook_module.HookEventPush), run1.TriggerEvent)
assert.Equal(t, actions_model.StatusRunning, run1.Status)

// trigger the task by schedule
spec := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionScheduleSpec{RepoID: repo.ID})
spec.Next = timeutil.TimeStampNow() // manually update "Next"
assert.NoError(t, actions_model.UpdateScheduleSpec(context.Background(), spec, "next"))
assert.NoError(t, actions_service.StartScheduleTasks(context.Background()))
runner.fetchNoTask(t) // cannot fetch because task1 is not completed
runner.execTask(t, task1, &mockTaskOutcome{
result: runnerv1.Result_RESULT_SUCCESS,
})
_, _, run1 = getTaskAndJobAndRunByTaskID(t, task1.Id)
assert.Equal(t, actions_model.StatusSuccess, run1.Status)
task2 := runner.fetchTask(t)
_, _, run2 := getTaskAndJobAndRunByTaskID(t, task2.Id)
assert.Equal(t, "schedule-concurrency", run2.ConcurrencyGroup)
assert.False(t, run2.ConcurrencyCancel)
assert.Equal(t, string(webhook_module.HookEventSchedule), run2.TriggerEvent)
assert.Equal(t, actions_model.StatusRunning, run2.Status)

// trigger the task by schedule again
spec = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionScheduleSpec{RepoID: repo.ID})
spec.Next = timeutil.TimeStampNow() // manually update "Next"
assert.NoError(t, actions_model.UpdateScheduleSpec(context.Background(), spec, "next"))
assert.NoError(t, actions_service.StartScheduleTasks(context.Background()))
runner.fetchNoTask(t) // cannot fetch because task2 is not completed
run3 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: repo.ID, Status: actions_model.StatusBlocked})
assert.Equal(t, "schedule-concurrency", run3.ConcurrencyGroup)
assert.False(t, run3.ConcurrencyCancel)
assert.Equal(t, string(webhook_module.HookEventSchedule), run3.TriggerEvent)

// trigger the task by push
doAPICreateFile(httpContext, "doc.txt", &api.CreateFileOptions{
FileOptions: api.FileOptions{
NewBranchName: "main",
Message: "create doc.txt",
Author: api.Identity{
Name: user2.Name,
Email: user2.Email,
},
Committer: api.Identity{
Name: user2.Name,
Email: user2.Email,
},
Dates: api.CommitDateOptions{
Author: time.Now(),
Committer: time.Now(),
},
},
ContentBase64: base64.StdEncoding.EncodeToString([]byte("doc")),
})(t)

httpContext := NewAPITestContext(t, user2.Name, repo.Name, auth_model.AccessTokenScopeWriteRepository)
doAPIDeleteRepository(httpContext)(t)
task4 := runner.fetchTask(t)
_, _, run4 := getTaskAndJobAndRunByTaskID(t, task4.Id)
assert.Equal(t, "schedule-concurrency", run4.ConcurrencyGroup)
assert.True(t, run4.ConcurrencyCancel)
assert.Equal(t, string(webhook_module.HookEventPush), run4.TriggerEvent)
run3 = unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: run3.ID})
assert.Equal(t, actions_model.StatusCancelled, run3.Status)
})
}

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/actions_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (r *mockRunner) fetchNoTask(t *testing.T, timeout ...time.Duration) {
assert.Nil(t, task, "a task is fetched")
}

const defaultFetchTaskTimeout = 5 * time.Second
const defaultFetchTaskTimeout = 1 * time.Second

func (r *mockRunner) tryFetchTask(t *testing.T, timeout ...time.Duration) *runnerv1.Task {
fetchTimeout := defaultFetchTaskTimeout
Expand All @@ -120,7 +120,7 @@ func (r *mockRunner) tryFetchTask(t *testing.T, timeout ...time.Duration) *runne
task = resp.Msg.Task
break
}
time.Sleep(time.Second)
time.Sleep(200 * time.Millisecond)
}

return task
Expand Down

0 comments on commit 19d3dcb

Please sign in to comment.