detached eca6041

test(kvstore): call Delete again when it gives up under contention

TestDeleteRacingWithWrites failed on the Delete of the race itself (conflict after deleteTries listings), also on main. Delete leaves the repository in place then, so the caller calls it again.
commit
eca604188bef98f81d67c4eb607cdbe9bfa0527e
author
brice · · 2026-10-12 20:28 UTC
parent
b4c1e2a
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +11 -2
M internal/adapters/kvstore/mergerequests_test.go +11 -2
@@ -360,7 +360,8 @@ func assertNoMergeRequestKeys(t *testing.T, mrs *kvstore.MergeRequests, n domain
360360 // TestDeleteRacingWithWrites: writes racing with Delete either land before it
361361 // and are deleted, or are refused (not found after it, or a conflict when the
362362 // retries run out under this contention); nothing is left for a repository
363-// created again under the name.
363+// created again under the name. Delete itself may report a conflict under the
364+// same contention and is then called again.
364365 func TestDeleteRacingWithWrites(t *testing.T) {
365366 ctx := context.Background()
366367 for round := range 20 {
@@ -394,7 +395,15 @@ func TestDeleteRacingWithWrites(t *testing.T) {
394395 }
395396 }()
396397 }
397- delErr := s.Delete(ctx, n)
398+ // Delete gives up with a conflict when the writers keep rewriting the
399+ // repository key for deleteTries listings in a row; it is documented as
400+ // safe to call again, as a caller does.
401+ var delErr error
402+ for range 20 {
403+ if delErr = s.Delete(ctx, n); !errors.Is(delErr, domain.ErrConflict) {
404+ break
405+ }
406+ }
398407 wg.Wait()
399408 require.NoError(t, delErr)
400409
@@ -360,7 +360,8 @@ func assertNoMergeRequestKeys(t *testing.T, mrs *kvstore.MergeRequests, n domain
360 // TestDeleteRacingWithWrites: writes racing with Delete either land before it360 // TestDeleteRacingWithWrites: writes racing with Delete either land before it
361 // and are deleted, or are refused (not found after it, or a conflict when the361 // and are deleted, or are refused (not found after it, or a conflict when the
362 // retries run out under this contention); nothing is left for a repository362 // retries run out under this contention); nothing is left for a repository
363-// created again under the name.363+// created again under the name. Delete itself may report a conflict under the
364+// same contention and is then called again.
364 func TestDeleteRacingWithWrites(t *testing.T) {365 func TestDeleteRacingWithWrites(t *testing.T) {
365 ctx := context.Background()366 ctx := context.Background()
366 for round := range 20 {367 for round := range 20 {
@@ -394,7 +395,15 @@ func TestDeleteRacingWithWrites(t *testing.T) {
394 }395 }
395 }()396 }()
396 }397 }
397- delErr := s.Delete(ctx, n)398+ // Delete gives up with a conflict when the writers keep rewriting the
399+ // repository key for deleteTries listings in a row; it is documented as
400+ // safe to call again, as a caller does.
401+ var delErr error
402+ for range 20 {
403+ if delErr = s.Delete(ctx, n); !errors.Is(delErr, domain.ErrConflict) {
404+ break
405+ }
406+ }
398 wg.Wait()407 wg.Wait()
399 require.NoError(t, delErr)408 require.NoError(t, delErr)
400 409

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
esc
close a dialog, leave a field

Branches 3

Tags 43

↑↓ moveenter openesc close