From b5fd3d6cc12b44cea7778a644ec2d22f6e45900b Mon Sep 17 00:00:00 2001 From: Florin Barbu Date: Tue, 18 Jun 2024 15:37:06 +0300 Subject: [PATCH] private group messages --- src/node/status_node.py | 4 ++ src/steps/common.py | 12 ++++ ...group.py => test_create_private_groups.py} | 11 ++-- tests/test_one_to_one_messages.py | 56 ++++++---------- tests/test_private_group_messages.py | 66 +++++++++++++++++++ 5 files changed, 107 insertions(+), 42 deletions(-) rename tests/{test_private_group.py => test_create_private_groups.py} (90%) create mode 100644 tests/test_private_group_messages.py diff --git a/src/node/status_node.py b/src/node/status_node.py index 74c80d4e..c1908749 100644 --- a/src/node/status_node.py +++ b/src/node/status_node.py @@ -130,6 +130,10 @@ class StatusNode: params = [None, group_chat_name, pubkey_list] return self.api.send_rpc_request("wakuext_createGroupChatWithMembers", params) + def send_group_chat_message(self, group_id, message): + params = [{"id": group_id, "message": message}] + return self.api.send_rpc_request("wakuext_sendGroupChatMessage", params) + def random_node_name(self, length=10): allowed_chars = string.ascii_lowercase + string.digits + "_-" return "".join(random.choice(allowed_chars) for _ in range(length)) diff --git a/src/steps/common.py b/src/steps/common.py index 9c1c84ff..26ce1f14 100644 --- a/src/steps/common.py +++ b/src/steps/common.py @@ -83,3 +83,15 @@ class StepsCommon: receiving_node_pk = self.first_node_pubkey sending_node.send_contact_request(receiving_node_pk, "hi") assert sending_node.wait_for_logs(["accepted your contact request"], timeout=10) + + @retry(stop=stop_after_delay(40), wait=wait_fixed(0.5), reraise=True) + def join_private_group(self, sending_node=None, members_list=None): + if not sending_node: + sending_node = self.second_node + if not members_list: + members_list = [self.first_node_pubkey] + response = sending_node.create_group_chat_with_members(members_list, "new_group") + receiving_node = self.first_node if sending_node == self.second_node else self.second_node + assert receiving_node.wait_for_logs(["created the group new_group"], timeout=10) + self.private_group_id = response["result"]["chats"][0]["id"] + return self.private_group_id diff --git a/tests/test_private_group.py b/tests/test_create_private_groups.py similarity index 90% rename from tests/test_private_group.py rename to tests/test_create_private_groups.py index 31a70068..7d57a908 100644 --- a/tests/test_private_group.py +++ b/tests/test_create_private_groups.py @@ -5,7 +5,7 @@ from src.steps.common import StepsCommon @pytest.mark.usefixtures("start_2_nodes") -class TestPrivateGroup(StepsCommon): +class TestCreatePrivateGroups(StepsCommon): def test_create_group_chat_baseline(self): num_private_groups = NUM_MESSAGES # Set the number of private groups to create @@ -14,9 +14,7 @@ class TestPrivateGroup(StepsCommon): self.accept_contact_request() for i in range(num_private_groups): - private_group_name = f"private_group_{i}" - - # alernating which node creates the private group + # Alernating which node creates the private group if i % 2 == 0: node = self.second_node other_node_pubkey = self.first_node_pubkey @@ -24,6 +22,7 @@ class TestPrivateGroup(StepsCommon): node = self.first_node other_node_pubkey = self.second_node_pubkey + private_group_name = f"private_group_from_{node.name}_{i}" timestamp, message_id = self.create_group_chat_with_timestamp(node, [other_node_pubkey], private_group_name) private_groups.append((timestamp, private_group_name, message_id, node.name)) delay(DELAY_BETWEEN_MESSAGES) @@ -38,11 +37,11 @@ class TestPrivateGroup(StepsCommon): missing_private_groups.append((timestamp, private_group_name, message_id, node_name)) if missing_private_groups: - formatted_missing_requests = [ + formatted_missing_groups = [ f"Timestamp: {ts}, GroupName: {msg}, ID: {mid}, Node: {node}" for ts, msg, mid, node in missing_private_groups ] raise AssertionError( - f"{len(missing_private_groups)} private groups out of {num_private_groups} were not created: " + "\n".join(formatted_missing_requests) + f"{len(missing_private_groups)} private groups out of {num_private_groups} were not created: " + "\n".join(formatted_missing_groups) ) def test_create_group_chat_with_latency(self): diff --git a/tests/test_one_to_one_messages.py b/tests/test_one_to_one_messages.py index 85f031e0..a87d8cde 100644 --- a/tests/test_one_to_one_messages.py +++ b/tests/test_one_to_one_messages.py @@ -9,56 +9,40 @@ class TestOneToOneMessages(StepsCommon): def test_one_to_one_baseline(self): num_messages = NUM_MESSAGES # Set the number of messages to send - # Send contact request from second_node to first_node - self.second_node.send_contact_request(self.first_node_pubkey, "test1") - assert self.second_node.wait_for_logs(["accepted your contact request"], timeout=20) + self.accept_contact_request() messages = [] - # Send messages from second_node to first_node and from first_node to second_node for i in range(num_messages): - message_second_node = f"message_from_second_node_{i}" - message_first_node = f"message_from_first_node_{i}" - timestamp_second_node, message_id_second_node = self.send_with_timestamp( - self.second_node.send_message, self.first_node_pubkey, message_second_node - ) + # Alternating which node sends the message + if i % 2 == 0: + sending_node = self.second_node + receiving_node_pubkey = self.first_node_pubkey + else: + sending_node = self.first_node + receiving_node_pubkey = self.second_node_pubkey + + message = f"message_from_{sending_node.name}_{i}" + timestamp, message_id = self.send_with_timestamp(sending_node.send_message, receiving_node_pubkey, message) + messages.append((timestamp, message, message_id, sending_node.name)) delay(DELAY_BETWEEN_MESSAGES) - timestamp_first_node, message_id_first_node = self.send_with_timestamp( - self.first_node.send_message, self.second_node_pubkey, message_first_node - ) - delay(DELAY_BETWEEN_MESSAGES) - messages.append((timestamp_second_node, message_second_node, message_id_second_node, "second_node")) - messages.append((timestamp_first_node, message_first_node, message_id_first_node, "first_node")) # Wait for 10 seconds to give all messages time to be received delay(10) # Validate that all messages were received - missing_messages = {"first_node": [], "second_node": []} + missing_messages = [] for timestamp, message, message_id, sender in messages: - if sender == "second_node": - log_message = f"message received: {message}" - if not self.first_node.search_logs(log_message): - missing_messages["first_node"].append((timestamp, message, message_id)) - elif sender == "first_node": - log_message = f"message received: {message}" - if not self.second_node.search_logs(log_message): - missing_messages["second_node"].append((timestamp, message, message_id)) + search_node = self.first_node if sender == self.second_node.name else self.second_node + if not search_node.search_logs(f"message received: {message}"): + missing_messages.append((timestamp, message, message_id, sender)) - # Check for missing messages and collect assertion errors - errors = [] - if missing_messages["first_node"]: - errors.append( - f"first_node didn't receive {len(missing_messages['first_node'])} out of {num_messages} messages from second_node: {missing_messages['first_node']}" + if missing_messages: + formatted_missing_messages = [f"Timestamp: {ts}, Message: {msg}, ID: {mid}, Sender: {snd}" for ts, msg, mid, snd in missing_messages] + raise AssertionError( + f"{len(missing_messages)} messages out of {num_messages} were not received: " + "\n".join(formatted_missing_messages) ) - errors.append( - f"second_node didn't receive {len(missing_messages['second_node'])} out of {num_messages} messages from first_node: {missing_messages['second_node']}" - ) - - # Raise a combined assertion error if there are any missing messages - if errors: - raise AssertionError("\n".join(errors)) def test_one_to_one_with_latency(self): self.accept_contact_request() diff --git a/tests/test_private_group_messages.py b/tests/test_private_group_messages.py new file mode 100644 index 00000000..1fc36bea --- /dev/null +++ b/tests/test_private_group_messages.py @@ -0,0 +1,66 @@ +import pytest +from src.env_vars import DELAY_BETWEEN_MESSAGES, NUM_MESSAGES +from src.libs.common import delay +from src.steps.common import StepsCommon + + +@pytest.mark.usefixtures("start_2_nodes") +class TestPrivateGroupMessages(StepsCommon): + def test_group_chat_messages(self): + num_private_groups = NUM_MESSAGES # Set the number of private messages to send + + self.accept_contact_request() + try: + self.private_group_id + except: + self.join_private_group() + + messages = [] + + for i in range(num_private_groups): + # Alternating which node sends the message + if i % 2 == 0: + sending_node = self.second_node + else: + sending_node = self.first_node + + message = f"message_from_{sending_node.name}_{i}" + timestamp, message_id = self.send_with_timestamp(sending_node.send_group_chat_message, self.private_group_id, message) + messages.append((timestamp, message, message_id, sending_node.name)) + delay(DELAY_BETWEEN_MESSAGES) + + # Wait for 10 seconds to give all messages time to be received + delay(10) + + # Validate that all messages were received + missing_messages = [] + + for timestamp, message, message_id, sender in messages: + search_node = self.first_node if sender == self.second_node.name else self.second_node + if not search_node.search_logs(f"message received: {message}"): + missing_messages.append((timestamp, message, message_id, sender)) + + if missing_messages: + formatted_missing_messages = [f"Timestamp: {ts}, Message: {msg}, ID: {mid}, Sender: {snd}" for ts, msg, mid, snd in missing_messages] + raise AssertionError( + f"{len(missing_messages)} messages out of {num_private_groups} were not received: " + "\n".join(formatted_missing_messages) + ) + + def test_group_chat_messages_with_latency(self): + self.accept_contact_request() + self.join_private_group() + # we want to set latency only on the group creation requests + with self.add_latency(): + self.test_group_chat_messages() + + def test_group_chat_messages_with_packet_loss(self): + self.accept_contact_request() + self.join_private_group() + with self.add_packet_loss(): + self.test_group_chat_messages() + + def test_group_chat_messages_with_low_bandwith(self): + self.accept_contact_request() + self.join_private_group() + with self.add_low_bandwith(): + self.test_group_chat_messages()