detached 9b35c25

Merge pull request 'test(kvstore): accept a conflict from SetRead racing with a repository delete' (#16) from fix/kvstore-delete-race-test into main

commit
9b35c2577f2ec5dbf579ac6510908034e8d1b759
author
bnema · · 2026-10-12 19:50 UTC
merge of
f3afb66 + a358636 · diff against the first parent
signature
SSH UnverifiedSHA256:VOCA5lYARHcbKDZ7GhTV45VmcjWnJ6ZQIBazj17LivA The key is unknown
2 files · +6 -3
M internal/adapters/kvstore/mergerequests_test.go +3 -2
@@ -358,7 +358,8 @@ func assertNoMergeRequestKeys(t *testing.T, mrs *kvstore.MergeRequests, n domain
358358 }
359359
360360 // TestDeleteRacingWithWrites: writes racing with Delete either land before it
361-// and are deleted, or are refused after it; nothing is left for a repository
361+// 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 repository
362363 // created again under the name.
363364 func TestDeleteRacingWithWrites(t *testing.T) {
364365 ctx := context.Background()
@@ -376,7 +377,7 @@ func TestDeleteRacingWithWrites(t *testing.T) {
376377 if w%2 == 0 {
377378 err := mrs.SetRead(ctx, n, mr.Number, oid('a'))
378379 if err != nil {
379- assert.ErrorIs(t, err, domain.ErrNotFound)
380+ assert.True(t, errors.Is(err, domain.ErrConflict) || errors.Is(err, domain.ErrNotFound), "round %d: %v", round, err)
380381 return
381382 }
382383 continue
@@ -358,7 +358,8 @@ func assertNoMergeRequestKeys(t *testing.T, mrs *kvstore.MergeRequests, n domain
358 }358 }
359 359
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 after it; nothing is left for a repository361+// 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 repository
362 // created again under the name.363 // created again under the name.
363 func TestDeleteRacingWithWrites(t *testing.T) {364 func TestDeleteRacingWithWrites(t *testing.T) {
364 ctx := context.Background()365 ctx := context.Background()
@@ -376,7 +377,7 @@ func TestDeleteRacingWithWrites(t *testing.T) {
376 if w%2 == 0 {377 if w%2 == 0 {
377 err := mrs.SetRead(ctx, n, mr.Number, oid('a'))378 err := mrs.SetRead(ctx, n, mr.Number, oid('a'))
378 if err != nil {379 if err != nil {
379- assert.ErrorIs(t, err, domain.ErrNotFound)380+ assert.True(t, errors.Is(err, domain.ErrConflict) || errors.Is(err, domain.ErrNotFound), "round %d: %v", round, err)
380 return381 return
381 }382 }
382 continue383 continue
M internal/ports/ports.go +3 -1
@@ -255,7 +255,9 @@ type MergeRequestStore interface {
255255 // ObjectID when there is none.
256256 GetRead(ctx context.Context, repo domain.RepoName, number int64) (domain.ObjectID, error)
257257 // SetRead records the head the reviewer has read. It returns
258- // domain.ErrNotFound when the repository does not exist.
258+ // domain.ErrNotFound when the repository does not exist, and
259+ // domain.ErrConflict when concurrent writes to the repository keep it
260+ // from landing.
259261 SetRead(ctx context.Context, repo domain.RepoName, number int64, head domain.ObjectID) error
260262 }
261263
@@ -255,7 +255,9 @@ type MergeRequestStore interface {
255 // ObjectID when there is none.255 // ObjectID when there is none.
256 GetRead(ctx context.Context, repo domain.RepoName, number int64) (domain.ObjectID, error)256 GetRead(ctx context.Context, repo domain.RepoName, number int64) (domain.ObjectID, error)
257 // SetRead records the head the reviewer has read. It returns257 // SetRead records the head the reviewer has read. It returns
258- // domain.ErrNotFound when the repository does not exist.258+ // domain.ErrNotFound when the repository does not exist, and
259+ // domain.ErrConflict when concurrent writes to the repository keep it
260+ // from landing.
259 SetRead(ctx context.Context, repo domain.RepoName, number int64, head domain.ObjectID) error261 SetRead(ctx context.Context, repo domain.RepoName, number int64, head domain.ObjectID) error
260 }262 }
261 263

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 4

Tags 45

↑↓ moveenter openesc close