feat/data-dnd e05cb15

security_transition_test.go RawHistoryFolder

1package drm
2
3import (
4	"context"
5	"errors"
6	"os"
7	"sync/atomic"
8	"testing"
9	"time"
10
11	portsmocks "github.com/bnema/neferwl/internal/mocks/ports"
12	"github.com/bnema/neferwl/internal/ports"
13	"github.com/stretchr/testify/mock"
14	"golang.org/x/sys/unix"
15)
16
17func TestSecurityTransitionDuringDesktopRenderPreservesReadFence(t *testing.T) {
18	o, _, commits := testOutput(t)
19	o.cursor, o.scanout = nil, false
20	var state atomic.Uint64
21	securityGate(t, o, &state)
22	r := portsmocks.NewMockRenderer(t)
23	f, _ := protectionFence(t, false)
24	r.EXPECT().UseTarget(0).Return().Once()
25	r.EXPECT().Render(mock.Anything, mock.Anything).RunAndReturn(func(ports.Scene, map[ports.WindowID]ports.SurfaceContent) (*os.File, error) {
26		state.Store(3)
27		return f, nil
28	}).Once()
29	_, err := o.submitFrame(context.Background(), r, ports.Scene{}, nil, nil, nil, nil)
30	if !errors.Is(err, errSecurityScene) || len(*commits) != 0 || o.readDone() {
31		t.Fatalf("old rendered frame committed or read fence dropped: %v", err)
32	}
33	o.dropRead()
34}
35
36func TestSecurityMasterLossInvalidatesWithoutProof(t *testing.T) {
37	o, _, _ := testOutput(t)
38	var state atomic.Uint64
39	state.Store(3)
40	securityGate(t, o, &state)
41	events := make(chan ports.SecurityBackendEvent, 2)
42	o.SecurityEvents = events
43	o.observeSecurity()
44	o.securityPrepared = true
45	enabled := true
46	if !o.commitFailed(unix.EACCES, &enabled) || enabled || o.securityPrepared {
47		t.Fatal("master loss retained proof")
48	}
49	if err := o.sendSecurityInvalid(context.Background()); err != nil {
50		t.Fatal(err)
51	}
52	ev := <-events
53	if invalid, ok := ev.(ports.SecurityOutputInvalidated); !ok || invalid.Generation != 1 || invalid.Instance != 77 {
54		t.Fatalf("invalid event %+v", ev)
55	}
56	if len(events) != 0 {
57		t.Fatal("master loss forged inactive proof")
58	}
59}
60
61func TestSecurityProofBackpressureRechecksEpoch(t *testing.T) {
62	o, k, _ := testOutput(t)
63	var state atomic.Uint64
64	state.Store(3)
65	securityGate(t, o, &state)
66	events := make(chan ports.SecurityBackendEvent) // no consumer until transition
67	o.SecurityEvents = events
68	r := portsmocks.NewMockRenderer(t)
69	cleared := make(chan struct{})
70	r.EXPECT().UseTarget(0).Return().Once()
71	r.EXPECT().Render(mock.Anything, mock.Anything).Return(nil, nil).Once()
72	k.EXPECT().createBlob(mock.Anything).RunAndReturn(func([]byte) (uint32, error) { close(cleared); return 99, nil }).Once()
73	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
74	defer cancel()
75	done := make(chan error, 1)
76	go func() { done <- o.prepareSecurity(ctx, r) }()
77	<-cleared
78	state.Store(5)
79	if err := <-done; err != nil {
80		t.Fatal(err)
81	}
82	select {
83	case ev := <-events:
84		t.Fatalf("obsolete proof emitted: %+v", ev)
85	default:
86	}
87	if o.securityPrepared {
88		t.Fatal("obsolete proof retained")
89	}
90}

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 25

Tags 10

↑↓ moveenter openesc close