mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-08 08:10:30 +00:00
test(e2e): speed up and cover exec and Kubernetes modes (#1363)
Follow-up to https://gitea.com/gitea/runner/pulls/1362, whose crash e2e missed because it only drove the daemon on Docker. - `dispatch`, `failure_paths` and `reusable_workflow` run through the daemon and `exec`, each on Docker and one shared k3s cluster. - Fixed sleeps become gates the test releases, the job timeout uses a 15s runner deadline, k3s boots alongside Gitea, Gitea's data is on tmpfs. - Outside a container, `make test-e2e` runs `go test` in a Linux container on its own network like CI, so local runs take the same paths. Local wall time: | | Before | After | |---|---|---| | Suite | 84s | 27–35s | | `job_timeout` | 64s | 17s | | `reconnect` | 22s | 4.5s | | `capacity/serial` | 20s | 2s | | `cli_shutdown_drains` | 14s | 2.3s | | `kubernetes` | 31s | 21–23s | _Written by Claude (Opus 5.5)._ --------- Co-authored-by: bircni <[email protected]> Reviewed-on: https://gitea.com/gitea/runner/pulls/1363 Reviewed-by: bircni <[email protected]> Co-authored-by: silverwind <[email protected]>
This commit is contained in:
1 parent
2e72cf902a
commit
a46d3f3eda
23 files changed
+577
-340
No files matched your search
+43
-7
@@ -9,18 +9,24 @@ import (
|
||||
"cmp"
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.com/gitea/runner/internal/app/poll"
|
||||
|
||||
mobyclient "github.com/moby/moby/client"
|
||||
)
|
||||
|
||||
const runTimeout = 3 * time.Minute
|
||||
@@ -33,6 +39,8 @@ var skipReason string
|
||||
|
||||
var binDir string
|
||||
|
||||
var dockerCLI mobyclient.APIClient
|
||||
|
||||
var runnerBinary = sync.OnceValues(func() (string, error) {
|
||||
bin := filepath.Join(binDir, "gitea-runner")
|
||||
if out, err := exec.Command(cmp.Or(os.Getenv("GO"), "go"), "build", "-o", bin, "..").CombinedOutput(); err != nil {
|
||||
@@ -54,6 +62,17 @@ func runSuite(m *testing.M) int {
|
||||
skipReason = fmt.Sprintf("docker unavailable: %v", err)
|
||||
return m.Run()
|
||||
}
|
||||
dockerCLI = cli
|
||||
|
||||
if binDir, err = os.MkdirTemp("", "gitea-runner-e2e-"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "create binary dir: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
defer os.RemoveAll(binDir)
|
||||
defer stopCluster()
|
||||
if flag.Parse(); flag.Lookup("test.run").Value.String() == "" { // a filtered run starts the cluster only if it needs it
|
||||
go func() { _, _ = k3s() }()
|
||||
}
|
||||
|
||||
f, err := StartGitea(ctx, cli)
|
||||
if err != nil {
|
||||
@@ -63,15 +82,14 @@ func runSuite(m *testing.M) int {
|
||||
fixture = f
|
||||
defer func() { _ = fixture.Close(context.Background()) }()
|
||||
|
||||
if binDir, err = os.MkdirTemp("", "gitea-runner-e2e-"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "create binary dir: %v\n", err)
|
||||
return 1
|
||||
}
|
||||
defer os.RemoveAll(binDir)
|
||||
|
||||
fmt.Fprintf(os.Stderr, "gitea fixture: image=%s version=%s\n", fixture.image, fixture.version)
|
||||
|
||||
return m.Run()
|
||||
code := m.Run()
|
||||
if err := checkClusterLeaks(); err != nil && code == 0 {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
code = 1
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
func newScenario(t *testing.T) (*GiteaAPI, string) {
|
||||
@@ -162,6 +180,24 @@ func dumpRunLogs(t *testing.T, api *GiteaAPI, repo string, runID int64) {
|
||||
}
|
||||
}
|
||||
|
||||
// newGate serves a URL that answers 503 until release, for jobs to poll instead of sleeping.
|
||||
func newGate(t *testing.T) (string, func()) {
|
||||
t.Helper()
|
||||
var released atomic.Bool
|
||||
listener, err := net.Listen("tcp", ":0")
|
||||
if err != nil {
|
||||
t.Fatalf("listen for the gate: %v", err)
|
||||
}
|
||||
server := &http.Server{Handler: http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
||||
if !released.Load() {
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
}
|
||||
}), ReadHeaderTimeout: time.Second}
|
||||
go func() { _ = server.Serve(listener) }()
|
||||
t.Cleanup(func() { _ = server.Close() })
|
||||
return fmt.Sprintf("http://%s/", net.JoinHostPort(fixture.selfIP, strconv.Itoa(listener.Addr().(*net.TCPAddr).Port))), func() { released.Store(true) }
|
||||
}
|
||||
|
||||
func waitForRun(t *testing.T, api *GiteaAPI, repo string) *ActionRun {
|
||||
t.Helper()
|
||||
return waitForRunAfter(t, api, repo, 0)
|
||||
|
||||
Reference in new issue
Block a user