2022-06-10 11:30:51 +00:00
|
|
|
{.used.}
|
|
|
|
|
2024-05-09 14:38:55 +00:00
|
|
|
import std/[sets, random], stew/[results, byteutils], testutils/unittests
|
2024-07-05 22:03:38 +00:00
|
|
|
import waku/waku_core, waku/waku_api/message_cache, ./testlib/wakucore
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2024-05-09 14:38:55 +00:00
|
|
|
randomize()
|
|
|
|
|
2022-08-30 13:57:45 +00:00
|
|
|
suite "MessageCache":
|
2023-11-28 12:21:41 +00:00
|
|
|
setup:
|
2022-06-10 11:30:51 +00:00
|
|
|
## Given
|
2023-11-28 12:21:41 +00:00
|
|
|
let capacity = 3
|
|
|
|
let testPubsubTopic = DefaultPubsubTopic
|
|
|
|
let testContentTopic = DefaultContentTopic
|
|
|
|
let cache = MessageCache.init(capacity)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2023-11-28 12:21:41 +00:00
|
|
|
test "subscribe to topic":
|
2022-06-10 11:30:51 +00:00
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
|
|
|
|
# idempotence of subscribe is also tested
|
|
|
|
cache.contentSubscribe(testContentTopic)
|
|
|
|
cache.contentSubscribe(testContentTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.isPubsubSubscribed(testPubsubTopic)
|
|
|
|
cache.isContentSubscribed(testContentTopic)
|
|
|
|
cache.pubsubTopicCount() == 1
|
|
|
|
cache.contentTopicCount() == 1
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2023-02-13 10:43:49 +00:00
|
|
|
test "unsubscribe from topic":
|
2022-06-10 11:30:51 +00:00
|
|
|
# Init cache content
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
cache.contentSubscribe(testContentTopic)
|
|
|
|
|
|
|
|
cache.pubsubSubscribe("AnotherPubsubTopic")
|
|
|
|
cache.contentSubscribe("AnotherContentTopic")
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubUnsubscribe(testPubsubTopic)
|
|
|
|
cache.contentUnsubscribe(testContentTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
2023-11-28 12:21:41 +00:00
|
|
|
not cache.isPubsubSubscribed(testPubsubTopic)
|
|
|
|
not cache.isContentSubscribed(testContentTopic)
|
|
|
|
cache.pubsubTopicCount() == 1
|
|
|
|
cache.contentTopicCount() == 1
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
test "get messages of a subscribed topic":
|
|
|
|
## Given
|
|
|
|
let testMessage = fakeWakuMessage()
|
|
|
|
|
|
|
|
# Init cache content
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
cache.addMessage(testPubsubTopic, testMessage)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
let res = cache.getMessages(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get() == @[testMessage]
|
|
|
|
|
|
|
|
test "get messages with clean flag shoud clear the messages cache":
|
|
|
|
## Given
|
|
|
|
let testMessage = fakeWakuMessage()
|
|
|
|
|
|
|
|
# Init cache content
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
cache.addMessage(testPubsubTopic, testMessage)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## When
|
2024-03-15 23:08:47 +00:00
|
|
|
var res = cache.getMessages(testPubsubTopic, clear = true)
|
2022-06-10 11:30:51 +00:00
|
|
|
require(res.isOk())
|
|
|
|
|
2023-11-28 12:21:41 +00:00
|
|
|
res = cache.getMessages(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().len == 0
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-06-10 11:30:51 +00:00
|
|
|
test "get messages of a non-subscribed topic":
|
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(PubsubTopic("dummyPubsub"))
|
|
|
|
let res = cache.getMessages(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
|
|
|
check:
|
|
|
|
res.isErr()
|
2023-11-28 12:21:41 +00:00
|
|
|
res.error() == "not subscribed to this pubsub topic"
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
test "add messages to subscribed topic":
|
|
|
|
## Given
|
|
|
|
let testMessage = fakeWakuMessage()
|
|
|
|
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2023-02-13 10:43:49 +00:00
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.addMessage(testPubsubTopic, testMessage)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
2023-11-28 12:21:41 +00:00
|
|
|
let messages = cache.getMessages(testPubsubTopic).tryGet()
|
2022-06-10 11:30:51 +00:00
|
|
|
check:
|
|
|
|
messages == @[testMessage]
|
|
|
|
|
|
|
|
test "add messages to non-subscribed topic":
|
|
|
|
## Given
|
|
|
|
let testMessage = fakeWakuMessage()
|
|
|
|
|
2023-02-13 10:43:49 +00:00
|
|
|
## When
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.addMessage(testPubsubTopic, testMessage)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
2023-11-28 12:21:41 +00:00
|
|
|
let res = cache.getMessages(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
check:
|
2024-03-15 23:08:47 +00:00
|
|
|
res.isErr()
|
|
|
|
res.error() == "not subscribed to any pubsub topics"
|
2023-02-13 10:43:49 +00:00
|
|
|
|
2022-06-10 11:30:51 +00:00
|
|
|
test "add messages beyond the capacity":
|
|
|
|
## Given
|
2023-11-28 12:21:41 +00:00
|
|
|
var testMessages = @[fakeWakuMessage(toBytes("MSG-1"))]
|
|
|
|
|
|
|
|
# Prevent duplicate messages timestamp
|
2024-03-15 23:08:47 +00:00
|
|
|
for i in 0 ..< 5:
|
2023-11-28 12:21:41 +00:00
|
|
|
var msg = fakeWakuMessage(toBytes("MSG-1"))
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2023-11-28 12:21:41 +00:00
|
|
|
while msg.timestamp <= testMessages[i].timestamp:
|
|
|
|
msg = fakeWakuMessage(toBytes("MSG-1"))
|
|
|
|
|
|
|
|
testMessages.add(msg)
|
|
|
|
|
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
2023-02-13 10:43:49 +00:00
|
|
|
## When
|
2022-06-10 11:30:51 +00:00
|
|
|
for msg in testMessages:
|
2023-11-28 12:21:41 +00:00
|
|
|
cache.addMessage(testPubsubTopic, msg)
|
2022-06-10 11:30:51 +00:00
|
|
|
|
|
|
|
## Then
|
2023-11-28 12:21:41 +00:00
|
|
|
let messages = cache.getMessages(testPubsubTopic).tryGet()
|
|
|
|
let messageSet = toHashSet(messages)
|
|
|
|
|
|
|
|
let testSet = toHashSet(testMessages)
|
|
|
|
|
|
|
|
check:
|
|
|
|
messageSet.len == capacity
|
|
|
|
messageSet < testSet
|
|
|
|
testMessages[0] notin messages
|
|
|
|
|
|
|
|
test "get messages on pubsub via content topics":
|
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
|
|
|
|
let fakeMessage = fakeWakuMessage()
|
|
|
|
|
|
|
|
cache.addMessage(testPubsubTopic, fakeMessage)
|
|
|
|
|
|
|
|
let getRes = cache.getAutoMessages(DefaultContentTopic)
|
|
|
|
|
|
|
|
check:
|
|
|
|
getRes.isOk
|
|
|
|
getRes.get() == @[fakeMessage]
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-11-28 12:21:41 +00:00
|
|
|
test "add same message twice":
|
|
|
|
cache.pubsubSubscribe(testPubsubTopic)
|
|
|
|
|
|
|
|
let fakeMessage = fakeWakuMessage()
|
|
|
|
|
|
|
|
cache.addMessage(testPubsubTopic, fakeMessage)
|
|
|
|
cache.addMessage(testPubsubTopic, fakeMessage)
|
|
|
|
|
|
|
|
check:
|
|
|
|
cache.messagesCount() == 1
|
|
|
|
|
|
|
|
test "unsubscribing remove messages":
|
|
|
|
let topic0 = "PubsubTopic0"
|
|
|
|
let topic1 = "PubsubTopic1"
|
|
|
|
let topic2 = "PubsubTopic2"
|
|
|
|
|
|
|
|
let fakeMessage0 = fakeWakuMessage(toBytes("MSG-0"))
|
|
|
|
let fakeMessage1 = fakeWakuMessage(toBytes("MSG-1"))
|
|
|
|
let fakeMessage2 = fakeWakuMessage(toBytes("MSG-2"))
|
|
|
|
|
|
|
|
cache.pubsubSubscribe(topic0)
|
|
|
|
cache.pubsubSubscribe(topic1)
|
|
|
|
cache.pubsubSubscribe(topic2)
|
|
|
|
cache.contentSubscribe("ContentTopic0")
|
|
|
|
|
|
|
|
cache.addMessage(topic0, fakeMessage0)
|
|
|
|
cache.addMessage(topic1, fakeMessage1)
|
|
|
|
cache.addMessage(topic2, fakeMessage2)
|
|
|
|
|
|
|
|
cache.pubsubUnsubscribe(topic0)
|
|
|
|
|
|
|
|
# at this point, fakeMessage0 is only ref by DefaultContentTopic
|
|
|
|
|
|
|
|
let res = cache.getAutoMessages(DefaultContentTopic)
|
|
|
|
|
|
|
|
check:
|
|
|
|
res.isOk()
|
|
|
|
res.get().len == 3
|
|
|
|
cache.isPubsubSubscribed(topic0) == false
|
|
|
|
cache.isPubsubSubscribed(topic1) == true
|
|
|
|
cache.isPubsubSubscribed(topic2) == true
|
|
|
|
|
|
|
|
cache.contentUnsubscribe(DefaultContentTopic)
|
|
|
|
|
|
|
|
# msg0 was delete because no refs
|
|
|
|
|
2022-06-10 11:30:51 +00:00
|
|
|
check:
|
2024-03-15 23:08:47 +00:00
|
|
|
cache.messagesCount() == 2
|
2024-05-09 14:38:55 +00:00
|
|
|
|
|
|
|
test "fuzzing":
|
|
|
|
let testContentTopic1 = "contentTopic1"
|
|
|
|
let testContentTopic2 = "contentTopic2"
|
|
|
|
|
|
|
|
let cache = MessageCache.init(50)
|
|
|
|
|
|
|
|
cache.contentSubscribe(testContentTopic1)
|
|
|
|
cache.contentSubscribe(testContentTopic2)
|
|
|
|
|
|
|
|
for _ in 0 .. 10000:
|
|
|
|
let numb = rand(1.0)
|
|
|
|
|
|
|
|
if numb > 0.4:
|
|
|
|
let topic = if rand(1.0) > 0.5: testContentTopic1 else: testContentTopic2
|
|
|
|
|
|
|
|
let testMessage = fakeWakuMessage(contentTopic = topic)
|
|
|
|
|
|
|
|
cache.addMessage(DefaultPubsubTopic, testMessage)
|
|
|
|
elif numb > 0.1:
|
|
|
|
let topic = if rand(1.0) > 0.5: testContentTopic1 else: testContentTopic2
|
|
|
|
|
|
|
|
let clear = rand(1.0) > 0.5
|
|
|
|
discard cache.getAutoMessages(topic, clear)
|
|
|
|
elif numb > 0.05:
|
|
|
|
if rand(1.0) > 0.5:
|
|
|
|
cache.pubsubUnsubscribe(DefaultPubsubTopic)
|
|
|
|
else:
|
|
|
|
cache.pubsubSubscribe(DefaultPubsubTopic)
|
|
|
|
else:
|
|
|
|
let topic = if rand(1.0) > 0.5: testContentTopic1 else: testContentTopic2
|
|
|
|
|
|
|
|
if rand(1.0) > 0.5:
|
|
|
|
cache.contentUnsubscribe(topic)
|
|
|
|
else:
|
|
|
|
cache.contentSubscribe(topic)
|