2021-11-10 14:28:45 +00:00
|
|
|
package protocol
|
|
|
|
|
|
|
|
import (
|
2023-09-06 04:37:21 +00:00
|
|
|
"math/rand"
|
2021-11-10 14:28:45 +00:00
|
|
|
"testing"
|
2023-09-06 04:37:21 +00:00
|
|
|
"time"
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
2023-08-25 04:25:38 +00:00
|
|
|
func TestContentTopicAndSharding(t *testing.T) {
|
2023-11-08 12:54:24 +00:00
|
|
|
ct, err := NewContentTopic("waku", "2", "test", "proto")
|
2023-08-25 04:25:38 +00:00
|
|
|
require.NoError(t, err)
|
2021-11-10 14:28:45 +00:00
|
|
|
require.Equal(t, ct.String(), "/waku/2/test/proto")
|
|
|
|
|
2023-08-25 04:25:38 +00:00
|
|
|
_, err = StringToContentTopic("/waku/-1/a/b")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.NoError(t, err)
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
_, err = StringToContentTopic("waku/1/a/b")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.Error(t, err, ErrInvalidFormat)
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
_, err = StringToContentTopic("////")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.Error(t, err, ErrInvalidFormat)
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
_, err = StringToContentTopic("/waku/1/a")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.Error(t, err, ErrInvalidFormat)
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
ct2, err := StringToContentTopic("/waku/2/test/proto")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, ct.String(), ct2.String())
|
|
|
|
require.True(t, ct.Equal(ct2))
|
|
|
|
|
2023-11-08 12:54:24 +00:00
|
|
|
ct3, err := NewContentTopic("waku", "2a", "test2", "proto")
|
2023-08-25 04:25:38 +00:00
|
|
|
require.NoError(t, err)
|
2021-11-10 14:28:45 +00:00
|
|
|
require.False(t, ct.Equal(ct3))
|
2023-08-25 04:25:38 +00:00
|
|
|
|
|
|
|
ct4, err := StringToContentTopic("/0/toychat/2/huilong/proto")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, ct4.Generation, 0)
|
|
|
|
|
|
|
|
ct6, err := StringToContentTopic("/toychat/2/huilong/proto")
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
nsPubSubT1 := GetShardFromContentTopic(ct6, GenerationZeroShardsCount)
|
|
|
|
require.Equal(t, NewStaticShardingPubsubTopic(ClusterIndex, 3), nsPubSubT1)
|
|
|
|
|
|
|
|
_, err = StringToContentTopic("/abc/toychat/2/huilong/proto")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.Error(t, err, ErrInvalidGeneration)
|
2023-08-25 04:25:38 +00:00
|
|
|
|
|
|
|
_, err = StringToContentTopic("/1/toychat/2/huilong/proto")
|
2023-11-08 12:54:24 +00:00
|
|
|
require.Error(t, err, ErrInvalidGeneration)
|
2023-08-25 04:25:38 +00:00
|
|
|
|
2023-11-08 12:54:24 +00:00
|
|
|
ct5, err := NewContentTopic("waku", "2b", "test2", "proto", WithGeneration(0))
|
2023-08-25 04:25:38 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, ct5.Generation, 0)
|
2021-11-10 14:28:45 +00:00
|
|
|
}
|
|
|
|
|
2023-09-06 04:37:21 +00:00
|
|
|
func randomContentTopic() (ContentTopic, error) {
|
|
|
|
var app = ""
|
|
|
|
const WordLength = 5
|
|
|
|
rand.New(rand.NewSource(time.Now().Unix()))
|
|
|
|
|
|
|
|
//Generate a random character between lowercase a to z
|
|
|
|
for i := 0; i < WordLength; i++ {
|
|
|
|
randomChar := 'a' + rune(rand.Intn(26))
|
|
|
|
app = app + string(randomChar)
|
|
|
|
}
|
2023-11-08 12:54:24 +00:00
|
|
|
version := "1"
|
2023-09-06 04:37:21 +00:00
|
|
|
|
|
|
|
var name = ""
|
|
|
|
|
|
|
|
for i := 0; i < WordLength; i++ {
|
|
|
|
randomChar := 'a' + rune(rand.Intn(26))
|
|
|
|
name = name + string(randomChar)
|
|
|
|
}
|
|
|
|
var enc = "proto"
|
|
|
|
|
|
|
|
return NewContentTopic(app, version, name, enc)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestShardChoiceSimulation(t *testing.T) {
|
|
|
|
//Given
|
|
|
|
var topics []ContentTopic
|
|
|
|
for i := 0; i < 100000; i++ {
|
|
|
|
ct, err := randomContentTopic()
|
|
|
|
require.NoError(t, err)
|
|
|
|
topics = append(topics, ct)
|
|
|
|
}
|
|
|
|
|
|
|
|
var counts [GenerationZeroShardsCount]int
|
|
|
|
|
|
|
|
// When
|
|
|
|
for _, topic := range topics {
|
|
|
|
pubsub := GetShardFromContentTopic(topic, GenerationZeroShardsCount)
|
|
|
|
counts[pubsub.Shard()]++
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Logf("Total number of topics simulated %d", len(topics))
|
|
|
|
for i := 0; i < GenerationZeroShardsCount; i++ {
|
|
|
|
t.Logf("Topics assigned to shard %d is %d", i, counts[i])
|
|
|
|
}
|
|
|
|
|
|
|
|
// Then
|
|
|
|
for i := 1; i < GenerationZeroShardsCount; i++ {
|
|
|
|
//t.Logf("float64(counts[%d]) %f float64(counts[%d]) %f", i-1, float64(counts[i-1]), i, float64(counts[i]))
|
|
|
|
if float64(counts[i-1]) <= (float64(counts[i])*1.05) &&
|
|
|
|
float64(counts[i]) <= (float64(counts[i-1])*1.05) &&
|
|
|
|
float64(counts[i-1]) >= (float64(counts[i])*0.95) &&
|
|
|
|
float64(counts[i]) >= (float64(counts[i-1])*0.95) {
|
|
|
|
t.Logf("Shard choice simulation successful")
|
|
|
|
} else {
|
|
|
|
t.FailNow()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-30 14:56:26 +00:00
|
|
|
func TestShardPubsubTopic(t *testing.T) {
|
|
|
|
{ // not waku topci
|
|
|
|
topic := "/waku/1/2/3"
|
|
|
|
_, err := ToWakuPubsubTopic(topic)
|
|
|
|
require.Error(t, ErrNotWakuPubsubTopic, err)
|
|
|
|
}
|
2021-11-10 14:28:45 +00:00
|
|
|
|
2023-10-30 14:56:26 +00:00
|
|
|
{ // check default pubsub topic
|
|
|
|
topic := defaultPubsubTopic
|
|
|
|
wakuTopic, err := ToWakuPubsubTopic(topic)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, defaultPubsubTopic, wakuTopic.String())
|
|
|
|
}
|
2021-11-10 14:28:45 +00:00
|
|
|
|
2023-10-30 14:56:26 +00:00
|
|
|
{ // check behavior of waku topic
|
|
|
|
topic := "/waku/2/rs/16/42"
|
|
|
|
wakuTopic, err := ToWakuPubsubTopic(topic)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, topic, wakuTopic.String())
|
|
|
|
require.Equal(t, uint16(16), wakuTopic.(StaticShardingPubsubTopic).Cluster())
|
|
|
|
require.Equal(t, uint16(42), wakuTopic.(StaticShardingPubsubTopic).Shard())
|
|
|
|
}
|
2021-11-10 14:28:45 +00:00
|
|
|
|
2023-10-30 14:56:26 +00:00
|
|
|
{ // check if shard pubtopic checks for prefix
|
|
|
|
topic := "/waku/1/rs/16/42"
|
|
|
|
err := (&StaticShardingPubsubTopic{}).Parse(topic)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.ErrorIs(t, err, ErrInvalidShardedTopicPrefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // check if cluster/index is missing
|
|
|
|
topic := "/waku/2/rs//02"
|
|
|
|
_, err := ToWakuPubsubTopic(topic)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.ErrorIs(t, err, ErrMissingClusterIndex)
|
|
|
|
|
|
|
|
topic = "/waku/2/rs/1/"
|
|
|
|
_, err = ToWakuPubsubTopic(topic)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.ErrorIs(t, err, ErrMissingShardNumber)
|
|
|
|
}
|
|
|
|
|
|
|
|
{ // check if the cluster/index are number
|
|
|
|
topic := "/waku/2/rs/xx/77"
|
|
|
|
_, err := ToWakuPubsubTopic(topic)
|
|
|
|
require.Error(t, err)
|
|
|
|
require.ErrorIs(t, err, ErrInvalidNumberFormat)
|
|
|
|
}
|
2021-11-10 14:28:45 +00:00
|
|
|
|
|
|
|
}
|