Skip to content

Commit 1597904

Browse files
committed
Add tests for SpectatorPeerChooser
Tests cover: - Success path with peer creation - Peer reuse on subsequent calls - Error cases (missing shard key, namespace header, spectator not found) - Lifecycle methods (Start, Stop, IsRunning) - SetSpectators method Signed-off-by: Jakob Haahr Taankvist <[email protected]>
1 parent e314db0 commit 1597904

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
package spectatorclient
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
"go.uber.org/mock/gomock"
10+
"go.uber.org/yarpc/api/peer"
11+
"go.uber.org/yarpc/api/transport"
12+
"go.uber.org/yarpc/transport/grpc"
13+
14+
"github.com/uber/cadence/common/log/testlogger"
15+
)
16+
17+
func TestSpectatorPeerChooser_Choose_MissingShardKey(t *testing.T) {
18+
chooser := &SpectatorPeerChooser{
19+
logger: testlogger.New(t),
20+
peers: make(map[string]peer.Peer),
21+
}
22+
23+
req := &transport.Request{
24+
ShardKey: "",
25+
Headers: transport.NewHeaders(),
26+
}
27+
28+
p, onFinish, err := chooser.Choose(context.Background(), req)
29+
30+
assert.Error(t, err)
31+
assert.Nil(t, p)
32+
assert.Nil(t, onFinish)
33+
assert.Contains(t, err.Error(), "ShardKey")
34+
}
35+
36+
func TestSpectatorPeerChooser_Choose_MissingNamespaceHeader(t *testing.T) {
37+
chooser := &SpectatorPeerChooser{
38+
logger: testlogger.New(t),
39+
peers: make(map[string]peer.Peer),
40+
}
41+
42+
req := &transport.Request{
43+
ShardKey: "shard-1",
44+
Headers: transport.NewHeaders(),
45+
}
46+
47+
p, onFinish, err := chooser.Choose(context.Background(), req)
48+
49+
assert.Error(t, err)
50+
assert.Nil(t, p)
51+
assert.Nil(t, onFinish)
52+
assert.Contains(t, err.Error(), "x-shard-distributor-namespace")
53+
}
54+
55+
func TestSpectatorPeerChooser_Choose_SpectatorNotFound(t *testing.T) {
56+
chooser := &SpectatorPeerChooser{
57+
logger: testlogger.New(t),
58+
peers: make(map[string]peer.Peer),
59+
spectators: make(Spectators),
60+
}
61+
62+
req := &transport.Request{
63+
ShardKey: "shard-1",
64+
Headers: transport.NewHeaders().With(NamespaceHeader, "unknown-namespace"),
65+
}
66+
67+
p, onFinish, err := chooser.Choose(context.Background(), req)
68+
69+
assert.Error(t, err)
70+
assert.Nil(t, p)
71+
assert.Nil(t, onFinish)
72+
assert.Contains(t, err.Error(), "spectator not found")
73+
}
74+
75+
func TestSpectatorPeerChooser_StartStop(t *testing.T) {
76+
chooser := &SpectatorPeerChooser{
77+
logger: testlogger.New(t),
78+
peers: make(map[string]peer.Peer),
79+
}
80+
81+
err := chooser.Start()
82+
require.NoError(t, err)
83+
84+
assert.True(t, chooser.IsRunning())
85+
86+
err = chooser.Stop()
87+
assert.NoError(t, err)
88+
}
89+
90+
func TestSpectatorPeerChooser_SetSpectators(t *testing.T) {
91+
chooser := &SpectatorPeerChooser{
92+
logger: testlogger.New(t),
93+
}
94+
95+
spectators := make(Spectators)
96+
chooser.SetSpectators(spectators)
97+
98+
assert.Equal(t, spectators, chooser.spectators)
99+
}
100+
101+
func TestSpectatorPeerChooser_Choose_Success(t *testing.T) {
102+
ctrl := gomock.NewController(t)
103+
defer ctrl.Finish()
104+
105+
mockSpectator := NewMockSpectator(ctrl)
106+
peerTransport := grpc.NewTransport()
107+
108+
chooser := &SpectatorPeerChooser{
109+
transport: peerTransport,
110+
logger: testlogger.New(t),
111+
peers: make(map[string]peer.Peer),
112+
spectators: Spectators{
113+
"test-namespace": mockSpectator,
114+
},
115+
}
116+
117+
ctx := context.Background()
118+
req := &transport.Request{
119+
ShardKey: "shard-1",
120+
Headers: transport.NewHeaders().With(NamespaceHeader, "test-namespace"),
121+
}
122+
123+
// Mock spectator to return shard owner with grpc_address
124+
mockSpectator.EXPECT().
125+
GetShardOwner(ctx, "shard-1").
126+
Return(&ShardOwner{
127+
ExecutorID: "executor-1",
128+
Metadata: map[string]string{
129+
grpcAddressMetadataKey: "127.0.0.1:7953",
130+
},
131+
}, nil)
132+
133+
// Execute
134+
p, onFinish, err := chooser.Choose(ctx, req)
135+
136+
// Assert
137+
assert.NoError(t, err)
138+
assert.NotNil(t, p)
139+
assert.NotNil(t, onFinish)
140+
assert.Equal(t, "127.0.0.1:7953", p.Identifier())
141+
assert.Len(t, chooser.peers, 1)
142+
}
143+
144+
func TestSpectatorPeerChooser_Choose_ReusesPeer(t *testing.T) {
145+
ctrl := gomock.NewController(t)
146+
defer ctrl.Finish()
147+
148+
mockSpectator := NewMockSpectator(ctrl)
149+
peerTransport := grpc.NewTransport()
150+
151+
chooser := &SpectatorPeerChooser{
152+
transport: peerTransport,
153+
logger: testlogger.New(t),
154+
peers: make(map[string]peer.Peer),
155+
spectators: Spectators{
156+
"test-namespace": mockSpectator,
157+
},
158+
}
159+
160+
req := &transport.Request{
161+
ShardKey: "shard-1",
162+
Headers: transport.NewHeaders().With(NamespaceHeader, "test-namespace"),
163+
}
164+
165+
// First call creates the peer
166+
mockSpectator.EXPECT().
167+
GetShardOwner(gomock.Any(), "shard-1").
168+
Return(&ShardOwner{
169+
ExecutorID: "executor-1",
170+
Metadata: map[string]string{
171+
grpcAddressMetadataKey: "127.0.0.1:7953",
172+
},
173+
}, nil).Times(2)
174+
175+
firstPeer, _, err := chooser.Choose(context.Background(), req)
176+
require.NoError(t, err)
177+
178+
// Second call should reuse the same peer
179+
secondPeer, _, err := chooser.Choose(context.Background(), req)
180+
181+
// Assert - should reuse existing peer
182+
assert.NoError(t, err)
183+
assert.Equal(t, firstPeer, secondPeer)
184+
assert.Len(t, chooser.peers, 1)
185+
}

0 commit comments

Comments
 (0)