2023-12-19 14:38:43 +00:00
|
|
|
{.used.}
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
import std/options, testutils/unittests, chronos, chronicles, libp2p/crypto/crypto
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
import
|
2024-03-15 23:08:47 +00:00
|
|
|
../../../waku/
|
|
|
|
[node/peer_manager, waku_core, waku_store, waku_store/client, common/paging],
|
|
|
|
../testlib/[common, wakucore, testasync, futures],
|
2023-12-19 14:38:43 +00:00
|
|
|
./store_utils
|
|
|
|
|
|
|
|
suite "Store Client":
|
|
|
|
var message1 {.threadvar.}: WakuMessage
|
|
|
|
var message2 {.threadvar.}: WakuMessage
|
|
|
|
var message3 {.threadvar.}: WakuMessage
|
2024-04-25 13:09:52 +00:00
|
|
|
var hash1 {.threadvar.}: WakuMessageHash
|
|
|
|
var hash2 {.threadvar.}: WakuMessageHash
|
|
|
|
var hash3 {.threadvar.}: WakuMessageHash
|
|
|
|
var messageSeq {.threadvar.}: seq[WakuMessageKeyValue]
|
|
|
|
var handlerFuture {.threadvar.}: Future[StoreQueryRequest]
|
|
|
|
var handler {.threadvar.}: StoreQueryRequestHandler
|
|
|
|
var storeQuery {.threadvar.}: StoreQueryRequest
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
var serverSwitch {.threadvar.}: Switch
|
|
|
|
var clientSwitch {.threadvar.}: Switch
|
|
|
|
|
|
|
|
var server {.threadvar.}: WakuStore
|
|
|
|
var client {.threadvar.}: WakuStoreClient
|
|
|
|
|
|
|
|
var serverPeerInfo {.threadvar.}: RemotePeerInfo
|
|
|
|
var clientPeerInfo {.threadvar.}: RemotePeerInfo
|
|
|
|
|
|
|
|
asyncSetup:
|
2024-03-15 23:08:47 +00:00
|
|
|
message1 = fakeWakuMessage(contentTopic = DefaultContentTopic)
|
|
|
|
message2 = fakeWakuMessage(contentTopic = DefaultContentTopic)
|
|
|
|
message3 = fakeWakuMessage(contentTopic = DefaultContentTopic)
|
2024-04-25 13:09:52 +00:00
|
|
|
hash1 = computeMessageHash(DefaultPubsubTopic, message1)
|
|
|
|
hash2 = computeMessageHash(DefaultPubsubTopic, message2)
|
|
|
|
hash3 = computeMessageHash(DefaultPubsubTopic, message3)
|
|
|
|
messageSeq =
|
|
|
|
@[
|
2024-05-08 19:35:56 +00:00
|
|
|
WakuMessageKeyValue(
|
|
|
|
messageHash: hash1,
|
|
|
|
message: some(message1),
|
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
),
|
|
|
|
WakuMessageKeyValue(
|
|
|
|
messageHash: hash2,
|
|
|
|
message: some(message2),
|
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
),
|
|
|
|
WakuMessageKeyValue(
|
|
|
|
messageHash: hash3,
|
|
|
|
message: some(message3),
|
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
),
|
2024-04-25 13:09:52 +00:00
|
|
|
]
|
2023-12-19 14:38:43 +00:00
|
|
|
handlerFuture = newHistoryFuture()
|
2024-04-25 13:09:52 +00:00
|
|
|
handler = proc(req: StoreQueryRequest): Future[StoreQueryResult] {.async, gcsafe.} =
|
|
|
|
var request = req
|
|
|
|
request.requestId = ""
|
|
|
|
handlerFuture.complete(request)
|
|
|
|
return ok(StoreQueryResponse(messages: messageSeq))
|
|
|
|
storeQuery = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
2024-04-25 13:09:52 +00:00
|
|
|
paginationForward: PagingDirection.FORWARD,
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
serverSwitch = newTestSwitch()
|
|
|
|
clientSwitch = newTestSwitch()
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
server = await newTestWakuStore(serverSwitch, handler = handler)
|
2023-12-19 14:38:43 +00:00
|
|
|
client = newTestWakuStoreClient(clientSwitch)
|
|
|
|
|
|
|
|
await allFutures(serverSwitch.start(), clientSwitch.start())
|
|
|
|
|
2024-05-16 16:04:04 +00:00
|
|
|
## The following sleep is aimed to prevent macos failures in CI
|
|
|
|
#[
|
|
|
|
2024-05-16T13:24:45.5106200Z INF 2024-05-16 13:24:45.509+00:00 Stopping AutonatService topics="libp2p autonatservice" tid=53712 file=service.nim:203
|
|
|
|
2024-05-16T13:24:45.5107960Z WRN 2024-05-16 13:24:45.509+00:00 service is already stopped topics="libp2p switch" tid=53712 file=switch.nim:86
|
|
|
|
2024-05-16T13:24:45.5109010Z . (1.68s)
|
|
|
|
2024-05-16T13:24:45.5109320Z Store Client (0.00s)
|
|
|
|
2024-05-16T13:24:45.5109870Z SIGSEGV: Illegal storage access. (Attempt to read from nil?)
|
|
|
|
2024-05-16T13:24:45.5111470Z stack trace: (most recent call last)
|
|
|
|
]#
|
|
|
|
await sleepAsync(500.millis)
|
2024-05-15 10:36:17 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
serverPeerInfo = serverSwitch.peerInfo.toRemotePeerInfo()
|
|
|
|
clientPeerInfo = clientSwitch.peerInfo.toRemotePeerInfo()
|
|
|
|
|
|
|
|
asyncTeardown:
|
|
|
|
await allFutures(serverSwitch.stop(), clientSwitch.stop())
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2024-04-25 13:09:52 +00:00
|
|
|
suite "StoreQueryRequest Creation and Execution":
|
2023-12-19 14:38:43 +00:00
|
|
|
asyncTest "Valid Queries":
|
|
|
|
# When a valid query is sent to the server
|
2024-04-25 13:09:52 +00:00
|
|
|
let queryResponse = await client.query(storeQuery, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is processed successfully
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
2024-04-25 13:09:52 +00:00
|
|
|
handlerFuture.read() == storeQuery
|
2023-12-19 14:38:43 +00:00
|
|
|
queryResponse.get().messages == messageSeq
|
|
|
|
|
|
|
|
asyncTest "Invalid Queries":
|
|
|
|
# TODO: IMPROVE: We can't test "actual" invalid queries because
|
|
|
|
# it directly depends on the handler implementation, to achieve
|
|
|
|
# proper coverage we'd need an example implementation.
|
|
|
|
|
|
|
|
# Given some invalid queries
|
2024-03-15 23:08:47 +00:00
|
|
|
let
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery1 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[],
|
2024-04-25 13:09:52 +00:00
|
|
|
paginationForward: PagingDirection.FORWARD,
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery2 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: PubsubTopic.none(),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
2024-04-25 13:09:52 +00:00
|
|
|
paginationForward: PagingDirection.FORWARD,
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery3 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
2024-04-25 13:09:52 +00:00
|
|
|
paginationLimit: some(uint64(0)),
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery4 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
2024-04-25 13:09:52 +00:00
|
|
|
paginationLimit: some(uint64(0)),
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery5 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
|
|
|
startTime: some(0.Timestamp),
|
2024-03-15 23:08:47 +00:00
|
|
|
endTime: some(0.Timestamp),
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
2024-04-25 13:09:52 +00:00
|
|
|
invalidQuery6 = StoreQueryRequest(
|
2023-12-19 14:38:43 +00:00
|
|
|
pubsubTopic: some(DefaultPubsubTopic),
|
|
|
|
contentTopics: @[DefaultContentTopic],
|
|
|
|
startTime: some(0.Timestamp),
|
2024-03-15 23:08:47 +00:00
|
|
|
endTime: some(-1.Timestamp),
|
2023-12-19 14:38:43 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
# When the query is sent to the server
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse1 = await client.query(invalidQuery1, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery1
|
|
|
|
queryResponse1.get().messages == messageSeq
|
|
|
|
|
|
|
|
# When the query is sent to the server
|
|
|
|
handlerFuture = newHistoryFuture()
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse2 = await client.query(invalidQuery2, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery2
|
|
|
|
queryResponse2.get().messages == messageSeq
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
# When the query is sent to the server
|
|
|
|
handlerFuture = newHistoryFuture()
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse3 = await client.query(invalidQuery3, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery3
|
|
|
|
queryResponse3.get().messages == messageSeq
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
# When the query is sent to the server
|
|
|
|
handlerFuture = newHistoryFuture()
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse4 = await client.query(invalidQuery4, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery4
|
|
|
|
queryResponse4.get().messages == messageSeq
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
# When the query is sent to the server
|
|
|
|
handlerFuture = newHistoryFuture()
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse5 = await client.query(invalidQuery5, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery5
|
|
|
|
queryResponse5.get().messages == messageSeq
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
# When the query is sent to the server
|
|
|
|
handlerFuture = newHistoryFuture()
|
2024-03-15 23:08:47 +00:00
|
|
|
let queryResponse6 = await client.query(invalidQuery6, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
assert await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
check:
|
|
|
|
handlerFuture.read() == invalidQuery6
|
|
|
|
queryResponse6.get().messages == messageSeq
|
|
|
|
|
2024-04-25 13:09:52 +00:00
|
|
|
suite "Verification of StoreQueryResponse Payload":
|
2023-12-19 14:38:43 +00:00
|
|
|
asyncTest "Positive Responses":
|
|
|
|
# When a valid query is sent to the server
|
2024-04-25 13:09:52 +00:00
|
|
|
let queryResponse = await client.query(storeQuery, peer = serverPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is processed successfully, and is of the expected type
|
|
|
|
check:
|
|
|
|
await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
2024-04-25 13:09:52 +00:00
|
|
|
type(queryResponse.get()) is StoreQueryResponse
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
asyncTest "Negative Responses - PeerDialFailure":
|
|
|
|
# Given a stopped peer
|
|
|
|
let
|
|
|
|
otherServerSwitch = newTestSwitch()
|
|
|
|
otherServerPeerInfo = otherServerSwitch.peerInfo.toRemotePeerInfo()
|
2024-03-15 23:08:47 +00:00
|
|
|
|
2023-12-19 14:38:43 +00:00
|
|
|
# When a query is sent to the stopped peer
|
2024-04-25 13:09:52 +00:00
|
|
|
let queryResponse = await client.query(storeQuery, peer = otherServerPeerInfo)
|
2023-12-19 14:38:43 +00:00
|
|
|
|
|
|
|
# Then the query is not processed
|
|
|
|
check:
|
|
|
|
not await handlerFuture.withTimeout(FUTURE_TIMEOUT)
|
|
|
|
queryResponse.isErr()
|
2024-04-25 13:09:52 +00:00
|
|
|
queryResponse.error.kind == ErrorCode.PEER_DIAL_FAILURE
|