2021-11-02 00:04:54 +00:00
|
|
|
package node
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"net"
|
|
|
|
"sync"
|
|
|
|
"testing"
|
2021-11-04 18:33:55 +00:00
|
|
|
"time"
|
2021-11-02 00:04:54 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2024-02-08 09:54:58 +00:00
|
|
|
"github.com/waku-org/go-waku/waku/v2/peermanager"
|
|
|
|
"github.com/waku-org/go-waku/waku/v2/peerstore"
|
|
|
|
"github.com/waku-org/go-waku/waku/v2/protocol"
|
2021-11-02 00:04:54 +00:00
|
|
|
)
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
const pubsubTopic = "/waku/2/rs/16/1000"
|
|
|
|
|
|
|
|
func goCheckConnectedness(t *testing.T, wg *sync.WaitGroup, topicHealthStatusChan chan peermanager.TopicHealthStatus,
|
|
|
|
healthStatus peermanager.TopicHealth) {
|
2021-11-04 18:33:55 +00:00
|
|
|
wg.Add(1)
|
2024-02-08 09:54:58 +00:00
|
|
|
go checkConnectedness(t, wg, topicHealthStatusChan, healthStatus)
|
2022-06-10 12:15:00 +00:00
|
|
|
}
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
func checkConnectedness(t *testing.T, wg *sync.WaitGroup, topicHealthStatusChan chan peermanager.TopicHealthStatus,
|
|
|
|
healthStatus peermanager.TopicHealth) {
|
2021-11-04 18:33:55 +00:00
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
timeout := time.After(5 * time.Second)
|
|
|
|
|
|
|
|
select {
|
2024-02-08 09:54:58 +00:00
|
|
|
case topicHealthStatus := <-topicHealthStatusChan:
|
|
|
|
require.Equal(t, healthStatus, topicHealthStatus.Health)
|
|
|
|
t.Log("received health status update ", topicHealthStatus.Health, "expected is ", healthStatus)
|
|
|
|
return
|
2021-11-04 18:33:55 +00:00
|
|
|
case <-timeout:
|
2024-02-08 09:54:58 +00:00
|
|
|
require.Fail(t, "health status should have changed")
|
2021-11-04 18:33:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-02 00:04:54 +00:00
|
|
|
func TestConnectionStatusChanges(t *testing.T) {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
topicHealthStatusChan := make(chan peermanager.TopicHealthStatus, 100)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
|
|
|
// Node1: Only Relay
|
|
|
|
hostAddr1, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
|
|
|
|
require.NoError(t, err)
|
2023-01-06 22:37:57 +00:00
|
|
|
node1, err := New(
|
2021-11-17 16:19:42 +00:00
|
|
|
WithHostAddress(hostAddr1),
|
2021-11-02 00:04:54 +00:00
|
|
|
WithWakuRelay(),
|
2024-03-14 14:21:47 +00:00
|
|
|
WithClusterID(16),
|
2024-02-08 09:54:58 +00:00
|
|
|
WithTopicHealthStatusChannel(topicHealthStatusChan),
|
2021-11-02 00:04:54 +00:00
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
2023-01-06 22:37:57 +00:00
|
|
|
err = node1.Start(ctx)
|
2021-11-02 00:04:54 +00:00
|
|
|
require.NoError(t, err)
|
2024-02-08 09:54:58 +00:00
|
|
|
_, err = node1.Relay().Subscribe(ctx, protocol.NewContentFilter(pubsubTopic))
|
2021-11-02 00:04:54 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
// Node2: Relay
|
|
|
|
node2 := startNodeAndSubscribe(t, ctx)
|
2022-05-30 18:48:22 +00:00
|
|
|
|
2021-11-02 00:04:54 +00:00
|
|
|
// Node3: Relay + Store
|
2024-02-08 09:54:58 +00:00
|
|
|
node3 := startNodeAndSubscribe(t, ctx)
|
|
|
|
|
|
|
|
// Node4: Relay
|
|
|
|
node4 := startNodeAndSubscribe(t, ctx)
|
|
|
|
|
|
|
|
// Node5: Relay
|
|
|
|
node5 := startNodeAndSubscribe(t, ctx)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
goCheckConnectedness(t, &wg, topicHealthStatusChan, peermanager.MinimallyHealthy)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
node1.AddDiscoveredPeer(node2.host.ID(), node2.ListenAddresses(), peerstore.Static, []string{pubsubTopic}, true)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2021-11-04 18:33:55 +00:00
|
|
|
err = node1.DialPeer(ctx, node3.ListenAddresses()[0].String())
|
|
|
|
require.NoError(t, err)
|
2021-11-02 00:12:18 +00:00
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
err = node1.DialPeer(ctx, node4.ListenAddresses()[0].String())
|
|
|
|
require.NoError(t, err)
|
|
|
|
goCheckConnectedness(t, &wg, topicHealthStatusChan, peermanager.SufficientlyHealthy)
|
|
|
|
|
|
|
|
err = node1.DialPeer(ctx, node5.ListenAddresses()[0].String())
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
goCheckConnectedness(t, &wg, topicHealthStatusChan, peermanager.MinimallyHealthy)
|
2021-11-04 18:33:55 +00:00
|
|
|
|
|
|
|
node3.Stop()
|
2021-11-02 00:04:54 +00:00
|
|
|
|
|
|
|
wg.Wait()
|
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
goCheckConnectedness(t, &wg, topicHealthStatusChan, peermanager.UnHealthy)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
2021-11-04 18:33:55 +00:00
|
|
|
err = node1.ClosePeerById(node2.Host().ID())
|
|
|
|
require.NoError(t, err)
|
2024-02-08 09:54:58 +00:00
|
|
|
|
|
|
|
node4.Stop()
|
|
|
|
node5.Stop()
|
|
|
|
|
2021-11-04 18:33:55 +00:00
|
|
|
wg.Wait()
|
2021-11-02 00:12:18 +00:00
|
|
|
|
2024-02-08 09:54:58 +00:00
|
|
|
goCheckConnectedness(t, &wg, topicHealthStatusChan, peermanager.MinimallyHealthy)
|
2021-11-02 00:04:54 +00:00
|
|
|
|
2021-11-04 18:33:55 +00:00
|
|
|
err = node1.DialPeerByID(ctx, node2.Host().ID())
|
|
|
|
require.NoError(t, err)
|
2021-11-02 00:04:54 +00:00
|
|
|
wg.Wait()
|
|
|
|
}
|
2024-02-08 09:54:58 +00:00
|
|
|
|
|
|
|
func startNodeAndSubscribe(t *testing.T, ctx context.Context) *WakuNode {
|
|
|
|
hostAddr, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
|
|
|
|
require.NoError(t, err)
|
|
|
|
node, err := New(
|
|
|
|
WithHostAddress(hostAddr),
|
|
|
|
WithWakuRelay(),
|
2024-03-14 14:21:47 +00:00
|
|
|
WithClusterID(16),
|
2024-02-08 09:54:58 +00:00
|
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
|
|
err = node.Start(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
_, err = node.Relay().Subscribe(ctx, protocol.NewContentFilter(pubsubTopic))
|
|
|
|
require.NoError(t, err)
|
|
|
|
return node
|
|
|
|
}
|