detached d8e7d5b

#5 test(app): fix flaky TestAC4PostReceiveAttribution (server busy)

state
merged · d8e7d5b · fast-forward
branch
fix/e2e-concurrent-push-slots → main
opened
bnema ·
updated

TestAC4PostReceiveAttribution pushes 4 repositories at once. The default receive-pack slots are max(2, GOMAXPROCS/2), so on a runner with 2-5 CPUs only 2 pushes run and the others get 503 "server busy".

Fix: a test-only wiring option (options.receivePacks -> githttp.Config.MaxReceivePacks) lets the test set one slot per push. Production defaults are unchanged.

Checks: GOMAXPROCS=2 failed 5/5 before, passes 10/10 after; GOMAXPROCS=1 passes 5/5; go test ./internal/app passes.

2 files · +18 -12
8/8
M internal/app/e2e_test.go +5 -3
@@ -324,11 +324,13 @@ func TestAC4HooksUnknownTokenAndMissingBinary(t *testing.T) {
324324 }
325325
326326 func TestAC4PostReceiveAttribution(t *testing.T) {
327- h := newHarness(t, harnessOpts{})
327+ // Four repositories, pushed at the same time with different refs. The
328+ // default receive-pack slots follow GOMAXPROCS (2 on a small runner), so
329+ // the test sets enough for every push to run at once.
330+ const n = 4
331+ h := newHarnessWith(t, harnessOpts{}, func(o *options) { o.receivePacks = n })
328332 events := h.forge.Bus.Subscribe(h.ctx)
329333
330- // Two repositories, pushed at the same time with different refs.
331- const n = 4
332334 type job struct {
333335 repo, branch string
334336 wt string
@@ -324,11 +324,13 @@ func TestAC4HooksUnknownTokenAndMissingBinary(t *testing.T) {
324 }324 }
325 325
326 func TestAC4PostReceiveAttribution(t *testing.T) {326 func TestAC4PostReceiveAttribution(t *testing.T) {
327- h := newHarness(t, harnessOpts{})327+ // Four repositories, pushed at the same time with different refs. The
328+ // default receive-pack slots follow GOMAXPROCS (2 on a small runner), so
329+ // the test sets enough for every push to run at once.
330+ const n = 4
331+ h := newHarnessWith(t, harnessOpts{}, func(o *options) { o.receivePacks = n })
328 events := h.forge.Bus.Subscribe(h.ctx)332 events := h.forge.Bus.Subscribe(h.ctx)
329 333
330- // Two repositories, pushed at the same time with different refs.
331- const n = 4
332 type job struct {334 type job struct {
333 repo, branch string335 repo, branch string
334 wt string336 wt string
M internal/app/forge.go +13 -9
@@ -63,6 +63,9 @@ type options struct {
6363 // archivesPerClient overrides the archives one client downloads at once
6464 // when positive.
6565 archivesPerClient int
66+ // receivePacks overrides the git-receive-pack backends running at once
67+ // when positive (the default follows GOMAXPROCS).
68+ receivePacks int
6669 // remote replaces the lister of github.com refs (tests never reach the
6770 // network).
6871 remoteLister ports.GitRemote
@@ -420,15 +423,16 @@ func newForge(ctx context.Context, cfg config.Config, opts options) (_ *forge, e
420423 })
421424
422425 gh := githttp.New(githttp.Config{
423- Auth: f.Auth,
424- Repos: f.Repos,
425- Pushes: f.Pushes,
426- Backend: git,
427- Owner: cfg.Owner,
428- Hooks: f.hooks,
429- TrustedProxies: cfg.TrustedProxies,
430- Limiter: limiter,
431- MaxBodyBytes: maxBody,
426+ Auth: f.Auth,
427+ Repos: f.Repos,
428+ Pushes: f.Pushes,
429+ Backend: git,
430+ Owner: cfg.Owner,
431+ Hooks: f.hooks,
432+ TrustedProxies: cfg.TrustedProxies,
433+ Limiter: limiter,
434+ MaxBodyBytes: maxBody,
435+ MaxReceivePacks: opts.receivePacks,
432436 })
433437 routes := make([]httpserver.Route, 0, 2*len(githttp.Patterns)+len(githubapi.Patterns)+len(oidchttp.Patterns)+len(web.Patterns))
434438 for _, p := range githttp.Patterns {
@@ -63,6 +63,9 @@ type options struct {
63 // archivesPerClient overrides the archives one client downloads at once63 // archivesPerClient overrides the archives one client downloads at once
64 // when positive.64 // when positive.
65 archivesPerClient int65 archivesPerClient int
66+ // receivePacks overrides the git-receive-pack backends running at once
67+ // when positive (the default follows GOMAXPROCS).
68+ receivePacks int
66 // remote replaces the lister of github.com refs (tests never reach the69 // remote replaces the lister of github.com refs (tests never reach the
67 // network).70 // network).
68 remoteLister ports.GitRemote71 remoteLister ports.GitRemote
@@ -420,15 +423,16 @@ func newForge(ctx context.Context, cfg config.Config, opts options) (_ *forge, e
420 })423 })
421 424
422 gh := githttp.New(githttp.Config{425 gh := githttp.New(githttp.Config{
423- Auth: f.Auth,426+ Auth: f.Auth,
424- Repos: f.Repos,427+ Repos: f.Repos,
425- Pushes: f.Pushes,428+ Pushes: f.Pushes,
426- Backend: git,429+ Backend: git,
427- Owner: cfg.Owner,430+ Owner: cfg.Owner,
428- Hooks: f.hooks,431+ Hooks: f.hooks,
429- TrustedProxies: cfg.TrustedProxies,432+ TrustedProxies: cfg.TrustedProxies,
430- Limiter: limiter,433+ Limiter: limiter,
431- MaxBodyBytes: maxBody,434+ MaxBodyBytes: maxBody,
435+ MaxReceivePacks: opts.receivePacks,
432 })436 })
433 routes := make([]httpserver.Route, 0, 2*len(githttp.Patterns)+len(githubapi.Patterns)+len(oidchttp.Patterns)+len(web.Patterns))437 routes := make([]httpserver.Route, 0, 2*len(githttp.Patterns)+len(githubapi.Patterns)+len(oidchttp.Patterns)+len(web.Patterns))
434 for _, p := range githttp.Patterns {438 for _, p := range githttp.Patterns {

Comments0 open / 0

no comments yet.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
l
merge request: the list of files (j k move, enter opens, esc back)
M
merge request: the merge menu; there 1–3 pick the mode, D deletes the branch, enter merges
R
merge request: mark the head read
esc
close a dialog, leave a field

Branches 2

Tags 41

↑↓ moveenter openesc close