mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-04 16:46:17 +02:00
110 lines
4.0 KiB
Go
110 lines
4.0 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package actions
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
actions_model "code.gitea.io/gitea/models/actions"
|
|
"code.gitea.io/gitea/models/db"
|
|
"code.gitea.io/gitea/models/unittest"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// countJobsByStatus returns the number of jobs with the given status in allJobs.
|
|
func countJobsByStatus(allJobs actions_model.ActionJobList, status actions_model.Status) int {
|
|
n := 0
|
|
for _, j := range allJobs {
|
|
if j.Status == status {
|
|
n++
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
// TestMaxParallel_ServiceLayer verifies the max-parallel invariant: Running+Waiting <= MaxParallel.
|
|
func TestMaxParallel_ServiceLayer(t *testing.T) {
|
|
require.NoError(t, unittest.PrepareTestDatabase())
|
|
|
|
t.Run("invariant: Running+Waiting <= MaxParallel", func(t *testing.T) {
|
|
runID := int64(10000)
|
|
jobID := "svc-max-parallel"
|
|
maxParallel := 2
|
|
|
|
run := &actions_model.ActionRun{ID: runID, RepoID: 1, OwnerID: 1, Index: 10000, Status: actions_model.StatusRunning}
|
|
require.NoError(t, db.Insert(context.Background(), run))
|
|
|
|
jobs := []*actions_model.ActionRunJob{
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "r1", Status: actions_model.StatusRunning, MaxParallel: maxParallel},
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "w1", Status: actions_model.StatusWaiting, MaxParallel: maxParallel},
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "b1", Status: actions_model.StatusBlocked, MaxParallel: maxParallel},
|
|
}
|
|
for _, j := range jobs {
|
|
require.NoError(t, db.Insert(context.Background(), j))
|
|
}
|
|
|
|
allJobs, err := actions_model.GetRunJobsByRunID(context.Background(), runID)
|
|
require.NoError(t, err)
|
|
|
|
running := countJobsByStatus(allJobs, actions_model.StatusRunning)
|
|
waiting := countJobsByStatus(allJobs, actions_model.StatusWaiting)
|
|
blocked := countJobsByStatus(allJobs, actions_model.StatusBlocked)
|
|
|
|
assert.LessOrEqual(t, running+waiting, maxParallel)
|
|
assert.Equal(t, 1, blocked)
|
|
})
|
|
|
|
t.Run("slot becomes available after completion", func(t *testing.T) {
|
|
runID := int64(20000)
|
|
jobID := "svc-slot-free"
|
|
maxParallel := 2
|
|
|
|
run := &actions_model.ActionRun{ID: runID, RepoID: 1, OwnerID: 1, Index: 20000, Status: actions_model.StatusRunning}
|
|
require.NoError(t, db.Insert(context.Background(), run))
|
|
|
|
jobs := []*actions_model.ActionRunJob{
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "r1", Status: actions_model.StatusRunning, MaxParallel: maxParallel},
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "r2", Status: actions_model.StatusRunning, MaxParallel: maxParallel},
|
|
{RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "b1", Status: actions_model.StatusBlocked, MaxParallel: maxParallel},
|
|
}
|
|
for _, j := range jobs {
|
|
require.NoError(t, db.Insert(context.Background(), j))
|
|
}
|
|
|
|
jobs[0].Status = actions_model.StatusSuccess
|
|
_, err := actions_model.UpdateRunJob(context.Background(), jobs[0], nil, "status")
|
|
require.NoError(t, err)
|
|
|
|
allJobs, err := actions_model.GetRunJobsByRunID(context.Background(), runID)
|
|
require.NoError(t, err)
|
|
|
|
running := countJobsByStatus(allJobs, actions_model.StatusRunning)
|
|
assert.Equal(t, 1, running)
|
|
assert.Less(t, running, maxParallel)
|
|
})
|
|
|
|
t.Run("no max-parallel means all jobs start as Waiting", func(t *testing.T) {
|
|
runID := int64(30000)
|
|
jobID := "svc-no-limit"
|
|
|
|
run := &actions_model.ActionRun{ID: runID, RepoID: 1, OwnerID: 1, Index: 30000, Status: actions_model.StatusRunning}
|
|
require.NoError(t, db.Insert(context.Background(), run))
|
|
|
|
for range 5 {
|
|
require.NoError(t, db.Insert(context.Background(), &actions_model.ActionRunJob{
|
|
RunID: runID, RepoID: 1, OwnerID: 1, JobID: jobID, Name: "j",
|
|
Status: actions_model.StatusWaiting, MaxParallel: 0,
|
|
}))
|
|
}
|
|
|
|
allJobs, err := actions_model.GetRunJobsByRunID(context.Background(), runID)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 5, countJobsByStatus(allJobs, actions_model.StatusWaiting))
|
|
assert.Equal(t, 0, countJobsByStatus(allJobs, actions_model.StatusBlocked))
|
|
})
|
|
}
|