broker_pool_test.go RawHistoryFolder

1package ports
2
3import (
4	"errors"
5	"strings"
6	"testing"
7
8	"github.com/bnema/vev/internal/domain"
9	"github.com/stretchr/testify/require"
10)
11
12func TestBrokerPolicyTokens(t *testing.T) {
13	for _, field := range []string{"trust", "launch", "isolation"} {
14		for _, value := range []string{"", "bad token", "\xff", "bad\u202e", strings.Repeat("x", BrokerMaxPolicyTokenBytes+1), strings.Repeat("x", BrokerMaxPolicyTokenBytes)} {
15			t.Run(field+"/"+value, func(t *testing.T) {
16				p := testBrokerPolicy()
17				switch field {
18				case "trust":
19					p.Trust = value
20				case "launch":
21					p.Launch = value
22				case "isolation":
23					p.Isolation = value
24				}
25				err := p.Validate()
26				if len(value) == BrokerMaxPolicyTokenBytes {
27					require.NoError(t, err)
28				} else {
29					require.ErrorContains(t, err, "policy "+field)
30				}
31			})
32		}
33	}
34}
35
36func TestBrokerDialTargetValidation(t *testing.T) {
37	for _, tc := range []struct {
38		name, address string
39		valid         bool
40	}{
41		{"valid", "route", true}, {"bound", strings.Repeat("x", BrokerMaxAddressBytes), true},
42		{"empty", "", false}, {"over", strings.Repeat("x", BrokerMaxAddressBytes+1), false},
43		{"utf8", "\xff", false}, {"control", "route\n", false},
44	} {
45		t.Run(tc.name, func(t *testing.T) {
46			target := BrokerDialTarget{Fence: BrokerEndpointFence{Local: true}, Policy: testBrokerPolicy(), Address: tc.address, StartMode: BrokerDaemonExistingOnly, ExpectedIdentity: BrokerExpectedIdentity{Identity: "daemon", Bound: true}}
47			require.Equal(t, tc.valid, target.Validate() == nil)
48		})
49	}
50	target := BrokerDialTarget{Fence: BrokerEndpointFence{Local: true}, Policy: testBrokerPolicy(), Address: "route", StartMode: BrokerDaemonExistingOnly, ExpectedIdentity: BrokerExpectedIdentity{Identity: "daemon", Bound: true}}
51	target.ExpectedIdentity.Identity = ""
52	require.Error(t, target.Validate())
53	target.ExpectedIdentity.Identity = "daemon"
54	target.Policy.Trust = ""
55	require.Error(t, target.Validate())
56}
57
58func TestBrokerStreamLostErrorChain(t *testing.T) {
59	cause := errors.New("transport diagnostic")
60	loss := BrokerStreamLost{Epoch: 1, Connection: BrokerConnectionID{1}, Stream: 1, Cause: domain.RemoteFailureTrust, Err: cause}
61	require.NoError(t, loss.Validate())
62	require.Equal(t, "broker attachment_lost", loss.Error())
63	require.ErrorIs(t, loss, cause)
64	var typed BrokerError
65	require.ErrorAs(t, loss, &typed)
66	require.Equal(t, BrokerErrorAttachmentLost, typed.Code)
67	loss.Cause = domain.RemoteFailureNone
68	require.Error(t, loss.Validate())
69	loss.Cause = 99
70	require.Error(t, loss.Validate())
71}
72
73func TestBrokerRequestLocalRemoteFencing(t *testing.T) {
74	for _, tc := range []struct {
75		name   string
76		mutate func(*BrokerOpenStreamRequest)
77		valid  bool
78	}{
79		{"local", func(*BrokerOpenStreamRequest) {}, true},
80		{"local endpoint", func(r *BrokerOpenStreamRequest) { r.Endpoint = "user@host" }, false},
81		{"local registration", func(r *BrokerOpenStreamRequest) { r.Registration = testBrokerRegistration("user@host", 1, 1) }, false},
82		{"remote missing", func(r *BrokerOpenStreamRequest) { r.Local = false }, false},
83		{"remote valid", func(r *BrokerOpenStreamRequest) {
84			r.Local = false
85			r.Endpoint = "user@host"
86			r.Registration = testBrokerRegistration(r.Endpoint, 1, 1)
87		}, true},
88		{"remote mismatch", func(r *BrokerOpenStreamRequest) {
89			r.Local = false
90			r.Endpoint = "user@other"
91			r.Registration = testBrokerRegistration("user@host", 1, 1)
92		}, false},
93	} {
94		t.Run(tc.name, func(t *testing.T) {
95			r := BrokerOpenStreamRequest{Epoch: 1, Connection: BrokerConnectionID{1}, Stream: 1, Local: true, Purpose: BrokerStreamControl, Policy: testBrokerPolicy(), StartMode: BrokerDaemonStartIfNeeded}
96			tc.mutate(&r)
97			require.Equal(t, tc.valid, r.Validate() == nil)
98		})
99	}
100}

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 12

Tags 11

↑↓ moveenter openesc close