detached 72285c7

test(drm): expect the owner to retry a protected modeset refused for master

The master-loss resume test sent a second seat activation after 20 ms,
racing the owner's own retry at 20 ms and hanging on a duplicate render.
The owner now retries without a seat event; the test checks the proof
follows a successful retry commit.
commit
72285c7b48fa22786601cf6adb284ffd6f07e077
author
brice · · 2026-10-10 15:11 UTC
committer
brice · · 2026-10-10 15:39 UTC
parent
591baeb
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
1 file · +11 -13
M internal/adapters/drm/security_resume_test.go +11 -13
@@ -58,19 +58,9 @@ func TestSecurityUnlockedResumeUsesOwnerRetry(t *testing.T) {
5858 waitFor(t, func() bool { mu.Lock(); defer mu.Unlock(); return len(*commits) == 1 })
5959 state.Store(3)
6060 wake <- ports.SecurityState{}
61- select {
62- case ev := <-events:
63- if _, ok := ev.(ports.SecurityOutputProof); ok {
64- t.Fatal("master loss forged proof")
65- }
66- case <-time.After(20 * time.Millisecond):
67- }
68- select {
69- case err := <-done:
70- t.Fatalf("resume stopped owner: %v", err)
71- default:
72- }
73- active <- true // only real seat reacquisition permits preparation
61+ // The seat reported active before master came back: the owner
62+ // retries the protected modeset itself, with no second seat
63+ // event. The proof below must follow that successful retry.
7464 }
7565 for {
7666 select {
@@ -79,6 +69,14 @@ func TestSecurityUnlockedResumeUsesOwnerRetry(t *testing.T) {
7969 if p.Proof.Generation != 1 || p.Proof.Instance != 77 {
8070 t.Fatalf("proof %+v", p)
8171 }
72+ if stage == "master-loss" {
73+ mu.Lock()
74+ n := len(*commits)
75+ mu.Unlock()
76+ if n < 2 {
77+ t.Fatal("master loss forged proof: no successful retry")
78+ }
79+ }
8280 cancel()
8381 if err := <-done; err != nil {
8482 t.Fatal(err)
@@ -58,19 +58,9 @@ func TestSecurityUnlockedResumeUsesOwnerRetry(t *testing.T) {
58 waitFor(t, func() bool { mu.Lock(); defer mu.Unlock(); return len(*commits) == 1 })58 waitFor(t, func() bool { mu.Lock(); defer mu.Unlock(); return len(*commits) == 1 })
59 state.Store(3)59 state.Store(3)
60 wake <- ports.SecurityState{}60 wake <- ports.SecurityState{}
61- select {61+ // The seat reported active before master came back: the owner
62- case ev := <-events:62+ // retries the protected modeset itself, with no second seat
63- if _, ok := ev.(ports.SecurityOutputProof); ok {63+ // event. The proof below must follow that successful retry.
64- t.Fatal("master loss forged proof")
65- }
66- case <-time.After(20 * time.Millisecond):
67- }
68- select {
69- case err := <-done:
70- t.Fatalf("resume stopped owner: %v", err)
71- default:
72- }
73- active <- true // only real seat reacquisition permits preparation
74 }64 }
75 for {65 for {
76 select {66 select {
@@ -79,6 +69,14 @@ func TestSecurityUnlockedResumeUsesOwnerRetry(t *testing.T) {
79 if p.Proof.Generation != 1 || p.Proof.Instance != 77 {69 if p.Proof.Generation != 1 || p.Proof.Instance != 77 {
80 t.Fatalf("proof %+v", p)70 t.Fatalf("proof %+v", p)
81 }71 }
72+ if stage == "master-loss" {
73+ mu.Lock()
74+ n := len(*commits)
75+ mu.Unlock()
76+ if n < 2 {
77+ t.Fatal("master loss forged proof: no successful retry")
78+ }
79+ }
82 cancel()80 cancel()
83 if err := <-done; err != nil {81 if err := <-done; err != nil {
84 t.Fatal(err)82 t.Fatal(err)

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 26

Tags 10

↑↓ moveenter openesc close