2023-09-22 11:46:55 +00:00
|
|
|
{.used.}
|
|
|
|
|
|
|
|
import
|
|
|
|
std/sequtils,
|
|
|
|
stew/byteutils,
|
|
|
|
stew/shims/net,
|
|
|
|
testutils/unittests,
|
2024-03-15 23:08:47 +00:00
|
|
|
presto,
|
|
|
|
presto/client as presto_client,
|
2023-09-22 11:46:55 +00:00
|
|
|
libp2p/crypto/crypto
|
|
|
|
|
|
|
|
import
|
2024-07-05 22:03:38 +00:00
|
|
|
waku/[
|
|
|
|
waku_api/message_cache,
|
|
|
|
waku_core,
|
|
|
|
waku_node,
|
|
|
|
node/peer_manager,
|
|
|
|
waku_lightpush/common,
|
|
|
|
waku_api/rest/server,
|
|
|
|
waku_api/rest/client,
|
|
|
|
waku_api/rest/responses,
|
|
|
|
waku_api/rest/lightpush/types,
|
|
|
|
waku_api/rest/lightpush/handlers as lightpush_api,
|
|
|
|
waku_api/rest/lightpush/client as lightpush_api_client,
|
|
|
|
waku_relay,
|
2024-07-16 13:46:21 +00:00
|
|
|
common/rate_limit/setting,
|
2024-07-05 22:03:38 +00:00
|
|
|
],
|
2023-09-22 11:46:55 +00:00
|
|
|
../testlib/wakucore,
|
2024-04-15 13:28:35 +00:00
|
|
|
../testlib/wakunode,
|
|
|
|
../testlib/testutils
|
2023-09-22 11:46:55 +00:00
|
|
|
|
|
|
|
proc testWakuNode(): WakuNode =
|
|
|
|
let
|
|
|
|
privkey = generateSecp256k1Key()
|
2023-12-14 06:16:39 +00:00
|
|
|
bindIp = parseIpAddress("0.0.0.0")
|
|
|
|
extIp = parseIpAddress("127.0.0.1")
|
2023-09-22 11:46:55 +00:00
|
|
|
port = Port(0)
|
|
|
|
|
|
|
|
return newTestWakuNode(privkey, bindIp, port, some(extIp), some(port))
|
|
|
|
|
|
|
|
type RestLightPushTest = object
|
|
|
|
serviceNode: WakuNode
|
|
|
|
pushNode: WakuNode
|
|
|
|
consumerNode: WakuNode
|
2024-02-29 08:48:14 +00:00
|
|
|
restServer: WakuRestServerRef
|
2023-09-22 11:46:55 +00:00
|
|
|
client: RestClientRef
|
|
|
|
|
2024-04-15 13:28:35 +00:00
|
|
|
proc init(
|
|
|
|
T: type RestLightPushTest, rateLimit: RateLimitSetting = (0, 0.millis)
|
|
|
|
): Future[T] {.async.} =
|
2023-09-22 11:46:55 +00:00
|
|
|
var testSetup = RestLightPushTest()
|
|
|
|
testSetup.serviceNode = testWakuNode()
|
|
|
|
testSetup.pushNode = testWakuNode()
|
|
|
|
testSetup.consumerNode = testWakuNode()
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
await allFutures(
|
|
|
|
testSetup.serviceNode.start(),
|
|
|
|
testSetup.pushNode.start(),
|
|
|
|
testSetup.consumerNode.start(),
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
|
|
|
await testSetup.consumerNode.mountRelay()
|
|
|
|
await testSetup.serviceNode.mountRelay()
|
2024-04-15 13:28:35 +00:00
|
|
|
await testSetup.serviceNode.mountLightPush(rateLimit)
|
2023-09-22 11:46:55 +00:00
|
|
|
testSetup.pushNode.mountLightPushClient()
|
|
|
|
|
|
|
|
testSetup.serviceNode.peerManager.addServicePeer(
|
2024-03-15 23:08:47 +00:00
|
|
|
testSetup.consumerNode.peerInfo.toRemotePeerInfo(), WakuRelayCodec
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
await testSetup.serviceNode.connectToNodes(
|
|
|
|
@[testSetup.consumerNode.peerInfo.toRemotePeerInfo()]
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
|
|
|
testSetup.pushNode.peerManager.addServicePeer(
|
2024-03-15 23:08:47 +00:00
|
|
|
testSetup.serviceNode.peerInfo.toRemotePeerInfo(), WakuLightPushCodec
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
2024-06-12 13:07:33 +00:00
|
|
|
var restPort = Port(0)
|
2023-12-14 06:16:39 +00:00
|
|
|
let restAddress = parseIpAddress("127.0.0.1")
|
2024-02-29 08:48:14 +00:00
|
|
|
testSetup.restServer = WakuRestServerRef.init(restAddress, restPort).tryGet()
|
2024-06-12 13:07:33 +00:00
|
|
|
restPort = testSetup.restServer.httpServer.address.port
|
|
|
|
# update with bound port for client use
|
2023-09-22 11:46:55 +00:00
|
|
|
|
|
|
|
installLightPushRequestHandler(testSetup.restServer.router, testSetup.pushNode)
|
|
|
|
|
|
|
|
testSetup.restServer.start()
|
|
|
|
|
|
|
|
testSetup.client = newRestHttpClient(initTAddress(restAddress, restPort))
|
|
|
|
|
|
|
|
return testSetup
|
|
|
|
|
|
|
|
proc shutdown(self: RestLightPushTest) {.async.} =
|
|
|
|
await self.restServer.stop()
|
|
|
|
await self.restServer.closeWait()
|
|
|
|
await allFutures(self.serviceNode.stop(), self.pushNode.stop())
|
|
|
|
|
|
|
|
suite "Waku v2 Rest API - lightpush":
|
|
|
|
asyncTest "Push message request":
|
|
|
|
# Given
|
|
|
|
let restLightPushTest = await RestLightPushTest.init()
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
restLightPushTest.consumerNode.subscribe(
|
|
|
|
(kind: PubsubSub, topic: DefaultPubsubTopic)
|
|
|
|
)
|
|
|
|
restLightPushTest.serviceNode.subscribe(
|
|
|
|
(kind: PubsubSub, topic: DefaultPubsubTopic)
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
require:
|
|
|
|
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
|
|
|
|
|
|
|
|
# When
|
2024-03-15 23:08:47 +00:00
|
|
|
let message: RelayWakuMessage = fakeWakuMessage(
|
|
|
|
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
|
|
|
|
)
|
|
|
|
.toRelayWakuMessage()
|
2023-09-22 11:46:55 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
let requestBody =
|
|
|
|
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
|
2023-09-22 11:46:55 +00:00
|
|
|
let response = await restLightPushTest.client.sendPushRequest(requestBody)
|
|
|
|
|
|
|
|
echo "response", $response
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 200
|
|
|
|
$response.contentType == $MIMETYPE_TEXT
|
|
|
|
|
|
|
|
await restLightPushTest.shutdown()
|
|
|
|
|
|
|
|
asyncTest "Push message bad-request":
|
|
|
|
# Given
|
|
|
|
let restLightPushTest = await RestLightPushTest.init()
|
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
restLightPushTest.serviceNode.subscribe(
|
|
|
|
(kind: PubsubSub, topic: DefaultPubsubTopic)
|
|
|
|
)
|
2023-09-22 11:46:55 +00:00
|
|
|
require:
|
|
|
|
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
|
|
|
|
|
|
|
|
# When
|
2024-03-15 23:08:47 +00:00
|
|
|
let badMessage1: RelayWakuMessage = fakeWakuMessage(
|
|
|
|
contentTopic = DefaultContentTopic, payload = toBytes("")
|
|
|
|
)
|
|
|
|
.toRelayWakuMessage()
|
|
|
|
let badRequestBody1 =
|
|
|
|
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: badMessage1)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
let badMessage2: RelayWakuMessage =
|
|
|
|
fakeWakuMessage(contentTopic = "", payload = toBytes("Sthg")).toRelayWakuMessage()
|
|
|
|
let badRequestBody2 =
|
|
|
|
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: badMessage2)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
2024-03-15 23:08:47 +00:00
|
|
|
let badRequestBody3 =
|
|
|
|
PushRequest(pubsubTopic: none(PubsubTopic), message: badMessage2)
|
2023-09-22 11:46:55 +00:00
|
|
|
|
|
|
|
var response: RestResponse[string]
|
|
|
|
|
|
|
|
response = await restLightPushTest.client.sendPushRequest(badRequestBody1)
|
|
|
|
|
|
|
|
echo "response", $response
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 400
|
|
|
|
$response.contentType == $MIMETYPE_TEXT
|
|
|
|
response.data.startsWith("Invalid content body")
|
|
|
|
|
|
|
|
# when
|
|
|
|
response = await restLightPushTest.client.sendPushRequest(badRequestBody2)
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 400
|
|
|
|
$response.contentType == $MIMETYPE_TEXT
|
|
|
|
response.data.startsWith("Invalid content body")
|
|
|
|
|
|
|
|
# when
|
|
|
|
response = await restLightPushTest.client.sendPushRequest(badRequestBody3)
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 400
|
|
|
|
$response.contentType == $MIMETYPE_TEXT
|
|
|
|
response.data.startsWith("Invalid content body")
|
|
|
|
|
|
|
|
await restLightPushTest.shutdown()
|
|
|
|
|
2024-04-15 13:28:35 +00:00
|
|
|
# disabled due to this bug in nim-chronos https://github.com/status-im/nim-chronos/issues/500
|
|
|
|
xasyncTest "Request rate limit push message":
|
|
|
|
# Given
|
|
|
|
let budgetCap = 3
|
|
|
|
let tokenPeriod = 500.millis
|
|
|
|
let restLightPushTest = await RestLightPushTest.init((budgetCap, tokenPeriod))
|
|
|
|
|
|
|
|
restLightPushTest.consumerNode.subscribe(
|
|
|
|
(kind: PubsubSub, topic: DefaultPubsubTopic)
|
|
|
|
)
|
|
|
|
restLightPushTest.serviceNode.subscribe(
|
|
|
|
(kind: PubsubSub, topic: DefaultPubsubTopic)
|
|
|
|
)
|
|
|
|
require:
|
|
|
|
toSeq(restLightPushTest.serviceNode.wakuRelay.subscribedTopics).len == 1
|
|
|
|
|
|
|
|
# When
|
|
|
|
let pushProc = proc() {.async.} =
|
|
|
|
let message: RelayWakuMessage = fakeWakuMessage(
|
|
|
|
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
|
|
|
|
)
|
|
|
|
.toRelayWakuMessage()
|
|
|
|
|
|
|
|
let requestBody =
|
|
|
|
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
|
|
|
|
let response = await restLightPushTest.client.sendPushRequest(requestBody)
|
|
|
|
|
|
|
|
echo "response", $response
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 200
|
|
|
|
$response.contentType == $MIMETYPE_TEXT
|
|
|
|
|
|
|
|
let pushRejectedProc = proc() {.async.} =
|
|
|
|
let message: RelayWakuMessage = fakeWakuMessage(
|
|
|
|
contentTopic = DefaultContentTopic, payload = toBytes("TEST-1")
|
|
|
|
)
|
|
|
|
.toRelayWakuMessage()
|
|
|
|
|
|
|
|
let requestBody =
|
|
|
|
PushRequest(pubsubTopic: some(DefaultPubsubTopic), message: message)
|
|
|
|
let response = await restLightPushTest.client.sendPushRequest(requestBody)
|
|
|
|
|
|
|
|
echo "response", $response
|
|
|
|
|
|
|
|
# Then
|
|
|
|
check:
|
|
|
|
response.status == 429
|
|
|
|
|
|
|
|
await pushProc()
|
|
|
|
await pushProc()
|
|
|
|
await pushProc()
|
|
|
|
await pushRejectedProc()
|
|
|
|
|
|
|
|
await sleepAsync(tokenPeriod)
|
|
|
|
|
|
|
|
for runCnt in 0 ..< 3:
|
|
|
|
let startTime = Moment.now()
|
|
|
|
for sendCnt in 0 ..< budgetCap:
|
|
|
|
await pushProc()
|
|
|
|
|
|
|
|
let endTime = Moment.now()
|
|
|
|
let elapsed: Duration = (endTime - startTime)
|
|
|
|
await sleepAsync(tokenPeriod - elapsed)
|
|
|
|
|
|
|
|
await restLightPushTest.shutdown()
|
|
|
|
|
2023-10-02 13:38:40 +00:00
|
|
|
## TODO: Re-work this test when lightpush protocol change is done: https://github.com/waku-org/pm/issues/93
|
|
|
|
## This test is similar when no available peer exists for publish. Currently it is returning success,
|
|
|
|
## that makes this test not useful.
|
|
|
|
# asyncTest "Push message request service not available":
|
|
|
|
# # Given
|
|
|
|
# let restLightPushTest = await RestLightPushTest.init()
|
|
|
|
|
|
|
|
# # When
|
|
|
|
# let message : RelayWakuMessage = fakeWakuMessage(contentTopic = DefaultContentTopic,
|
|
|
|
# payload = toBytes("TEST-1")).toRelayWakuMessage()
|
|
|
|
|
|
|
|
# let requestBody = PushRequest(pubsubTopic: some("NoExistTopic"),
|
|
|
|
# message: message)
|
|
|
|
# let response = await restLightPushTest.client.sendPushRequest(requestBody)
|
|
|
|
|
|
|
|
# echo "response", $response
|
|
|
|
|
|
|
|
# # Then
|
|
|
|
# check:
|
|
|
|
# response.status == 503
|
|
|
|
# $response.contentType == $MIMETYPE_TEXT
|
|
|
|
# response.data == "Failed to request a message push: Can not publish to any peers"
|
|
|
|
|
|
|
|
# await restLightPushTest.shutdown()
|