-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into fix/node-deref-error
- Loading branch information
Showing
5 changed files
with
344 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package network | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/libp2p/go-libp2p" | ||
"github.com/multiformats/go-multiaddr" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetMultiAddressesForHost(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
listenAddrs []string | ||
expectEmpty bool | ||
expectError bool | ||
}{ | ||
{ | ||
name: "valid non-local addresses", | ||
listenAddrs: []string{ | ||
"/ip4/0.0.0.0/tcp/0", // Use 0.0.0.0 and port 0 for testing | ||
}, | ||
expectEmpty: false, | ||
expectError: false, | ||
}, | ||
{ | ||
name: "only localhost addresses", | ||
listenAddrs: []string{ | ||
"/ip4/127.0.0.1/tcp/0", | ||
}, | ||
expectEmpty: true, | ||
expectError: false, | ||
}, | ||
{ | ||
name: "mixed addresses", | ||
listenAddrs: []string{ | ||
"/ip4/127.0.0.1/tcp/0", | ||
"/ip4/0.0.0.0/tcp/0", | ||
}, | ||
expectEmpty: false, | ||
expectError: false, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Create a test host with specified listen addresses | ||
opts := []libp2p.Option{ | ||
libp2p.ListenAddrStrings(tt.listenAddrs...), | ||
} | ||
h, err := libp2p.New(opts...) | ||
require.NoError(t, err) | ||
defer h.Close() | ||
|
||
// Get multiaddresses | ||
addrs, err := GetMultiAddressesForHost(h) | ||
|
||
// Check error | ||
if tt.expectError { | ||
assert.Error(t, err) | ||
return | ||
} | ||
assert.NoError(t, err) | ||
|
||
// Check if empty when expected | ||
if tt.expectEmpty { | ||
assert.Empty(t, addrs) | ||
return | ||
} | ||
|
||
// Verify no localhost addresses | ||
for _, addr := range addrs { | ||
assert.NotContains(t, addr.String(), "127.0.0.1") | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func TestGetBootNodesMultiAddress(t *testing.T) { | ||
tests := []struct { | ||
name string | ||
bootstrapNodes []string | ||
expectedLen int | ||
expectError bool | ||
}{ | ||
{ | ||
name: "valid addresses", | ||
bootstrapNodes: []string{ | ||
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", | ||
"/ip4/104.131.131.83/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuK", | ||
}, | ||
expectedLen: 2, | ||
expectError: false, | ||
}, | ||
{ | ||
name: "empty list", | ||
bootstrapNodes: []string{}, | ||
expectedLen: 0, | ||
expectError: false, | ||
}, | ||
{ | ||
name: "list with empty string", | ||
bootstrapNodes: []string{""}, | ||
expectedLen: 0, | ||
expectError: false, | ||
}, | ||
{ | ||
name: "invalid address", | ||
bootstrapNodes: []string{ | ||
"invalid-address", | ||
}, | ||
expectedLen: 0, | ||
expectError: true, | ||
}, | ||
{ | ||
name: "mixed valid and empty", | ||
bootstrapNodes: []string{ | ||
"", | ||
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", | ||
}, | ||
expectedLen: 1, | ||
expectError: false, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
addrs, err := GetBootNodesMultiAddress(tt.bootstrapNodes) | ||
|
||
if tt.expectError { | ||
assert.Error(t, err) | ||
return | ||
} | ||
|
||
assert.NoError(t, err) | ||
assert.Len(t, addrs, tt.expectedLen) | ||
|
||
// Verify each address is valid | ||
for _, addr := range addrs { | ||
assert.NotNil(t, addr) | ||
assert.Implements(t, (*multiaddr.Multiaddr)(nil), addr) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package network | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/libp2p/go-libp2p" | ||
"github.com/libp2p/go-libp2p/core/host" | ||
"github.com/libp2p/go-libp2p/core/network" | ||
"github.com/libp2p/go-libp2p/core/peer" | ||
"github.com/multiformats/go-multiaddr" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestReconnectToBootnodes(t *testing.T) { | ||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
bootnode, err := libp2p.New( | ||
libp2p.ListenAddrStrings("/ip4/127.0.0.1/tcp/0"), | ||
) | ||
require.NoError(t, err) | ||
defer bootnode.Close() | ||
|
||
regularNode, err := libp2p.New() | ||
require.NoError(t, err) | ||
defer regularNode.Close() | ||
|
||
bootNodeAddr := bootnode.Addrs()[0].String() + "/p2p/" + bootnode.ID().String() | ||
|
||
tests := []struct { | ||
name string | ||
bootnodes []string | ||
expectConnected bool // New field to explicitly state connection expectation | ||
}{ | ||
{ | ||
name: "successful connection to valid bootnode", | ||
bootnodes: []string{bootNodeAddr}, | ||
expectConnected: true, | ||
}, | ||
{ | ||
name: "invalid bootnode address", | ||
bootnodes: []string{"/ip4/256.256.256.256/tcp/1234/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"}, | ||
expectConnected: false, | ||
}, | ||
{ | ||
name: "empty bootnode list", | ||
bootnodes: []string{}, | ||
expectConnected: false, // Changed to false since no connection is expected | ||
}, | ||
{ | ||
name: "unreachable bootnode", | ||
bootnodes: []string{"/ip4/127.0.0.1/tcp/1234/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"}, | ||
expectConnected: false, | ||
}, | ||
{ | ||
name: "multiple bootnodes with one valid", | ||
bootnodes: []string{ | ||
"/ip4/256.256.256.256/tcp/1234/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", | ||
bootNodeAddr, | ||
}, | ||
expectConnected: true, | ||
}, | ||
} | ||
|
||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// Disconnect from any existing connections | ||
for _, conn := range regularNode.Network().Conns() { | ||
_ = conn.Close() | ||
} | ||
|
||
// Test reconnection | ||
reconnectToBootnodes(ctx, regularNode, tt.bootnodes) | ||
|
||
// Verify connection status matches expectation | ||
connected := isConnectedToAnyBootnode(regularNode, tt.bootnodes) | ||
assert.Equal(t, tt.expectConnected, connected, | ||
"Connection status mismatch: expected connected=%v, got connected=%v", | ||
tt.expectConnected, connected) | ||
|
||
// Add small delay to allow for connection cleanup | ||
time.Sleep(100 * time.Millisecond) | ||
}) | ||
} | ||
} | ||
|
||
func isConnectedToAnyBootnode(h host.Host, bootnodes []string) bool { | ||
for _, bn := range bootnodes { | ||
if bn == "" { | ||
continue | ||
} | ||
ma, err := multiaddr.NewMultiaddr(bn) | ||
if err != nil { | ||
continue | ||
} | ||
pinfo, err := peer.AddrInfoFromP2pAddr(ma) | ||
if err != nil { | ||
continue | ||
} | ||
if h.Network().Connectedness(pinfo.ID) == network.Connected { | ||
return true | ||
} | ||
} | ||
return false | ||
} |