0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-26 22:56:25 +02:00

test: fix flaky TestResourceIndex and reduce its runtime (#37847)

The modernc SQLite driver (default since
https://github.com/go-gitea/gitea/pull/37562) returns `SQLITE_BUSY` once
the busy timeout is reached, unlike mattn which waited indefinitely.
`TestResourceIndex` fires many concurrent `NewIssue` writers, but SQLite
serializes all writers, so they queue on a single `BEGIN IMMEDIATE`
write lock. Under `-race` (modernc is much slower) the goroutines at the
back of the queue exceeded the hardcoded 5s test timeout, producing
`database is locked (5) (SQLITE_BUSY)`.

Changes:
- Reduce the concurrent inserts from 25 to 10. Since SQLite serializes
writers, the extra goroutines only deepen the busy-lock queue without
adding coverage. 10 still exercises concurrent index allocation while
cutting the test's `-race` runtime ~3x (2.76s to 0.86s locally).
- Share the busy-timeout constant: export `DefaultSQLiteBusyTimeout`
(20s, the production default) and reference it from the test engine
instead of the hardcoded `5000`.

Observed flake:
https://github.com/go-gitea/gitea/actions/runs/26394082930/job/77690496092

---
This PR was written with the help of Claude Opus 4.7

---------

Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
This commit is contained in:
silverwind 2026-05-26 07:06:54 +02:00 committed by GitHub
parent 5badd1bdee
commit 3223d919b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 6 additions and 6 deletions

View File

@ -7,7 +7,7 @@
- Run single playwright e2e test files with `GITEA_TEST_E2E_FLAGS='<filepath>' make test-e2e`
- Add the current year into the copyright header of new `.go` files
- Ensure no trailing whitespace in edited files
- Use Conventional Commits format for commit messages and PR titles (for example `type(scope): subject`; place `!` immediately before the colon when the change is breaking)
- Use Conventional Commits for commit messages and PR titles, e.g. `type(scope): subject`; `!` before the colon if breaking. Use `test` type for test-only changes.
- Never force-push, amend, or squash unless asked. Use new commits and normal push for pull request updates
- Preserve existing code comments, do not remove or rewrite comments that are still relevant
- Keep comments short, prefer same-line, explain why, never narrate code

View File

@ -299,7 +299,7 @@ func TestIssue_ResolveMentions(t *testing.T) {
func TestResourceIndex(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
var wg sync.WaitGroup
for i := range 25 {
for i := range 10 {
wg.Go(func() {
testInsertIssue(t, fmt.Sprintf("issue %d", i+1), "my issue", 0)
})

View File

@ -207,7 +207,7 @@ type FixturesOptions struct {
// CreateTestEngine creates a test database and loads the fixture data from fixturesDir
func CreateTestEngine(testSQLiteFile string, opts FixturesOptions) error {
driver, connStr, err := db.ConnStr(db.ConnOptions{Type: setting.DatabaseTypeSQLite3, SQLitePath: testSQLiteFile, SQLiteBusyTimeout: 5000})
driver, connStr, err := db.ConnStr(db.ConnOptions{Type: setting.DatabaseTypeSQLite3, SQLitePath: testSQLiteFile, SQLiteBusyTimeout: setting.DefaultSQLiteBusyTimeout})
if err != nil {
return err
}

View File

@ -8,7 +8,7 @@ import (
"time"
)
const defaultSQLiteBusyTimeout = 20 * 1000
const DefaultSQLiteBusyTimeout = 20 * 1000
var (
// SupportedDatabaseTypes includes all XORM supported databases type, sqlite3 maybe added by the tag-controlled drivers
@ -66,11 +66,11 @@ func loadDBSetting(rootCfg ConfigProvider) {
Database.Path = sec.Key("PATH").MustString(filepath.Join(AppDataPath, "gitea.db"))
Database.SQLiteBusyTimeout = sec.Key("SQLITE_TIMEOUT").MustInt(defaultSQLiteBusyTimeout)
Database.SQLiteBusyTimeout = sec.Key("SQLITE_TIMEOUT").MustInt(DefaultSQLiteBusyTimeout)
// mattn driver isn't really affected by this timeout, but other drivers are affected
// the default value was 500 (0.5s), to avoid breaking existing users, make sure the timeout is long enough (at least, 5 seconds)
if Database.SQLiteBusyTimeout < 5000 {
Database.SQLiteBusyTimeout = defaultSQLiteBusyTimeout
Database.SQLiteBusyTimeout = DefaultSQLiteBusyTimeout
}
Database.SQLiteJournalMode = sec.Key("SQLITE_JOURNAL_MODE").MustString("")