test: speed up tests, fix transaction bug (#39030)

Speed up tests: `make test-backend` 103s to 37s, `make test-integration`
908s to 852s.

Most of it is a detached system notice insert blocking on the SQLite
write lock until the busy timeout expired, and `ExternalServiceHTTP`
re-probing on every call with an untimed `http.Get`.

- fixed one correctness bug with nested transactions: files were deleted
while the outer transaction was open, so a later failure could roll the
database back with the files gone
- git push branch counts were far above the hook batch size
- Fix makefile dependencies so running tests and lint work in fresh
worktrees.

---------

Co-authored-by: Giteabot <teabot@gitea.io>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2026-08-22 13:04:35 +02:00
committed by GitHub
parent cce2360846
commit 66d6f74cb0
8 changed files with 69 additions and 29 deletions
+31 -12
View File
@@ -18,6 +18,7 @@ import (
"strconv"
"strings"
"sync"
"time"
"gitea.dev/modules/json"
"gitea.dev/modules/util"
@@ -160,29 +161,47 @@ type TestingT interface {
TempDir() string
}
var externalServiceCheckResult sync.Map
func ExternalServiceHTTP(t TestingT, envVarName, def string) string {
t.Helper()
val := util.IfZero(os.Getenv(envVarName), def)
if val == "" {
extSvc := util.IfZero(os.Getenv(envVarName), def)
if extSvc == "" {
if AllowSkipExternalService() {
t.Skipf("skipping test because %s is not set", envVarName)
} else {
t.Fatalf("%s is not set, but skipping is not allowed in CI", envVarName)
}
}
// minio's endpoint is "host:port" pattern
testURL := util.Iif(strings.Contains(val, "://"), val, "http://"+val)
resp, err := http.Get(testURL)
if err != nil {
if AllowSkipExternalService() {
t.Skipf("skipping test because %s is not ready", val)
} else {
t.Fatalf("%s is not ready, but skipping is not allowed in CI", val)
// only need to check once, if there are saved check result, just use it
lastCheckErrAny, lastCheckExists := externalServiceCheckResult.Load(extSvc)
var lastCheckErr error
if !lastCheckExists {
{
// minio's endpoint is "host:port" pattern
testURL := util.Iif(strings.Contains(extSvc, "://"), extSvc, "http://"+extSvc)
// do a quick check with short timeout
client := &http.Client{Timeout: 2 * time.Second}
resp, err := client.Get(testURL)
if err == nil {
_ = resp.Body.Close()
}
lastCheckErr = err
}
externalServiceCheckResult.Store(extSvc, lastCheckErr)
} else {
_ = resp.Body.Close()
lastCheckErr, _ = lastCheckErrAny.(error)
}
return val
if lastCheckErr != nil {
if AllowSkipExternalService() {
t.Skipf("skipping test because %s is not ready", extSvc)
} else {
t.Fatalf("%s is not ready, but skipping is not allowed in CI", extSvc)
}
}
return extSvc
}
var normalizeHTMLSpacesRegexp = sync.OnceValue(func() (ret struct {