test_: Code Migration from status-cli-tests review addressing

This commit is contained in:
shashankshampi 2024-11-02 20:15:39 +05:30
parent 1827420f4c
commit 670f17a25f
6 changed files with 84 additions and 28 deletions

View File

@ -5,7 +5,10 @@ from src.libs.common import write_signal_to_file
import websocket
logger = logging.getLogger(__name__)
from src.libs.custom_logger import get_custom_logger
logger = get_custom_logger(__name__)
class SignalClient:
@ -23,25 +26,31 @@ class SignalClient:
if signal_type in self.await_signals:
self.received_signals[signal_type].append(signal_data)
def wait_for_signal(self, signal_type, expected_event=None, timeout=20):
def wait_for_signal(self, signal_type, timeout=20):
start_time = time.time()
while not self.received_signals.get(signal_type):
if time.time() - start_time >= timeout:
raise TimeoutError(
f"Signal {signal_type} is not received in {timeout} seconds")
time.sleep(0.2)
logging.debug(f"Signal {signal_type} is received in {round(time.time() - start_time)} seconds")
return self.received_signals[signal_type][0]
def wait_for_complete_signal(self, signal_type, timeout=5):
start_time = time.time()
events = []
while time.time() - start_time < timeout:
if self.received_signals.get(signal_type):
received_signal = self.received_signals[signal_type][0]
if expected_event:
event = received_signal.get("event", {})
if all(event.get(k) == v for k, v in expected_event.items()):
logger.info(f"Signal {signal_type} with event {expected_event} received and matched.")
return received_signal
else:
logger.debug(
f"Signal {signal_type} received but event did not match expected event: {expected_event}. Received event: {event}")
else:
logger.info(f"Signal {signal_type} received without specific event validation.")
return received_signal
events.extend(self.received_signals[signal_type])
self.received_signals[signal_type] = []
time.sleep(0.2)
raise TimeoutError(f"Signal {signal_type} with event {expected_event} not received in {timeout} seconds")
if events:
logging.debug(
f"Collected {len(events)} events of type {signal_type} within {timeout} seconds")
return events
raise TimeoutError(f"No signals of type {signal_type} received in {timeout} seconds")
def _on_error(self, ws, error):
logger.error(f"WebSocket error: {error}")

View File

@ -65,7 +65,7 @@ class RpcClient:
response = self.rpc_request(method, params, _id, url)
self.verify_is_valid_json_rpc_response(response, _id)
return response
def verify_json_schema(self, response, method):
with open(f"{option.base_dir}/schemas/{method}", "r") as schema:
jsonschema.validate(instance=response,

View File

@ -81,7 +81,7 @@ class StatusNode:
def start_signal_client(self):
ws_url = f"ws://localhost:{self.port}"
await_signals = ["history.request.started", "history.request.completed","messages.new"]
await_signals = ["history.request.started", "messages.new", "history.request.completed"]
self.signal_client = SignalClient(ws_url, await_signals)
websocket_thread = threading.Thread(target=self.signal_client._connect)
@ -125,8 +125,11 @@ class StatusNode:
return account.get("public-key")
raise ValueError(f"Public key not found for display name: {display_name}")
def wait_for_signal(self, signal_type, expected_event=None, timeout=20):
return self.signal_client.wait_for_signal(signal_type, expected_event, timeout)
def wait_for_signal(self, signal_type, timeout=20):
return self.signal_client.wait_for_signal(signal_type, timeout)
def wait_for_complete_signal(self, signal_type, timeout=20):
return self.signal_client.wait_for_complete_signal(signal_type, timeout)
def stop(self, remove_local_data=True):
if self.process:

View File

@ -2,7 +2,6 @@ from contextlib import contextmanager
import inspect
import subprocess
import pytest
from tenacity import retry
from src.libs.common import delay
from src.libs.custom_logger import get_custom_logger

View File

@ -2,15 +2,17 @@ import logging
from uuid import uuid4
from constants import *
from src.libs.common import delay
from src.node.status_node import StatusNode, logger
from src.libs.custom_logger import get_custom_logger
from src.node.status_node import StatusNode
from src.steps.common import StepsCommon
from src.libs.common import create_unique_data_dir, get_project_root
from validators.contact_request_validator import ContactRequestValidator
logger = get_custom_logger(__name__)
class TestContactRequest(StepsCommon):
def test_contact_request_baseline(self):
timeout_secs = 10
timeout_secs = 3
num_contact_requests = NUM_CONTACT_REQUESTS
project_root = get_project_root()
nodes = []
@ -86,10 +88,38 @@ class TestContactRequest(StepsCommon):
timestamp, message_id, response = self.send_with_timestamp(
second_node.send_contact_request, first_node_pubkey, contact_request_message
)
validator = ContactRequestValidator(response)
validator.run_all_validations(first_node_pubkey, display_name, contact_request_message)
try:
first_node.wait_for_signal("history.request.started", None, timeout)
first_node.wait_for_signal("history.request.completed", None, timeout)
except TimeoutError as e:
first_node.wait_for_signal("history.request.started", timeout)
messages_new_events = first_node.wait_for_complete_signal("messages.new", timeout)
messages_new_event = None
for event in messages_new_events:
if "chats" in event.get("event", {}):
messages_new_event = event
try:
validator.validate_event_against_response(
messages_new_event,
fields_to_validate={
"text": "text",
"displayName": "displayName",
"id": "id"
}
)
break
except AssertionError as validation_error:
logging.error(f"Validation failed for event: {messages_new_event}, Error: {validation_error}")
continue
if messages_new_event is None:
raise ValueError("No 'messages.new' event with 'chats' data found within the timeout period.")
first_node.wait_for_signal("history.request.completed", timeout)
except (TimeoutError, ValueError) as e:
logging.error(f"Signal validation failed: {str(e)}")
return timestamp, message_id, contact_request_message, None
@ -115,4 +145,4 @@ class TestContactRequest(StepsCommon):
message = str(uuid4())
self.first_node.send_contact_request(self.second_node_pubkey, message)
delay(10)
assert self.second_node.wait_for_signal("history.request.completed")
assert self.second_node.wait_for_complete_signal("history.request.completed")

View File

@ -1,10 +1,11 @@
import logging
from src.steps.common import logger
from src.libs.custom_logger import get_custom_logger
logger = get_custom_logger(__name__)
class ContactRequestValidator:
def __init__(self, response):
self.response = response
@ -25,6 +26,20 @@ class ContactRequestValidator:
assert last_message.get("contactRequestState") == 1, "Unexpected contact request state"
assert "compressedKey" in last_message, "Missing 'compressedKey' in last message"
def validate_event_against_response(self, event, fields_to_validate):
chats_in_event = event.get("event", {}).get("chats", [])
assert len(chats_in_event) > 0, "No chats found in the event"
response_chat = self.response["result"]["chats"][0]
event_chat = chats_in_event[0]
for response_field, event_field in fields_to_validate.items():
response_value = response_chat.get("lastMessage", {}).get(response_field)
event_value = event_chat.get("lastMessage", {}).get(event_field)
assert response_value == event_value, (
f"Mismatch for '{response_field}': expected '{response_value}', got '{event_value}'"
)
def run_all_validations(self, expected_chat_id, expected_display_name, expected_text):
self.validate_response_structure()
self.validate_chat_data(expected_chat_id, expected_display_name, expected_text)