mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-19 11:09:26 +00:00
* WIP logosdeliverynode app initial commit * WIP - extra cli option * WIP: messaging client REST endpoints * Add event poll for messaging rest with cache mechanism * Messaging rest tests * test: assert 404 via raw string client in messaging REST test presto's typed REST client raises RestDecodingError when it cannot decode a non-2xx text error body into the response type. Add a RestResponse[string] stub (messagingGetSendEventsByIdRawV1) and point the "already-polled id -> 404" assertion at it, matching the relay REST test pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * remove customized cli args as confutils has no support for it * Introduce --entry-layer and re-introduce --mode flags into cli args, applied new driver into LogosDelivery + tests * Add messaging REST client test * Add docker image build of logosdeliverynode for CI builds * Fix tests * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Refactor Messaging REST API to better match Messaging Send and Receive APIs * chore: migrate messaging REST API to Opt[T] Follow-up to the rebase onto master's repo-wide Option[T] -> Opt[T] change (#4035). Converts the code this branch adds to the new convention: - messaging/rest_api/types.nim: MessagingJsonEnvelope fields to Opt[T], Opt.some/Opt.none, and json_serialization/pkg/results instead of json_serialization/std/options. - tests: WakuNodeConf.clusterId is now Opt[uint16]; DTO fields are Opt. `Option[ContentBody]` in the handlers is presto's own API and stays as-is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
129 lines
4.6 KiB
Nim
129 lines
4.6 KiB
Nim
{.used.}
|
|
|
|
import std/[options, net]
|
|
import chronos, testutils/unittests, presto, presto/client as presto_client
|
|
import brokers/broker_context
|
|
import logos_delivery
|
|
import
|
|
logos_delivery/api/conf/logos_delivery_conf,
|
|
logos_delivery/messaging/rest_api/client as messaging_rest_client,
|
|
logos_delivery/waku/rest_api/endpoint/client
|
|
import tools/confutils/cli_args
|
|
import ../testlib/testasync
|
|
|
|
## Validates the layer-selection invariant of `LogosDelivery.new(WakuNodeConf)`:
|
|
## `messagingClient` (and `reliableChannelManager`) are instantiated only for the
|
|
## entry layers that call for them.
|
|
##
|
|
## kernel -> waku only
|
|
## messaging -> waku + messagingClient
|
|
## channels -> waku + messagingClient + reliableChannelManager
|
|
|
|
proc nodeConf(entryLayer: EntryLayer, rest = false): WakuNodeConf =
|
|
var conf = defaultWakuNodeConf().valueOr:
|
|
raiseAssert error
|
|
conf.entryLayer = entryLayer
|
|
conf.mode = LogosDeliveryMode.Core
|
|
conf.listenAddress = parseIpAddress("0.0.0.0")
|
|
conf.tcpPort = Port(0)
|
|
conf.discv5UdpPort = Port(0)
|
|
conf.clusterId = Opt.some(3'u16)
|
|
conf.numShardsInNetwork = 1
|
|
conf.rest = rest
|
|
conf.restAddress = parseIpAddress("127.0.0.1")
|
|
conf.restPort = 0'u16 # bind to an ephemeral port
|
|
return conf
|
|
|
|
proc restClientFor(node: LogosDelivery): RestClientRef =
|
|
let boundPort = node.waku.restServer.httpServer.address.port
|
|
newRestHttpClient(initTAddress(parseIpAddress("127.0.0.1"), boundPort))
|
|
|
|
suite "LogosDelivery - entry layer selection":
|
|
asyncTest "kernel: waku only, no messaging / channels":
|
|
var node: LogosDelivery
|
|
lockNewGlobalBrokerContext:
|
|
node = (await LogosDelivery.new(nodeConf(EntryLayer.kernel))).valueOr:
|
|
raiseAssert error
|
|
check:
|
|
not node.waku.isNil()
|
|
node.messagingClient.isNil()
|
|
node.reliableChannelManager.isNil()
|
|
node.ensureMessaging().isErr()
|
|
node.ensureChannels().isErr()
|
|
(await node.stop()).isOkOr:
|
|
raiseAssert "stop failed: " & error
|
|
|
|
asyncTest "messaging: waku + messagingClient, no channels":
|
|
var node: LogosDelivery
|
|
lockNewGlobalBrokerContext:
|
|
node = (await LogosDelivery.new(nodeConf(EntryLayer.messaging))).valueOr:
|
|
raiseAssert error
|
|
check:
|
|
not node.waku.isNil()
|
|
not node.messagingClient.isNil()
|
|
node.reliableChannelManager.isNil()
|
|
node.ensureMessaging().isOk()
|
|
node.ensureChannels().isErr()
|
|
(await node.stop()).isOkOr:
|
|
raiseAssert "stop failed: " & error
|
|
|
|
asyncTest "channels: full stack":
|
|
var node: LogosDelivery
|
|
lockNewGlobalBrokerContext:
|
|
node = (await LogosDelivery.new(nodeConf(EntryLayer.channels))).valueOr:
|
|
raiseAssert error
|
|
check:
|
|
not node.waku.isNil()
|
|
not node.messagingClient.isNil()
|
|
not node.reliableChannelManager.isNil()
|
|
node.ensureMessaging().isOk()
|
|
node.ensureChannels().isOk()
|
|
(await node.stop()).isOkOr:
|
|
raiseAssert "stop failed: " & error
|
|
|
|
asyncTest "messaging + rest: messaging REST endpoints are installed and working":
|
|
## entry-layer=messaging, mode=Core, rest=true -> `start` mounts the messaging
|
|
## REST endpoints; they respond over HTTP.
|
|
var node: LogosDelivery
|
|
lockNewGlobalBrokerContext:
|
|
node = (await LogosDelivery.new(nodeConf(EntryLayer.messaging, rest = true))).valueOr:
|
|
raiseAssert error
|
|
(await node.start()).isOkOr:
|
|
raiseAssert "start failed: " & error
|
|
|
|
check not node.messagingClient.isNil()
|
|
|
|
let client = restClientFor(node)
|
|
|
|
# A command endpoint and an observability endpoint both respond -> the
|
|
# handlers were installed onto the kernel router.
|
|
let subResp =
|
|
await client.messagingPostSubscriptionsV1(@["/test/1/entry-layer/proto"])
|
|
check subResp.status == 200
|
|
|
|
let sendEventsResp = await client.messagingGetSendEventsV1()
|
|
check sendEventsResp.status == 200
|
|
|
|
(await node.stop()).isOkOr:
|
|
raiseAssert "stop failed: " & error
|
|
|
|
asyncTest "kernel + rest: messaging REST endpoints are NOT installed":
|
|
## Gating check: a kernel-only node still starts a REST server, but the
|
|
## messaging endpoints must be absent (no messaging client to mount them).
|
|
var node: LogosDelivery
|
|
lockNewGlobalBrokerContext:
|
|
node = (await LogosDelivery.new(nodeConf(EntryLayer.kernel, rest = true))).valueOr:
|
|
raiseAssert error
|
|
(await node.start()).isOkOr:
|
|
raiseAssert "start failed: " & error
|
|
|
|
check node.messagingClient.isNil()
|
|
|
|
let client = restClientFor(node)
|
|
let subResp =
|
|
await client.messagingPostSubscriptionsV1(@["/test/1/entry-layer/proto"])
|
|
check subResp.status == 404 # route not mounted
|
|
|
|
(await node.stop()).isOkOr:
|
|
raiseAssert "stop failed: " & error
|