detached eebe943

test(broker): use generated port mocks

commit
eebe943bcf78776ae8af40778f95bd8b1270ae7d
author
brice · · 2026-09-23 14:49 UTC
committer
brice · · 2026-09-23 14:49 UTC
parent
357815c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +33 -61
M internal/app/ui_driver_acceptance_test.go +6 -4
@@ -11,14 +11,14 @@ import (
1111 "github.com/bnema/vev/internal/adapters/uiterm"
1212 "github.com/bnema/vev/internal/domain"
1313 "github.com/bnema/vev/internal/ports"
14+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
1415 "github.com/bnema/vev/internal/protocol"
1516 "github.com/bnema/vev/internal/usecase/client"
17+ "github.com/stretchr/testify/mock"
1618 "github.com/stretchr/testify/require"
1719 )
1820
19-// scriptedBrokerConnector adapts one scripted broker service to the connector
20-// port, so a driver test can run the whole JSONL composition over a deterministic
21-// committed publication without a broker process.
21+// scriptedBrokerConnector is also used by broker_client_test.go, outside this change's scope.
2222 type scriptedBrokerConnector struct{ service *terminalCompositionService }
2323
2424 func (c scriptedBrokerConnector) Connect(context.Context) (ports.BrokerService, error) {
@@ -46,9 +46,11 @@ func startScriptedUIDriverRun(t *testing.T, service *terminalCompositionService,
4646 t.Error("the scripted UI driver did not stop")
4747 }
4848 })
49+ connector := portsmocks.NewMockBrokerConnector(t)
50+ connector.EXPECT().Connect(mock.Anything).Return(service, nil).Maybe()
4951 go func() {
5052 run.done <- runUIDriverClient(ctx, brokerClientConfig{
51- Connector: scriptedBrokerConnector{service: service},
53+ Connector: connector,
5254 Terminal: terminal,
5355 Clock: clock.New(),
5456 UI: ui,
@@ -11,14 +11,14 @@ import (
11 "github.com/bnema/vev/internal/adapters/uiterm"11 "github.com/bnema/vev/internal/adapters/uiterm"
12 "github.com/bnema/vev/internal/domain"12 "github.com/bnema/vev/internal/domain"
13 "github.com/bnema/vev/internal/ports"13 "github.com/bnema/vev/internal/ports"
14+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
14 "github.com/bnema/vev/internal/protocol"15 "github.com/bnema/vev/internal/protocol"
15 "github.com/bnema/vev/internal/usecase/client"16 "github.com/bnema/vev/internal/usecase/client"
17+ "github.com/stretchr/testify/mock"
16 "github.com/stretchr/testify/require"18 "github.com/stretchr/testify/require"
17 )19 )
18 20
19-// scriptedBrokerConnector adapts one scripted broker service to the connector21+// scriptedBrokerConnector is also used by broker_client_test.go, outside this change's scope.
20-// port, so a driver test can run the whole JSONL composition over a deterministic
21-// committed publication without a broker process.
22 type scriptedBrokerConnector struct{ service *terminalCompositionService }22 type scriptedBrokerConnector struct{ service *terminalCompositionService }
23 23
24 func (c scriptedBrokerConnector) Connect(context.Context) (ports.BrokerService, error) {24 func (c scriptedBrokerConnector) Connect(context.Context) (ports.BrokerService, error) {
@@ -46,9 +46,11 @@ func startScriptedUIDriverRun(t *testing.T, service *terminalCompositionService,
46 t.Error("the scripted UI driver did not stop")46 t.Error("the scripted UI driver did not stop")
47 }47 }
48 })48 })
49+ connector := portsmocks.NewMockBrokerConnector(t)
50+ connector.EXPECT().Connect(mock.Anything).Return(service, nil).Maybe()
49 go func() {51 go func() {
50 run.done <- runUIDriverClient(ctx, brokerClientConfig{52 run.done <- runUIDriverClient(ctx, brokerClientConfig{
51- Connector: scriptedBrokerConnector{service: service},53+ Connector: connector,
52 Terminal: terminal,54 Terminal: terminal,
53 Clock: clock.New(),55 Clock: clock.New(),
54 UI: ui,56 UI: ui,
M internal/app/web_daemon_broker_test.go +14 -41
@@ -21,7 +21,9 @@ import (
2121 "github.com/bnema/vev/internal/adapters/brokeripc"
2222 "github.com/bnema/vev/internal/adapters/webterm"
2323 "github.com/bnema/vev/internal/ports"
24+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
2425 "github.com/bnema/vev/internal/usecase/client"
26+ "github.com/stretchr/testify/mock"
2527 )
2628
2729 // Browser gateway broker composition tests (Plan 001 P7.4d).
@@ -50,35 +52,6 @@ const (
5052
5153 var webGatewayReadyPID = regexp.MustCompile(`READY-(\d+)`)
5254
53-// webConnectorFunc adapts one function to the broker connector port, so a test
54-// can script successive attempts without a broker process.
55-type webConnectorFunc func(context.Context) (ports.BrokerService, error)
56-
57-func (f webConnectorFunc) Connect(ctx context.Context) (ports.BrokerService, error) { return f(ctx) }
58-
59-// webScriptedConnector serves one scripted broker service and then fails every
60-// later attempt, so a broker loss cannot silently reconnect into the scripted
61-// publication.
62-type webScriptedConnector struct {
63- mu sync.Mutex
64- service ports.BrokerService
65- err error
66- calls int
67-}
68-
69-func (c *webScriptedConnector) Connect(context.Context) (ports.BrokerService, error) {
70- c.mu.Lock()
71- defer c.mu.Unlock()
72- c.calls++
73- if c.calls == 1 && c.service != nil {
74- return c.service, nil
75- }
76- if c.err == nil {
77- c.err = errors.New("broker is gone")
78- }
79- return nil, c.err
80-}
81-
8255 // webFrame is one gateway websocket frame: the transactional VT update plus the
8356 // mouse-tracking flag.
8457 type webFrame struct {
@@ -603,10 +576,10 @@ func TestWebGatewayTabClosingIsIsolated(t *testing.T) {
603576 // keeps serving frames.
604577 func TestWebGatewayTabStaysPickerWhenDestinationIsRefused(t *testing.T) {
605578 service := newTerminalCompositionService(ports.BrokerSnapshot{Epoch: terminalCompositionEpoch, Revision: 1})
579+ connector := portsmocks.NewMockBrokerConnector(t)
580+ connector.EXPECT().Connect(mock.Anything).Return(service, nil).Maybe()
606581 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector {
607- return webConnectorFunc(func(context.Context) (ports.BrokerService, error) {
608- return service, nil
609- })
582+ return connector
610583 })
611584
612585 tab := fixture.openTab(t)
@@ -633,7 +606,14 @@ func TestWebGatewayTabStaysPickerWhenDestinationIsRefused(t *testing.T) {
633606 // and keeps serving frames while it retries.
634607 func TestWebGatewayTabReturnsToPickerOnBrokerLoss(t *testing.T) {
635608 service := newTerminalCompositionService(terminalCompositionSnapshot([]string{"work"}, nil))
636- connector := &webScriptedConnector{service: service}
609+ connector := portsmocks.NewMockBrokerConnector(t)
610+ var calls atomic.Int32
611+ connector.EXPECT().Connect(mock.Anything).RunAndReturn(func(context.Context) (ports.BrokerService, error) {
612+ if calls.Add(1) == 1 {
613+ return service, nil
614+ }
615+ return nil, errors.New("broker is gone")
616+ }).Maybe()
637617 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector { return connector })
638618
639619 tab := fixture.openTab(t)
@@ -655,14 +635,7 @@ func TestWebGatewayTabReturnsToPickerOnBrokerLoss(t *testing.T) {
655635 t.Fatalf("broker loss ended the browser run: %v", tab.readerErr())
656636 default:
657637 }
658- require.GreaterOrEqual(t, connector.attempts(), 2, "a lost connection must be retried, never fatal")
659-}
660-
661-// attempts reports how many connect attempts the scripted connector observed.
662-func (c *webScriptedConnector) attempts() int {
663- c.mu.Lock()
664- defer c.mu.Unlock()
665- return c.calls
638+ require.GreaterOrEqual(t, calls.Load(), int32(2), "a lost connection must be retried, never fatal")
666639 }
667640
668641 // TestWebCompositionUsesTheBrokerConnector pins the production composition
@@ -21,7 +21,9 @@ import (
21 "github.com/bnema/vev/internal/adapters/brokeripc"21 "github.com/bnema/vev/internal/adapters/brokeripc"
22 "github.com/bnema/vev/internal/adapters/webterm"22 "github.com/bnema/vev/internal/adapters/webterm"
23 "github.com/bnema/vev/internal/ports"23 "github.com/bnema/vev/internal/ports"
24+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
24 "github.com/bnema/vev/internal/usecase/client"25 "github.com/bnema/vev/internal/usecase/client"
26+ "github.com/stretchr/testify/mock"
25 )27 )
26 28
27 // Browser gateway broker composition tests (Plan 001 P7.4d).29 // Browser gateway broker composition tests (Plan 001 P7.4d).
@@ -50,35 +52,6 @@ const (
50 52
51 var webGatewayReadyPID = regexp.MustCompile(`READY-(\d+)`)53 var webGatewayReadyPID = regexp.MustCompile(`READY-(\d+)`)
52 54
53-// webConnectorFunc adapts one function to the broker connector port, so a test
54-// can script successive attempts without a broker process.
55-type webConnectorFunc func(context.Context) (ports.BrokerService, error)
56-
57-func (f webConnectorFunc) Connect(ctx context.Context) (ports.BrokerService, error) { return f(ctx) }
58-
59-// webScriptedConnector serves one scripted broker service and then fails every
60-// later attempt, so a broker loss cannot silently reconnect into the scripted
61-// publication.
62-type webScriptedConnector struct {
63- mu sync.Mutex
64- service ports.BrokerService
65- err error
66- calls int
67-}
68-
69-func (c *webScriptedConnector) Connect(context.Context) (ports.BrokerService, error) {
70- c.mu.Lock()
71- defer c.mu.Unlock()
72- c.calls++
73- if c.calls == 1 && c.service != nil {
74- return c.service, nil
75- }
76- if c.err == nil {
77- c.err = errors.New("broker is gone")
78- }
79- return nil, c.err
80-}
81-
82 // webFrame is one gateway websocket frame: the transactional VT update plus the55 // webFrame is one gateway websocket frame: the transactional VT update plus the
83 // mouse-tracking flag.56 // mouse-tracking flag.
84 type webFrame struct {57 type webFrame struct {
@@ -603,10 +576,10 @@ func TestWebGatewayTabClosingIsIsolated(t *testing.T) {
603 // keeps serving frames.576 // keeps serving frames.
604 func TestWebGatewayTabStaysPickerWhenDestinationIsRefused(t *testing.T) {577 func TestWebGatewayTabStaysPickerWhenDestinationIsRefused(t *testing.T) {
605 service := newTerminalCompositionService(ports.BrokerSnapshot{Epoch: terminalCompositionEpoch, Revision: 1})578 service := newTerminalCompositionService(ports.BrokerSnapshot{Epoch: terminalCompositionEpoch, Revision: 1})
579+ connector := portsmocks.NewMockBrokerConnector(t)
580+ connector.EXPECT().Connect(mock.Anything).Return(service, nil).Maybe()
606 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector {581 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector {
607- return webConnectorFunc(func(context.Context) (ports.BrokerService, error) {582+ return connector
608- return service, nil
609- })
610 })583 })
611 584
612 tab := fixture.openTab(t)585 tab := fixture.openTab(t)
@@ -633,7 +606,14 @@ func TestWebGatewayTabStaysPickerWhenDestinationIsRefused(t *testing.T) {
633 // and keeps serving frames while it retries.606 // and keeps serving frames while it retries.
634 func TestWebGatewayTabReturnsToPickerOnBrokerLoss(t *testing.T) {607 func TestWebGatewayTabReturnsToPickerOnBrokerLoss(t *testing.T) {
635 service := newTerminalCompositionService(terminalCompositionSnapshot([]string{"work"}, nil))608 service := newTerminalCompositionService(terminalCompositionSnapshot([]string{"work"}, nil))
636- connector := &webScriptedConnector{service: service}609+ connector := portsmocks.NewMockBrokerConnector(t)
610+ var calls atomic.Int32
611+ connector.EXPECT().Connect(mock.Anything).RunAndReturn(func(context.Context) (ports.BrokerService, error) {
612+ if calls.Add(1) == 1 {
613+ return service, nil
614+ }
615+ return nil, errors.New("broker is gone")
616+ }).Maybe()
637 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector { return connector })617 fixture := startWebGatewayFixtureOver(t, offlineClientFixture{}, func() ports.BrokerConnector { return connector })
638 618
639 tab := fixture.openTab(t)619 tab := fixture.openTab(t)
@@ -655,14 +635,7 @@ func TestWebGatewayTabReturnsToPickerOnBrokerLoss(t *testing.T) {
655 t.Fatalf("broker loss ended the browser run: %v", tab.readerErr())635 t.Fatalf("broker loss ended the browser run: %v", tab.readerErr())
656 default:636 default:
657 }637 }
658- require.GreaterOrEqual(t, connector.attempts(), 2, "a lost connection must be retried, never fatal")638+ require.GreaterOrEqual(t, calls.Load(), int32(2), "a lost connection must be retried, never fatal")
659-}
660-
661-// attempts reports how many connect attempts the scripted connector observed.
662-func (c *webScriptedConnector) attempts() int {
663- c.mu.Lock()
664- defer c.mu.Unlock()
665- return c.calls
666 }639 }
667 640
668 // TestWebCompositionUsesTheBrokerConnector pins the production composition641 // TestWebCompositionUsesTheBrokerConnector pins the production composition
M internal/usecase/broker/pool_test.go +13 -16
@@ -10,7 +10,9 @@ import (
1010
1111 "github.com/bnema/vev/internal/domain"
1212 "github.com/bnema/vev/internal/ports"
13+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
1314 "github.com/bnema/vev/internal/protocol"
15+ "github.com/stretchr/testify/mock"
1416 "github.com/stretchr/testify/require"
1517 )
1618
@@ -84,12 +86,14 @@ func poolRequest(id ports.BrokerConnectionID, n uint64) ports.BrokerOpenStreamRe
8486 func setupPool(t testing.TB, connector poolConnector) (*Pool, *manualClock) {
8587 t.Helper()
8688 clock := newManualClock(time.Unix(0, 0))
87- resolver := poolResolver(func(_ context.Context, r ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {
89+ resolver := portsmocks.NewMockBrokerRouteAuthority(t)
90+ resolver.EXPECT().ResolveDialTarget(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, r ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {
8891 return ports.BrokerDialTarget{Fence: ports.BrokerEndpointFence{Local: true}, Policy: r.Policy, Address: "fake", StartMode: r.StartMode, ExpectedIdentity: ports.BrokerExpectedIdentity{Identity: "canonical", Bound: true}}, nil
89- })
90- binder := poolBinder(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
92+ }).Maybe()
93+ binder := portsmocks.NewMockBrokerIdentityBinder(t)
94+ binder.EXPECT().BindAuthenticatedIdentity(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
9195 return request.Identity, nil
92- })
96+ }).Maybe()
9397 p, err := NewPool(1, resolver, binder, connector, clock, PoolLimits{Physical: 2, Clients: 128, Streams: 128, StreamsPerClient: 128, Warm: 2, Idle: time.Minute})
9498 require.NoError(t, err)
9599 t.Cleanup(func() { require.NoError(t, p.Close()) })
@@ -109,17 +113,10 @@ func await(t *testing.T, ch <-chan struct{}) {
109113 // a physical transport, so an unprovisioned or conflicting request can never
110114 // reach an address. The same ordering fences a refused local request.
111115 func TestPoolRefusedResolutionNeverDials(t *testing.T) {
112- var dials atomic.Int32
113- resolver := poolResolver(func(context.Context, ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {
114- return ports.BrokerDialTarget{}, ports.BrokerError{Code: ports.BrokerErrorConflictingPolicy, Cause: errors.New("refused")}
115- })
116- connector := poolConnector(func(context.Context, ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error) {
117- dials.Add(1)
118- return nil, nil
119- })
120- binder := poolBinder(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
121- return request.Identity, nil
122- })
116+ resolver := portsmocks.NewMockBrokerRouteAuthority(t)
117+ resolver.EXPECT().ResolveDialTarget(mock.Anything, mock.Anything).Return(ports.BrokerDialTarget{}, ports.BrokerError{Code: ports.BrokerErrorConflictingPolicy, Cause: errors.New("refused")}).Once()
118+ connector := portsmocks.NewMockBrokerEndpointConnector(t)
119+ binder := portsmocks.NewMockBrokerIdentityBinder(t)
123120 pool, err := NewPool(1, resolver, binder, connector, newManualClock(time.Unix(0, 0)), PoolLimits{Physical: 1, Clients: 8, Streams: 8, StreamsPerClient: 8, Warm: 1, Idle: time.Minute})
124121 require.NoError(t, err)
125122 t.Cleanup(func() { require.NoError(t, pool.Close()) })
@@ -131,7 +128,7 @@ func TestPoolRefusedResolutionNeverDials(t *testing.T) {
131128 var typed ports.BrokerError
132129 require.ErrorAs(t, err, &typed)
133130 require.Equal(t, ports.BrokerErrorConflictingPolicy, typed.Code)
134- require.Zero(t, dials.Load(), "a refused request must never dial")
131+ connector.AssertNotCalled(t, "Connect", mock.Anything, mock.Anything)
135132 }
136133
137134 // TestPoolOpenFailureWithTypedNilConnection proves a failed open that still
@@ -10,7 +10,9 @@ import (
10 10
11 "github.com/bnema/vev/internal/domain"11 "github.com/bnema/vev/internal/domain"
12 "github.com/bnema/vev/internal/ports"12 "github.com/bnema/vev/internal/ports"
13+ portsmocks "github.com/bnema/vev/internal/ports/mocks"
13 "github.com/bnema/vev/internal/protocol"14 "github.com/bnema/vev/internal/protocol"
15+ "github.com/stretchr/testify/mock"
14 "github.com/stretchr/testify/require"16 "github.com/stretchr/testify/require"
15 )17 )
16 18
@@ -84,12 +86,14 @@ func poolRequest(id ports.BrokerConnectionID, n uint64) ports.BrokerOpenStreamRe
84 func setupPool(t testing.TB, connector poolConnector) (*Pool, *manualClock) {86 func setupPool(t testing.TB, connector poolConnector) (*Pool, *manualClock) {
85 t.Helper()87 t.Helper()
86 clock := newManualClock(time.Unix(0, 0))88 clock := newManualClock(time.Unix(0, 0))
87- resolver := poolResolver(func(_ context.Context, r ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {89+ resolver := portsmocks.NewMockBrokerRouteAuthority(t)
90+ resolver.EXPECT().ResolveDialTarget(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, r ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {
88 return ports.BrokerDialTarget{Fence: ports.BrokerEndpointFence{Local: true}, Policy: r.Policy, Address: "fake", StartMode: r.StartMode, ExpectedIdentity: ports.BrokerExpectedIdentity{Identity: "canonical", Bound: true}}, nil91 return ports.BrokerDialTarget{Fence: ports.BrokerEndpointFence{Local: true}, Policy: r.Policy, Address: "fake", StartMode: r.StartMode, ExpectedIdentity: ports.BrokerExpectedIdentity{Identity: "canonical", Bound: true}}, nil
89- })92+ }).Maybe()
90- binder := poolBinder(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {93+ binder := portsmocks.NewMockBrokerIdentityBinder(t)
94+ binder.EXPECT().BindAuthenticatedIdentity(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
91 return request.Identity, nil95 return request.Identity, nil
92- })96+ }).Maybe()
93 p, err := NewPool(1, resolver, binder, connector, clock, PoolLimits{Physical: 2, Clients: 128, Streams: 128, StreamsPerClient: 128, Warm: 2, Idle: time.Minute})97 p, err := NewPool(1, resolver, binder, connector, clock, PoolLimits{Physical: 2, Clients: 128, Streams: 128, StreamsPerClient: 128, Warm: 2, Idle: time.Minute})
94 require.NoError(t, err)98 require.NoError(t, err)
95 t.Cleanup(func() { require.NoError(t, p.Close()) })99 t.Cleanup(func() { require.NoError(t, p.Close()) })
@@ -109,17 +113,10 @@ func await(t *testing.T, ch <-chan struct{}) {
109 // a physical transport, so an unprovisioned or conflicting request can never113 // a physical transport, so an unprovisioned or conflicting request can never
110 // reach an address. The same ordering fences a refused local request.114 // reach an address. The same ordering fences a refused local request.
111 func TestPoolRefusedResolutionNeverDials(t *testing.T) {115 func TestPoolRefusedResolutionNeverDials(t *testing.T) {
112- var dials atomic.Int32116+ resolver := portsmocks.NewMockBrokerRouteAuthority(t)
113- resolver := poolResolver(func(context.Context, ports.BrokerOpenStreamRequest) (ports.BrokerDialTarget, error) {117+ resolver.EXPECT().ResolveDialTarget(mock.Anything, mock.Anything).Return(ports.BrokerDialTarget{}, ports.BrokerError{Code: ports.BrokerErrorConflictingPolicy, Cause: errors.New("refused")}).Once()
114- return ports.BrokerDialTarget{}, ports.BrokerError{Code: ports.BrokerErrorConflictingPolicy, Cause: errors.New("refused")}118+ connector := portsmocks.NewMockBrokerEndpointConnector(t)
115- })119+ binder := portsmocks.NewMockBrokerIdentityBinder(t)
116- connector := poolConnector(func(context.Context, ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error) {
117- dials.Add(1)
118- return nil, nil
119- })
120- binder := poolBinder(func(_ context.Context, request ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
121- return request.Identity, nil
122- })
123 pool, err := NewPool(1, resolver, binder, connector, newManualClock(time.Unix(0, 0)), PoolLimits{Physical: 1, Clients: 8, Streams: 8, StreamsPerClient: 8, Warm: 1, Idle: time.Minute})120 pool, err := NewPool(1, resolver, binder, connector, newManualClock(time.Unix(0, 0)), PoolLimits{Physical: 1, Clients: 8, Streams: 8, StreamsPerClient: 8, Warm: 1, Idle: time.Minute})
124 require.NoError(t, err)121 require.NoError(t, err)
125 t.Cleanup(func() { require.NoError(t, pool.Close()) })122 t.Cleanup(func() { require.NoError(t, pool.Close()) })
@@ -131,7 +128,7 @@ func TestPoolRefusedResolutionNeverDials(t *testing.T) {
131 var typed ports.BrokerError128 var typed ports.BrokerError
132 require.ErrorAs(t, err, &typed)129 require.ErrorAs(t, err, &typed)
133 require.Equal(t, ports.BrokerErrorConflictingPolicy, typed.Code)130 require.Equal(t, ports.BrokerErrorConflictingPolicy, typed.Code)
134- require.Zero(t, dials.Load(), "a refused request must never dial")131+ connector.AssertNotCalled(t, "Connect", mock.Anything, mock.Anything)
135 }132 }
136 133
137 // TestPoolOpenFailureWithTypedNilConnection proves a failed open that still134 // TestPoolOpenFailureWithTypedNilConnection proves a failed open that still

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