2023-08-21 03:50:38 +00:00
|
|
|
package pstoremanager_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p/core/event"
|
|
|
|
"github.com/libp2p/go-libp2p/core/network"
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
|
|
"github.com/libp2p/go-libp2p/p2p/host/eventbus"
|
|
|
|
"github.com/libp2p/go-libp2p/p2p/host/pstoremanager"
|
2024-06-07 06:25:43 +00:00
|
|
|
swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
|
2023-08-21 03:50:38 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2024-06-07 06:25:43 +00:00
|
|
|
"go.uber.org/mock/gomock"
|
2023-08-21 03:50:38 +00:00
|
|
|
)
|
|
|
|
|
2024-06-07 06:25:43 +00:00
|
|
|
//go:generate sh -c "go run go.uber.org/mock/mockgen -package pstoremanager_test -destination mock_peerstore_test.go github.com/libp2p/go-libp2p/core/peerstore Peerstore"
|
2023-08-21 03:50:38 +00:00
|
|
|
|
|
|
|
func TestGracePeriod(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
ctrl := gomock.NewController(t)
|
|
|
|
defer ctrl.Finish()
|
|
|
|
eventBus := eventbus.NewBus()
|
|
|
|
pstore := NewMockPeerstore(ctrl)
|
|
|
|
const gracePeriod = 250 * time.Millisecond
|
2024-06-07 06:25:43 +00:00
|
|
|
man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
|
2023-08-21 03:50:38 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer man.Close()
|
|
|
|
man.Start()
|
|
|
|
|
|
|
|
emitter, err := eventBus.Emitter(new(event.EvtPeerConnectednessChanged))
|
|
|
|
require.NoError(t, err)
|
|
|
|
start := time.Now()
|
|
|
|
removed := make(chan struct{})
|
|
|
|
pstore.EXPECT().RemovePeer(peer.ID("foobar")).DoAndReturn(func(p peer.ID) {
|
|
|
|
defer close(removed)
|
|
|
|
// make sure the call happened after the grace period
|
|
|
|
require.GreaterOrEqual(t, time.Since(start), gracePeriod)
|
|
|
|
require.LessOrEqual(t, time.Since(start), 3*gracePeriod)
|
|
|
|
})
|
|
|
|
require.NoError(t, emitter.Emit(event.EvtPeerConnectednessChanged{
|
|
|
|
Peer: "foobar",
|
|
|
|
Connectedness: network.NotConnected,
|
|
|
|
}))
|
|
|
|
<-removed
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestReconnect(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
ctrl := gomock.NewController(t)
|
|
|
|
eventBus := eventbus.NewBus()
|
|
|
|
pstore := NewMockPeerstore(ctrl)
|
|
|
|
const gracePeriod = 200 * time.Millisecond
|
2024-06-07 06:25:43 +00:00
|
|
|
man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
|
2023-08-21 03:50:38 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer man.Close()
|
|
|
|
man.Start()
|
|
|
|
|
|
|
|
emitter, err := eventBus.Emitter(new(event.EvtPeerConnectednessChanged))
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, emitter.Emit(event.EvtPeerConnectednessChanged{
|
|
|
|
Peer: "foobar",
|
|
|
|
Connectedness: network.NotConnected,
|
|
|
|
}))
|
|
|
|
require.NoError(t, emitter.Emit(event.EvtPeerConnectednessChanged{
|
|
|
|
Peer: "foobar",
|
|
|
|
Connectedness: network.Connected,
|
|
|
|
}))
|
|
|
|
time.Sleep(gracePeriod * 3 / 2)
|
|
|
|
// There should have been no calls to RemovePeer.
|
|
|
|
ctrl.Finish()
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestClose(t *testing.T) {
|
|
|
|
ctrl := gomock.NewController(t)
|
|
|
|
defer ctrl.Finish()
|
|
|
|
eventBus := eventbus.NewBus()
|
|
|
|
pstore := NewMockPeerstore(ctrl)
|
|
|
|
const gracePeriod = time.Hour
|
2024-06-07 06:25:43 +00:00
|
|
|
man, err := pstoremanager.NewPeerstoreManager(pstore, eventBus, swarmt.GenSwarm(t), pstoremanager.WithGracePeriod(gracePeriod))
|
2023-08-21 03:50:38 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
man.Start()
|
|
|
|
|
|
|
|
emitter, err := eventBus.Emitter(new(event.EvtPeerConnectednessChanged))
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
sub, err := eventBus.Subscribe(&event.EvtPeerConnectednessChanged{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.NoError(t, emitter.Emit(event.EvtPeerConnectednessChanged{
|
|
|
|
Peer: "foobar",
|
|
|
|
Connectedness: network.NotConnected,
|
|
|
|
}))
|
|
|
|
|
|
|
|
// make sure the event is sent before we close
|
|
|
|
select {
|
|
|
|
case <-sub.Out():
|
|
|
|
time.Sleep(100 * time.Millisecond) // make sure this event is also picked up by the pstoremanager
|
|
|
|
case <-time.After(5 * time.Second):
|
|
|
|
t.Fatalf("Hit timeout")
|
|
|
|
}
|
|
|
|
|
|
|
|
done := make(chan struct{})
|
|
|
|
pstore.EXPECT().RemovePeer(peer.ID("foobar")).Do(func(peer.ID) { close(done) })
|
|
|
|
require.NoError(t, man.Close())
|
|
|
|
select {
|
|
|
|
case <-done:
|
|
|
|
case <-time.After(5 * time.Second):
|
|
|
|
t.Fatalf("Hit timeout")
|
|
|
|
}
|
|
|
|
}
|