Skip to content

Commit 100618d

Browse files
committed
test(client): add tests for relay peer configuration and client behavior
1 parent cc59a51 commit 100618d

File tree

1 file changed

+287
-0
lines changed

1 file changed

+287
-0
lines changed

client_additional_test.go

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
package p2p
2+
3+
import (
4+
"testing"
5+
"time"
6+
7+
"github.com/libp2p/go-libp2p/core/peer"
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestNewClientWithCustomRelayPeers(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
relayPeers []string
16+
wantErr bool
17+
}{
18+
{
19+
name: "single relay peer",
20+
relayPeers: []string{
21+
"/ip4/127.0.0.1/tcp/4001/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N",
22+
},
23+
wantErr: false,
24+
},
25+
{
26+
name: "empty relay peers",
27+
relayPeers: []string{},
28+
wantErr: false,
29+
},
30+
{
31+
name: "invalid relay peer",
32+
relayPeers: []string{
33+
"invalid-relay",
34+
},
35+
wantErr: false, // Invalid relays are logged but don't fail client creation
36+
},
37+
}
38+
39+
for _, tt := range tests {
40+
t.Run(tt.name, func(t *testing.T) {
41+
privKey, err := GeneratePrivateKey()
42+
require.NoError(t, err)
43+
44+
config := Config{
45+
Name: testPeerName,
46+
PrivateKey: privKey,
47+
RelayPeers: tt.relayPeers,
48+
}
49+
50+
cl, err := NewClient(config)
51+
if tt.wantErr {
52+
require.Error(t, err)
53+
} else {
54+
require.NoError(t, err)
55+
require.NotNil(t, cl)
56+
closeErr := cl.Close()
57+
require.NoError(t, closeErr)
58+
}
59+
})
60+
}
61+
}
62+
63+
func TestConfigureRelayPeersWithValidPeers(t *testing.T) {
64+
logger := &DefaultLogger{}
65+
bootstrapPeers := []peer.AddrInfo{}
66+
67+
// Valid relay peer
68+
relayPeersConfig := []string{
69+
"/ip4/127.0.0.1/tcp/4001/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N",
70+
}
71+
72+
relayPeers := configureRelayPeers(relayPeersConfig, bootstrapPeers, logger)
73+
74+
assert.Len(t, relayPeers, 1)
75+
}
76+
77+
func TestConfigureRelayPeersWithMixedValidity(t *testing.T) {
78+
logger := &DefaultLogger{}
79+
bootstrapPeers := []peer.AddrInfo{}
80+
81+
// Mix of valid and invalid
82+
relayPeersConfig := []string{
83+
"/ip4/127.0.0.1/tcp/4001/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N",
84+
"invalid-peer",
85+
}
86+
87+
relayPeers := configureRelayPeers(relayPeersConfig, bootstrapPeers, logger)
88+
89+
// Should have 1 valid peer (second one is invalid)
90+
assert.Len(t, relayPeers, 1)
91+
}
92+
93+
func TestClientCloseTwice(t *testing.T) {
94+
privKey, err := GeneratePrivateKey()
95+
require.NoError(t, err)
96+
97+
config := Config{
98+
Name: testPeerName,
99+
PrivateKey: privKey,
100+
}
101+
102+
cl, err := NewClient(config)
103+
require.NoError(t, err)
104+
105+
// First close
106+
err = cl.Close()
107+
require.NoError(t, err)
108+
109+
// Second close should not panic
110+
err = cl.Close()
111+
// May return error or nil, both are acceptable
112+
_ = err
113+
}
114+
115+
func TestClientWithBootstrapPeers(t *testing.T) {
116+
privKey, err := GeneratePrivateKey()
117+
require.NoError(t, err)
118+
119+
config := Config{
120+
Name: testPeerName,
121+
PrivateKey: privKey,
122+
BootstrapPeers: []string{
123+
"/ip4/127.0.0.1/tcp/9999/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N",
124+
},
125+
}
126+
127+
cl, err := NewClient(config)
128+
require.NoError(t, err)
129+
130+
err = cl.Close()
131+
require.NoError(t, err)
132+
}
133+
134+
func TestGetPeersWithNoConnections(t *testing.T) {
135+
privKey, err := GeneratePrivateKey()
136+
require.NoError(t, err)
137+
138+
config := Config{
139+
Name: testPeerName,
140+
PrivateKey: privKey,
141+
}
142+
143+
cl, err := NewClient(config)
144+
require.NoError(t, err)
145+
defer func() {
146+
closeErr := cl.Close()
147+
require.NoError(t, closeErr)
148+
}()
149+
150+
c := cl.(*client)
151+
152+
// Manually add a peer to the tracker
153+
testPeerID := generateTestPeerID(t)
154+
c.peerTracker.recordMessageFrom(testPeerID)
155+
156+
peers := cl.GetPeers()
157+
158+
// Should have one peer, even without connections
159+
assert.Len(t, peers, 1)
160+
assert.Equal(t, testPeerID.String(), peers[0].ID)
161+
}
162+
163+
func TestClientSubscribeAndClose(t *testing.T) {
164+
privKey, err := GeneratePrivateKey()
165+
require.NoError(t, err)
166+
167+
config := Config{
168+
Name: testPeerName,
169+
PrivateKey: privKey,
170+
}
171+
172+
cl, err := NewClient(config)
173+
require.NoError(t, err)
174+
175+
// Subscribe to a topic
176+
msgChan := cl.Subscribe("test-topic")
177+
require.NotNil(t, msgChan)
178+
179+
// Give subscription time to initialize
180+
time.Sleep(100 * time.Millisecond)
181+
182+
// Close immediately
183+
err = cl.Close()
184+
require.NoError(t, err)
185+
186+
// Channel should be closed
187+
select {
188+
case _, ok := <-msgChan:
189+
assert.False(t, ok, "channel should be closed")
190+
case <-time.After(100 * time.Millisecond):
191+
t.Fatal("channel not closed in time")
192+
}
193+
}
194+
195+
func TestClientWithAllOptions(t *testing.T) {
196+
privKey, err := GeneratePrivateKey()
197+
require.NoError(t, err)
198+
199+
config := Config{
200+
Name: "full-featured-client",
201+
PrivateKey: privKey,
202+
ProtocolVersion: "test/1.0.0",
203+
Port: 0,
204+
PeerCacheTTL: 1 * time.Hour,
205+
Logger: &DefaultLogger{},
206+
AnnounceAddrs: []string{"/ip4/192.168.1.100/tcp/4001"},
207+
}
208+
209+
cl, err := NewClient(config)
210+
require.NoError(t, err)
211+
require.NotNil(t, cl)
212+
213+
err = cl.Close()
214+
require.NoError(t, err)
215+
}
216+
217+
func TestConnectToRelayPeersWithCustomPeers(t *testing.T) {
218+
privKey, err := GeneratePrivateKey()
219+
require.NoError(t, err)
220+
221+
config := Config{
222+
Name: testPeerName,
223+
PrivateKey: privKey,
224+
RelayPeers: []string{
225+
"/ip4/127.0.0.1/tcp/9999/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N",
226+
},
227+
}
228+
229+
cl, err := NewClient(config)
230+
require.NoError(t, err)
231+
232+
// Give time for connection attempts
233+
time.Sleep(100 * time.Millisecond)
234+
235+
err = cl.Close()
236+
require.NoError(t, err)
237+
}
238+
239+
func TestConnectToDiscoveredPeerWithRealConnection(t *testing.T) {
240+
// Create two clients that can discover each other
241+
privKey1, err := GeneratePrivateKey()
242+
require.NoError(t, err)
243+
244+
privKey2, err := GeneratePrivateKey()
245+
require.NoError(t, err)
246+
247+
config1 := Config{
248+
Name: "peer1",
249+
PrivateKey: privKey1,
250+
Port: 0,
251+
}
252+
253+
config2 := Config{
254+
Name: "peer2",
255+
PrivateKey: privKey2,
256+
Port: 0,
257+
}
258+
259+
cl1, err := NewClient(config1)
260+
require.NoError(t, err)
261+
defer func() {
262+
closeErr := cl1.Close()
263+
require.NoError(t, closeErr)
264+
}()
265+
266+
cl2, err := NewClient(config2)
267+
require.NoError(t, err)
268+
defer func() {
269+
closeErr := cl2.Close()
270+
require.NoError(t, closeErr)
271+
}()
272+
273+
// Subscribe both to same topic
274+
_ = cl1.Subscribe("discovery-test")
275+
_ = cl2.Subscribe("discovery-test")
276+
277+
// Give time for discovery - mDNS discovery should work locally
278+
time.Sleep(5 * time.Second)
279+
280+
// Check if peers discovered each other
281+
peers1 := cl1.GetPeers()
282+
peers2 := cl2.GetPeers()
283+
284+
// This is a best-effort test - discovery may not always work in test environment
285+
// Just verify no panic occurred
286+
t.Logf("Peer1 discovered %d peers, Peer2 discovered %d peers", len(peers1), len(peers2))
287+
}

0 commit comments

Comments
 (0)