Files
gitocean/tests/integration/actions_create_task_for_runner_test.go
T
CloudsandGusted 044f3d95b6 chore: re-enable nilnil lint for models/actions/task.go (#12768)
I added sentinel error values for jobs not being found and no jobs being updated by the `CreateTaskForRunner` function. This avoids the nilnil antipattern and allows the nilnil lint to be enabled for the `models/actions/task.go` file again.

The handling of these new errors was added to the `PickTask` function in `services/actions/task.go`.

Related issue: https://codeberg.org/forgejo/forgejo/issues/11261

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12768
Reviewed-by: limiting-factor <limiting-factor@noreply.codeberg.org>
Reviewed-by: elle <0xllx0@noreply.codeberg.org>
2026-06-05 01:38:23 +02:00

79 lines
2.1 KiB
Go

// Copyright 2026 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: GPL-3.0-or-later
package integration
import (
"errors"
"sync"
"testing"
"time"
actions_model "forgejo.org/models/actions"
"forgejo.org/models/unittest"
"forgejo.org/modules/setting"
"forgejo.org/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCreateTaskForRunnerNoMatchingJobFound(t *testing.T) {
defer unittest.OverrideFixtures("tests/integration/fixtures/TestCreateTaskForRunner")()
defer tests.PrepareTestEnv(t)()
runner := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 1004})
_, err := actions_model.CreateTaskForRunner(t.Context(), runner, nil, nil)
require.ErrorIs(t, err, actions_model.ErrNoMatchingJobFound)
}
// We need to concurrently choose the same job with two requests to CreateTaskForRunner. The second
// request that tries to update the job in the database (that was already updated by the first
// request) then chokes and returns the error ErrNoJobUpdated.
func TestCreateTaskForRunnerNoJobUpdated(t *testing.T) {
if setting.Database.Type.IsSQLite3() {
// SQLite locks on the transaction and the desired race condition can't be achieved
t.Skip()
}
defer unittest.OverrideFixtures("tests/integration/fixtures/TestCreateTaskForRunner")()
defer tests.PrepareTestEnv(t)()
assert.Eventually(
t,
func() bool {
unittest.LoadFixtures()
runner := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 1005})
var w sync.WaitGroup
errs := make(chan error, 2)
for range 2 {
w.Go(func() {
_, err := actions_model.CreateTaskForRunner(t.Context(), runner, nil, nil)
errs <- err
})
}
w.Wait()
close(errs)
gotNoJobUpdated := false
succeded := false
for err := range errs {
if errors.Is(err, actions_model.ErrNoJobUpdated) {
gotNoJobUpdated = true
}
if err == nil {
succeded = true
}
}
return succeded && gotNoJobUpdated
},
30*time.Second,
500*time.Microsecond,
"one call to CreateTaskForRunner should succeed and the other one should return the error ErrNoJobUpdated",
)
}