chore: RLN relay tests (#30)
* fix: add get_multiaddr_with_id step - temporarily use local docker images * fix: discard containers used for RLN registration * fix: switch to use cluster ID 1 for RLN * test: publish at slow and spam rate * fix: shorten test data set * fix: move RLN related code into separate class * fix: use send only publish function - add spam and alternate rate tests * fix: use math.trunc instead of rounding * fix: first message without delay * fix: add one more second to messages with delay * fix: add methods to setup non default RLN nodes * fix: rewrite tests using steps rather than fixtures - prepare for non default settings for RLN * test: random epoch with valid_payloads_at_slow_rate * test: random user message limit with valid payloads * fix: skip test "random user message limit with valid payloads" * fix: mark flaky "at variable_rate with valid payloads" * fix: rename tests for easier debugging * fix: mark valid_payloads_dynamic_at_slow_rate to skip * fix: forgot to add actual file * test: valid payloads dynamic(on chain) at spam rate - extend timeout for ensure_ready() to 600s - add ensure_healthy() for future use - add text content based rest call - remove NODE1, NODE2 imports * fix: revert env_vars to source images from Harbor * fix: reuse setup first and second rln relay node for setup_main_rln_relay_nodes * fix: reuse register_rln_single_node for register_main_rln_relay_nodes * fix: start using src.steps.common - removed RLN test class inheritance from StepsRelay * fix: test using whole data set at test payloads_at_slow_rate * fix: switch to send msg and check for slow rate tests * fix: add comment for skip check at first message * fix: refactor payloads_at_variable_rate to use only one payload pattern * fix: remove the plural from payloads_at_variable_rate * fix: multiple class inheritance for TestRelayRLN * test: node1 with rln node2 without rln at spam rate * test: mixed epoch at slow rate * test: add lightpush methods * test: send valid payloads lightpush at spam rate * fix: node1 to act as light push receiving node - add setup lightpush node to spin off node2 with lightpush support * fix: use NODE1 NODE2 instead of DEFAULT_NWAKU * fix: no lightpush param required for plain RLN relay * fix: comment for lightpush * fix: comment for lightpush - wait for implementation * fix: comment on chain tests * fix: add lightpush case to publish_message * fix: remove check_light_pushed_message_reaches_receiving_peer from StepsRLN * fix: change comment for mixed_epoch_at_slow_rate * test: happy and common case with 5 nodes * fix: add all required fixtures explicitly * fix: add timeout param to ensure_ready * fix: skip RLN tests for go-waku * fix: reformated with pre-commit * fix: uncomment skip for debugging * fix: put the skip back * fix: change comment for on chain tests * fix: run RLN tests in serial - add grouping of tests to runner - use smaller dataset for spam rate tests * test: Nim to Nim workflow * test: check also additional nodes for go-waku * test: all nodes are nwaku * fix: string quotes * fix: remove additional nodes * fix: re-arrange skip conditions * test: RLN only * fix: change default additional nodes to nwaku only * fix: change additional nodes rather at top level workflow * fix: enable all tests * test: problems with current workdir * test: rln only * test: correct typo * test: re-enable all tests - remove current dir debug * fix: nwaku additional nodes for nim to nim worklfow * fix: re-able discord notification - delete test workflow * fix: add get_multiaddr_with_id step - temporarily use local docker images * fix: discard containers used for RLN registration * fix: switch to use cluster ID 1 for RLN * test: publish at slow and spam rate * fix: shorten test data set * fix: rebase onto master * fix: use send only publish function - add spam and alternate rate tests * fix: use math.trunc instead of rounding * fix: first message without delay * fix: add one more second to messages with delay * fix: add methods to setup non default RLN nodes * fix: rewrite tests using steps rather than fixtures - prepare for non default settings for RLN * test: random epoch with valid_payloads_at_slow_rate * test: random user message limit with valid payloads * fix: skip test "random user message limit with valid payloads" * fix: mark flaky "at variable_rate with valid payloads" * fix: rename tests for easier debugging * fix: mark valid_payloads_dynamic_at_slow_rate to skip * fix: forgot to add actual file * test: valid payloads dynamic(on chain) at spam rate - extend timeout for ensure_ready() to 600s - add ensure_healthy() for future use - add text content based rest call - remove NODE1, NODE2 imports * fix: revert env_vars to source images from Harbor * fix: reuse setup first and second rln relay node for setup_main_rln_relay_nodes * fix: reuse register_rln_single_node for register_main_rln_relay_nodes * fix: start using src.steps.common - removed RLN test class inheritance from StepsRelay * fix: test using whole data set at test payloads_at_slow_rate * fix: switch to send msg and check for slow rate tests * fix: add comment for skip check at first message * fix: refactor payloads_at_variable_rate to use only one payload pattern * fix: remove the plural from payloads_at_variable_rate * fix: multiple class inheritance for TestRelayRLN * test: node1 with rln node2 without rln at spam rate * test: mixed epoch at slow rate * test: add lightpush methods * test: send valid payloads lightpush at spam rate * fix: node1 to act as light push receiving node - add setup lightpush node to spin off node2 with lightpush support * fix: use NODE1 NODE2 instead of DEFAULT_NWAKU * fix: no lightpush param required for plain RLN relay * fix: comment for lightpush * fix: comment for lightpush - wait for implementation * fix: comment on chain tests * fix: add lightpush case to publish_message * fix: remove check_light_pushed_message_reaches_receiving_peer from StepsRLN * fix: change comment for mixed_epoch_at_slow_rate * test: happy and common case with 5 nodes * fix: add all required fixtures explicitly * fix: add timeout param to ensure_ready * fix: skip RLN tests for go-waku * fix: uncomment skip for debugging * fix: put the skip back * fix: change comment for on chain tests * fix: run RLN tests in serial - add grouping of tests to runner - use smaller dataset for spam rate tests * test: Nim to Nim workflow * test: check also additional nodes for go-waku * test: all nodes are nwaku * fix: string quotes * fix: remove additional nodes * fix: re-arrange skip conditions * test: RLN only * fix: change default additional nodes to nwaku only * fix: change additional nodes rather at top level workflow * fix: enable all tests * test: problems with current workdir * test: rln only * test: correct typo * test: re-enable all tests - remove current dir debug * fix: nwaku additional nodes for nim to nim worklfow * fix: re-able discord notification - delete test workflow * test: re-test again after rebase * fix: wait longer for credential store * test: try again with Discord report off * fix: enable Discord - delete test workflow
This commit is contained in:
parent
edb1f59448
commit
151233fddb
|
@ -16,4 +16,5 @@ jobs:
|
|||
with:
|
||||
node1: "harbor.status.im/wakuorg/nwaku:latest"
|
||||
node2: "harbor.status.im/wakuorg/nwaku:latest"
|
||||
additional_nodes: "harbor.status.im/wakuorg/nwaku:latest,harbor.status.im/wakuorg/nwaku:latest,harbor.status.im/wakuorg/nwaku:latest"
|
||||
caller: "nim"
|
||||
|
|
|
@ -49,7 +49,8 @@ jobs:
|
|||
- run: pip install -r requirements.txt
|
||||
|
||||
- name: Run tests
|
||||
run: pytest -n 4 --reruns 2 --alluredir=allure-results
|
||||
run: |
|
||||
pytest -n 4 --dist loadgroup --reruns 2 --alluredir=allure-results
|
||||
|
||||
- name: Get allure history
|
||||
if: always()
|
||||
|
|
|
@ -15,10 +15,19 @@ class REST(BaseClient):
|
|||
headers = {"Content-Type": "application/json"}
|
||||
return self.make_request(method, url, headers=headers, data=payload)
|
||||
|
||||
def rest_call_text(self, method, endpoint, payload=None):
|
||||
url = f"http://127.0.0.1:{self._rest_port}/{endpoint}"
|
||||
headers = {"accept": "text/plain"}
|
||||
return self.make_request(method, url, headers=headers, data=payload)
|
||||
|
||||
def info(self):
|
||||
info_response = self.rest_call("get", "debug/v1/info")
|
||||
return info_response.json()
|
||||
|
||||
def health(self):
|
||||
health_response = self.rest_call_text("get", "health")
|
||||
return health_response.text()
|
||||
|
||||
def get_peers(self):
|
||||
get_peers_response = self.rest_call("get", "admin/v1/peers")
|
||||
return get_peers_response.json()
|
||||
|
|
|
@ -31,7 +31,7 @@ def sanitize_docker_flags(input_flags):
|
|||
return output_flags
|
||||
|
||||
|
||||
@retry(stop=stop_after_delay(120), wait=wait_fixed(0.5), reraise=True)
|
||||
@retry(stop=stop_after_delay(180), wait=wait_fixed(0.5), reraise=True)
|
||||
def rln_credential_store_ready(creds_file_path):
|
||||
if os.path.exists(creds_file_path):
|
||||
return True
|
||||
|
@ -48,7 +48,7 @@ class WakuNode:
|
|||
logger.debug(f"WakuNode instance initialized with log path {self._log_path}")
|
||||
|
||||
@retry(stop=stop_after_delay(5), wait=wait_fixed(0.1), reraise=True)
|
||||
def start(self, **kwargs):
|
||||
def start(self, wait_for_node_sec=10, **kwargs):
|
||||
logger.debug("Starting Node...")
|
||||
self._docker_manager.create_network()
|
||||
self._ext_ip = self._docker_manager.generate_random_ext_ip()
|
||||
|
@ -113,6 +113,8 @@ class WakuNode:
|
|||
else:
|
||||
logger.info(f"RLN credentials not set or credential store not available, starting without RLN")
|
||||
|
||||
logger.debug(f"Using volumes {self._volumes}")
|
||||
|
||||
self._container = self._docker_manager.start_container(
|
||||
self._docker_manager.image, self._ports, default_args, self._log_path, self._ext_ip, self._volumes
|
||||
)
|
||||
|
@ -121,7 +123,7 @@ class WakuNode:
|
|||
DS.waku_nodes.append(self)
|
||||
delay(1) # if we fire requests to soon after starting the node will sometimes fail to start correctly
|
||||
try:
|
||||
self.ensure_ready()
|
||||
self.ensure_ready(timeout_duration=wait_for_node_sec)
|
||||
except Exception as ex:
|
||||
logger.error(f"REST service did not become ready in time: {ex}")
|
||||
raise
|
||||
|
@ -184,10 +186,18 @@ class WakuNode:
|
|||
logger.debug(f"Unpause container with id {self._container.short_id}")
|
||||
self._container.unpause()
|
||||
|
||||
@retry(stop=stop_after_delay(10), wait=wait_fixed(0.1), reraise=True)
|
||||
def ensure_ready(self):
|
||||
self.info_response = self.info()
|
||||
logger.info("REST service is ready !!")
|
||||
def ensure_ready(self, timeout_duration=10):
|
||||
@retry(stop=stop_after_delay(timeout_duration), wait=wait_fixed(0.1), reraise=True)
|
||||
def check_ready(node=self):
|
||||
node.info_response = node.info()
|
||||
logger.info("REST service is ready !!")
|
||||
|
||||
check_ready()
|
||||
|
||||
@retry(stop=stop_after_delay(10), wait=wait_fixed(1), reraise=True)
|
||||
def ensure_healthy(self):
|
||||
self.health_response = self.health()
|
||||
logger.info("Node is healthy !!")
|
||||
|
||||
def get_enr_uri(self):
|
||||
try:
|
||||
|
@ -208,6 +218,9 @@ class WakuNode:
|
|||
def info(self):
|
||||
return self._api.info()
|
||||
|
||||
def health(self):
|
||||
return self._api.health()
|
||||
|
||||
def get_peers(self):
|
||||
return self._api.get_peers()
|
||||
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
import inspect
|
||||
import os
|
||||
from src.libs.custom_logger import get_custom_logger
|
||||
from time import time
|
||||
import pytest
|
||||
import allure
|
||||
from src.libs.common import to_base64, delay, gen_step_id
|
||||
from src.libs.common import to_base64, delay
|
||||
from src.node.waku_message import WakuMessage
|
||||
from src.env_vars import (
|
||||
NODE_1,
|
||||
NODE_2,
|
||||
ADDITIONAL_NODES,
|
||||
NODEKEY,
|
||||
DEFAULT_NWAKU,
|
||||
RLN_CREDENTIALS,
|
||||
)
|
||||
from src.node.waku_node import WakuNode, rln_credential_store_ready
|
||||
from src.node.waku_node import WakuNode
|
||||
from tenacity import retry, stop_after_delay, wait_fixed
|
||||
from src.steps.common import StepsCommon
|
||||
from src.test_data import VALID_PUBSUB_TOPICS
|
||||
|
@ -45,28 +42,6 @@ class StepsRelay(StepsCommon):
|
|||
self.add_node_peer(self.node2, [self.multiaddr_with_id])
|
||||
self.main_nodes.extend([self.node1, self.node2])
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def register_main_rln_relay_nodes(self, request):
|
||||
logger.debug(f"Registering RLN credentials: {inspect.currentframe().f_code.co_name}")
|
||||
self.node1 = WakuNode(DEFAULT_NWAKU, f"node1_{request.cls.test_id}")
|
||||
self.node1.register_rln(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="1")
|
||||
self.node2 = WakuNode(DEFAULT_NWAKU, f"node2_{request.cls.test_id}")
|
||||
self.node2.register_rln(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="2")
|
||||
self.main_nodes.extend([self.node1, self.node2])
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def setup_main_rln_relay_nodes(self, request):
|
||||
logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
|
||||
self.node1 = WakuNode(DEFAULT_NWAKU, f"node1_{request.cls.test_id}")
|
||||
self.node1.start(relay="true", nodekey=NODEKEY, rln_creds_source=RLN_CREDENTIALS, rln_creds_id="1", rln_relay_membership_index="1")
|
||||
self.enr_uri = self.node1.get_enr_uri()
|
||||
self.node2 = WakuNode(DEFAULT_NWAKU, f"node2_{request.cls.test_id}")
|
||||
self.node2.start(
|
||||
relay="true", discv5_bootstrap_node=self.enr_uri, rln_creds_source=RLN_CREDENTIALS, rln_creds_id="2", rln_relay_membership_index="1"
|
||||
)
|
||||
self.add_node_peer(self.node2, [self.multiaddr_with_id])
|
||||
self.main_nodes.extend([self.node1, self.node2])
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def setup_optional_relay_nodes(self, request):
|
||||
logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
|
||||
|
@ -156,19 +131,3 @@ class StepsRelay(StepsCommon):
|
|||
def subscribe_and_publish_with_retry(self, node_list, pubsub_topic_list):
|
||||
self.ensure_relay_subscriptions_on_nodes(node_list, pubsub_topic_list)
|
||||
self.check_published_message_reaches_relay_peer()
|
||||
|
||||
@allure.step
|
||||
def register_rln_single_node(self, **kwargs):
|
||||
logger.debug("Registering RLN credentials for single node")
|
||||
self.node1 = WakuNode(DEFAULT_NWAKU, f"node1_{gen_step_id()}")
|
||||
self.node1.register_rln(rln_creds_source=kwargs["rln_creds_source"], rln_creds_id=kwargs["rln_creds_id"])
|
||||
|
||||
@allure.step
|
||||
def check_rln_registration(self, key_id):
|
||||
current_working_directory = os.getcwd()
|
||||
creds_file_path = f"{current_working_directory}/keystore_{key_id}/keystore.json"
|
||||
try:
|
||||
rln_credential_store_ready(creds_file_path)
|
||||
except Exception as ex:
|
||||
logger.error(f"Credentials at {creds_file_path} not available: {ex}")
|
||||
raise
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
import os
|
||||
import inspect
|
||||
import pytest
|
||||
import allure
|
||||
|
||||
from src.node.waku_message import WakuMessage
|
||||
from src.steps.common import StepsCommon
|
||||
from src.test_data import PUBSUB_TOPICS_RLN
|
||||
from src.env_vars import DEFAULT_NWAKU, RLN_CREDENTIALS, NODEKEY, NODE_1, NODE_2, ADDITIONAL_NODES
|
||||
from src.libs.common import gen_step_id, delay
|
||||
from src.libs.custom_logger import get_custom_logger
|
||||
from src.node.waku_node import WakuNode, rln_credential_store_ready
|
||||
|
||||
logger = get_custom_logger(__name__)
|
||||
|
||||
|
||||
class StepsRLN(StepsCommon):
|
||||
test_pubsub_topic = PUBSUB_TOPICS_RLN[0]
|
||||
test_content_topic = "/test/1/waku-rln-relay/proto"
|
||||
test_payload = "RLN relay works!!"
|
||||
|
||||
main_nodes = []
|
||||
optional_nodes = []
|
||||
multiaddr_list = []
|
||||
lightpush_nodes = []
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def register_main_rln_relay_nodes(self, request):
|
||||
logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="1")
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="2")
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def register_optional_rln_relay_nodes(self, request):
|
||||
logger.debug(f"Running fixture setup: {inspect.currentframe().f_code.co_name}")
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="3")
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="4")
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id="5")
|
||||
|
||||
@allure.step
|
||||
def setup_main_rln_relay_nodes(self, **kwargs):
|
||||
self.setup_first_rln_relay_node(**kwargs)
|
||||
self.setup_second_rln_relay_node(**kwargs)
|
||||
|
||||
@allure.step
|
||||
def setup_first_rln_relay_node(self, **kwargs):
|
||||
self.node1 = WakuNode(NODE_1, f"node1_{self.test_id}")
|
||||
self.node1.start(
|
||||
relay="true",
|
||||
nodekey=NODEKEY,
|
||||
rln_creds_source=RLN_CREDENTIALS,
|
||||
rln_creds_id="1",
|
||||
rln_relay_membership_index="1",
|
||||
**kwargs,
|
||||
)
|
||||
self.enr_uri = self.node1.get_enr_uri()
|
||||
self.multiaddr_with_id = self.node1.get_multiaddr_with_id()
|
||||
self.main_nodes.extend([self.node1])
|
||||
|
||||
self.multiaddr_list.extend([self.node1.get_multiaddr_with_id()])
|
||||
|
||||
@allure.step
|
||||
def setup_second_rln_relay_node(self, **kwargs):
|
||||
self.node2 = WakuNode(NODE_2, f"node2_{self.test_id}")
|
||||
self.node2.start(
|
||||
relay="true",
|
||||
discv5_bootstrap_node=self.enr_uri,
|
||||
rln_creds_source=RLN_CREDENTIALS,
|
||||
rln_creds_id="2",
|
||||
rln_relay_membership_index="1",
|
||||
**kwargs,
|
||||
)
|
||||
self.add_node_peer(self.node2, [self.multiaddr_with_id])
|
||||
self.main_nodes.extend([self.node2])
|
||||
|
||||
@allure.step
|
||||
def setup_optional_rln_relay_nodes(self, **kwargs):
|
||||
if ADDITIONAL_NODES:
|
||||
nodes = [node.strip() for node in ADDITIONAL_NODES.split(",")]
|
||||
else:
|
||||
pytest.skip("ADDITIONAL_NODES is empty, cannot run test")
|
||||
if len(nodes) > 3:
|
||||
logger.debug("More than 3 nodes are not supported for RLN tests, using first 3")
|
||||
nodes = nodes[:3]
|
||||
for index, node in enumerate(nodes):
|
||||
node = WakuNode(node, f"node{index + 3}_{self.test_id}")
|
||||
node.start(
|
||||
relay="true",
|
||||
discv5_bootstrap_node=self.enr_uri,
|
||||
rln_creds_source=RLN_CREDENTIALS,
|
||||
rln_creds_id=f"{index + 3}",
|
||||
rln_relay_membership_index="1",
|
||||
**kwargs,
|
||||
)
|
||||
self.add_node_peer(node, [self.multiaddr_with_id])
|
||||
self.optional_nodes.append(node)
|
||||
|
||||
@allure.step
|
||||
def setup_second_lightpush_node(self, relay="false", **kwargs):
|
||||
self.light_push_node2 = WakuNode(NODE_2, f"lightpush_node2_{self.test_id}")
|
||||
self.light_push_node2.start(relay=relay, discv5_bootstrap_node=self.enr_uri, lightpush="true", lightpushnode=self.multiaddr_list[0], **kwargs)
|
||||
if relay == "true":
|
||||
self.main_nodes.extend([self.light_push_node2])
|
||||
self.lightpush_nodes.extend([self.light_push_node2])
|
||||
self.add_node_peer(self.light_push_node2, self.multiaddr_list)
|
||||
|
||||
@allure.step
|
||||
def setup_first_relay_node(self, **kwargs):
|
||||
self.node1 = WakuNode(NODE_1, f"node1_{self.test_id}")
|
||||
self.node1.start(relay="true", nodekey=NODEKEY, **kwargs)
|
||||
self.enr_uri = self.node1.get_enr_uri()
|
||||
self.multiaddr_with_id = self.node1.get_multiaddr_with_id()
|
||||
self.main_nodes.extend([self.node1])
|
||||
|
||||
@allure.step
|
||||
def setup_second_relay_node(self, **kwargs):
|
||||
self.node2 = WakuNode(NODE_2, f"node2_{self.test_id}")
|
||||
self.node2.start(
|
||||
relay="true",
|
||||
discv5_bootstrap_node=self.enr_uri,
|
||||
**kwargs,
|
||||
)
|
||||
self.add_node_peer(self.node2, [self.multiaddr_with_id])
|
||||
self.main_nodes.extend([self.node2])
|
||||
|
||||
@allure.step
|
||||
def register_rln_single_node(self, **kwargs):
|
||||
logger.debug("Registering RLN credentials for single node")
|
||||
self.node1 = WakuNode(DEFAULT_NWAKU, f"node1_{gen_step_id()}")
|
||||
self.node1.register_rln(rln_creds_source=kwargs["rln_creds_source"], rln_creds_id=kwargs["rln_creds_id"])
|
||||
|
||||
@allure.step
|
||||
def check_rln_registration(self, key_id):
|
||||
current_working_directory = os.getcwd()
|
||||
creds_file_path = f"{current_working_directory}/keystore_{key_id}/keystore.json"
|
||||
try:
|
||||
rln_credential_store_ready(creds_file_path)
|
||||
except Exception as ex:
|
||||
logger.error(f"Credentials at {creds_file_path} not available: {ex}")
|
||||
raise
|
||||
|
||||
@allure.step
|
||||
def publish_message(self, message=None, pubsub_topic=None, sender=None, use_lightpush=False):
|
||||
if message is None:
|
||||
message = self.create_message()
|
||||
if pubsub_topic is None:
|
||||
pubsub_topic = self.test_pubsub_topic
|
||||
if not sender:
|
||||
sender = self.node1
|
||||
|
||||
if use_lightpush:
|
||||
payload = self.create_payload(pubsub_topic, message)
|
||||
sender.send_light_push_message(payload)
|
||||
else:
|
||||
sender.send_relay_message(message, pubsub_topic)
|
||||
|
||||
@allure.step
|
||||
def ensure_relay_subscriptions_on_nodes(self, node_list, pubsub_topic_list):
|
||||
for node in node_list:
|
||||
node.set_relay_subscriptions(pubsub_topic_list)
|
||||
|
||||
@allure.step
|
||||
def subscribe_main_relay_nodes(self):
|
||||
self.ensure_relay_subscriptions_on_nodes(self.main_nodes, [self.test_pubsub_topic])
|
||||
|
||||
@allure.step
|
||||
def subscribe_optional_relay_nodes(self):
|
||||
self.ensure_relay_subscriptions_on_nodes(self.optional_nodes, [self.test_pubsub_topic])
|
||||
|
||||
@allure.step
|
||||
def create_payload(self, pubsub_topic=None, message=None, **kwargs):
|
||||
if message is None:
|
||||
message = self.create_message()
|
||||
if pubsub_topic is None:
|
||||
pubsub_topic = self.test_pubsub_topic
|
||||
payload = {"pubsubTopic": pubsub_topic, "message": message}
|
||||
payload.update(kwargs)
|
||||
return payload
|
|
@ -148,3 +148,5 @@ SAMPLE_TIMESTAMPS = [
|
|||
{"description": "ISO 8601 timestamp", "value": "2023-12-26T10:58:51", "valid_for": []},
|
||||
{"description": "Missing", "value": None, "valid_for": ["gowaku"]},
|
||||
]
|
||||
|
||||
PUBSUB_TOPICS_RLN = ["/waku/2/rs/1/0"]
|
||||
|
|
|
@ -1,24 +1,237 @@
|
|||
import os
|
||||
import math
|
||||
import random
|
||||
from time import time
|
||||
import pytest
|
||||
|
||||
from src.env_vars import RLN_CREDENTIALS
|
||||
from src.env_vars import NODE_1, NODE_2, ADDITIONAL_NODES
|
||||
from src.libs.common import delay, to_base64
|
||||
from src.libs.custom_logger import get_custom_logger
|
||||
from src.steps.relay import StepsRelay
|
||||
from src.steps.rln import StepsRLN
|
||||
from src.test_data import SAMPLE_INPUTS
|
||||
|
||||
logger = get_custom_logger(__name__)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures()
|
||||
class TestRelayRLN(StepsRelay):
|
||||
def test_register_rln(self):
|
||||
logger.debug("Running register RLN test for main relay nodes")
|
||||
key_stores_found = 0
|
||||
@pytest.mark.xdist_group(name="RLN serial tests")
|
||||
@pytest.mark.usefixtures("register_main_rln_relay_nodes")
|
||||
@pytest.mark.skipif("go-waku" in (NODE_1 + NODE_2), reason="Test works only with nwaku")
|
||||
class TestRelayRLN(StepsRLN, StepsRelay):
|
||||
def test_valid_payloads_at_slow_rate(self):
|
||||
self.setup_main_rln_relay_nodes()
|
||||
self.subscribe_main_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.check_published_message_reaches_relay_peer(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
delay(1)
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
if RLN_CREDENTIALS is None:
|
||||
pytest.skip("RLN_CREDENTIALS not set, skipping test")
|
||||
def test_valid_payloads_at_spam_rate(self):
|
||||
self.setup_main_rln_relay_nodes()
|
||||
self.subscribe_main_relay_nodes()
|
||||
previous = math.trunc(time())
|
||||
for i, payload in enumerate(SAMPLE_INPUTS[:5]):
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
now = math.trunc(time())
|
||||
self.publish_message(message)
|
||||
# Skip for the first message (i > 0) - previous could be too apart from now
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
||||
for k in range(1, 6):
|
||||
self.register_rln_single_node(rln_creds_source=RLN_CREDENTIALS, rln_creds_id=f"{k}")
|
||||
self.check_rln_registration(k)
|
||||
key_stores_found += 1
|
||||
assert key_stores_found == 5, f"Invalid number of RLN keystores found, expected 5 found {key_stores_found}"
|
||||
def test_valid_payload_at_variable_rate(self):
|
||||
self.setup_main_rln_relay_nodes()
|
||||
self.subscribe_main_relay_nodes()
|
||||
payload_desc = SAMPLE_INPUTS[0]["description"]
|
||||
payload = to_base64(SAMPLE_INPUTS[0]["value"])
|
||||
previous = math.trunc(time())
|
||||
for i in range(0, 10):
|
||||
logger.debug(f"Running test with payload {payload_desc}")
|
||||
message = self.create_message(payload=payload)
|
||||
try:
|
||||
if i % 2 == 1: # every odd iteration is sent slowly
|
||||
delay(1 + 1)
|
||||
now = math.trunc(time())
|
||||
logger.debug(f"Message sent at timestamp {now}")
|
||||
self.publish_message(message)
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
||||
def test_valid_payloads_random_epoch_at_slow_rate(self):
|
||||
epoch_sec = random.randint(2, 5)
|
||||
self.setup_main_rln_relay_nodes(rln_relay_epoch_sec=epoch_sec)
|
||||
self.subscribe_main_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS[:5]:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.check_published_message_reaches_relay_peer(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
delay(epoch_sec)
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
@pytest.mark.skip(reason="waiting for RLN v2 implementation")
|
||||
def test_valid_payloads_random_user_message_limit(self):
|
||||
user_message_limit = random.randint(2, 4)
|
||||
self.setup_main_rln_relay_nodes(rln_relay_user_message_limit=user_message_limit)
|
||||
self.subscribe_main_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS[:user_message_limit]:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.publish_message(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
@pytest.mark.skip(reason="exceeding timeout, waiting for https://github.com/waku-org/nwaku/pull/2612 to be part of the release")
|
||||
@pytest.mark.timeout(600)
|
||||
def test_valid_payloads_dynamic_at_slow_rate(self):
|
||||
self.setup_main_rln_relay_nodes(rln_relay_dynamic="true", wait_for_node_sec=600)
|
||||
self.subscribe_main_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.check_published_message_reaches_relay_peer(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
delay(1)
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
@pytest.mark.skip(reason="exceeding timeout, waiting for https://github.com/waku-org/nwaku/pull/2612 to be part of the release")
|
||||
@pytest.mark.timeout(600)
|
||||
def test_valid_payloads_dynamic_at_spam_rate(self):
|
||||
self.setup_main_rln_relay_nodes(rln_relay_dynamic="true", wait_for_node_sec=600)
|
||||
self.subscribe_main_relay_nodes()
|
||||
previous = math.trunc(time())
|
||||
for i, payload in enumerate(SAMPLE_INPUTS[:5]):
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
now = math.trunc(time())
|
||||
self.publish_message(message)
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
||||
def test_valid_payloads_n1_with_rln_n2_without_rln_at_spam_rate(self):
|
||||
self.setup_first_rln_relay_node()
|
||||
self.setup_second_relay_node()
|
||||
self.subscribe_main_relay_nodes()
|
||||
previous = math.trunc(time())
|
||||
for i, payload in enumerate(SAMPLE_INPUTS[:5]):
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
now = math.trunc(time())
|
||||
self.publish_message(message)
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
||||
@pytest.mark.skip(reason="Epoch settings aren't compatible across nodes")
|
||||
def test_valid_payloads_mixed_epoch_at_slow_rate(self):
|
||||
n1_epoch_sec = 5
|
||||
n2_epoch_sec = 1
|
||||
self.setup_first_rln_relay_node(rln_relay_epoch_sec=n1_epoch_sec)
|
||||
self.setup_second_rln_relay_node(rln_relay_epoch_sec=n2_epoch_sec)
|
||||
self.subscribe_main_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS[:5]:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.check_published_message_reaches_relay_peer(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
delay(n1_epoch_sec)
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
@pytest.mark.skip(reason="waiting for NWAKU lightpush + RLN node implementation")
|
||||
def test_valid_payloads_lightpush_at_spam_rate(self):
|
||||
self.setup_first_rln_relay_node(lightpush="true")
|
||||
self.setup_second_lightpush_node()
|
||||
self.subscribe_main_relay_nodes()
|
||||
previous = math.trunc(time())
|
||||
for i, payload in enumerate(SAMPLE_INPUTS[:5]):
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
now = math.trunc(time())
|
||||
self.publish_message(message=message, sender=self.light_push_node2, use_lightpush=True)
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
||||
@pytest.mark.skipif("go-waku" in ADDITIONAL_NODES, reason="Test works only with nwaku")
|
||||
@pytest.mark.usefixtures("register_main_rln_relay_nodes", "register_optional_rln_relay_nodes")
|
||||
def test_valid_payloads_with_optional_nodes_at_slow_rate(self):
|
||||
self.setup_main_rln_relay_nodes()
|
||||
self.setup_optional_rln_relay_nodes()
|
||||
self.subscribe_main_relay_nodes()
|
||||
self.subscribe_optional_relay_nodes()
|
||||
failed_payloads = []
|
||||
for payload in SAMPLE_INPUTS:
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
self.check_published_message_reaches_relay_peer(message)
|
||||
except Exception as e:
|
||||
logger.error(f'Payload {payload["description"]} failed: {str(e)}')
|
||||
failed_payloads.append(payload["description"])
|
||||
delay(1)
|
||||
assert not failed_payloads, f"Payloads failed: {failed_payloads}"
|
||||
|
||||
@pytest.mark.skipif("go-waku" in ADDITIONAL_NODES, reason="Test works only with nwaku")
|
||||
@pytest.mark.usefixtures("register_main_rln_relay_nodes", "register_optional_rln_relay_nodes")
|
||||
def test_valid_payloads_with_optional_nodes_at_spam_rate(self):
|
||||
self.setup_main_rln_relay_nodes()
|
||||
self.setup_optional_rln_relay_nodes()
|
||||
self.subscribe_main_relay_nodes()
|
||||
self.subscribe_optional_relay_nodes()
|
||||
previous = math.trunc(time())
|
||||
for i, payload in enumerate(SAMPLE_INPUTS[:5]):
|
||||
logger.debug(f'Running test with payload {payload["description"]}')
|
||||
message = self.create_message(payload=to_base64(payload["value"]))
|
||||
try:
|
||||
now = math.trunc(time())
|
||||
self.publish_message(message)
|
||||
if i > 0 and (now - previous) == 0:
|
||||
raise AssertionError("Publish with RLN enabled at spam rate worked!!!")
|
||||
else:
|
||||
previous = now
|
||||
except Exception as e:
|
||||
assert "RLN validation failed" in str(e)
|
||||
|
|
Loading…
Reference in New Issue