From f494d09c2431ad093843938a6563cab326c0d746 Mon Sep 17 00:00:00 2001 From: fbarbu15 Date: Wed, 19 Feb 2025 14:25:57 +0200 Subject: [PATCH] test_: ip change (#6336) * test_: merge develop * test_: rerun rpc tests * test_: merge develop --- .github/workflows/test-reliability.yml | 4 +- _assets/scripts/run_functional_tests.sh | 2 +- tests-functional/clients/status_backend.py | 21 ++++- .../docker-compose.test.reliability.yml | 89 +++++++++++++++++++ tests-functional/requirements.txt | 1 + .../reliability/test_community_messages.py | 7 ++ .../tests/reliability/test_contact_request.py | 10 +++ .../reliability/test_create_private_groups.py | 10 ++- .../reliability/test_one_to_one_messages.py | 5 ++ .../test_private_groups_messages.py | 13 ++- 10 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 tests-functional/docker-compose.test.reliability.yml diff --git a/.github/workflows/test-reliability.yml b/.github/workflows/test-reliability.yml index 01dea236e4..8a65efb791 100644 --- a/.github/workflows/test-reliability.yml +++ b/.github/workflows/test-reliability.yml @@ -36,10 +36,10 @@ jobs: run: pip install -r tests-functional/requirements.txt - name: Build status-backend - run: cd tests-functional; docker compose -f docker-compose.anvil.yml -f docker-compose.test.status-go.yml -f docker-compose.status-go.local.yml up --build --remove-orphans -d + run: cd tests-functional; docker compose -f docker-compose.test.reliability.yml up --build --remove-orphans -d - name: Run tests - run: pytest -n auto -m "reliability" -c tests-functional/pytest.ini --junit-xml=pytest_results.xml --tb=short + run: pytest --reruns 2 -n auto -m "reliability" -c tests-functional/pytest.ini --junit-xml=pytest_results.xml --tb=short - name: Test Report if: always() diff --git a/_assets/scripts/run_functional_tests.sh b/_assets/scripts/run_functional_tests.sh index 923bd704aa..6e3957cf6f 100755 --- a/_assets/scripts/run_functional_tests.sh +++ b/_assets/scripts/run_functional_tests.sh @@ -54,7 +54,7 @@ pip install --upgrade pip pip install -r "${root_path}/requirements.txt" # Run functional tests -pytest -m rpc --docker_project_name=${project_name} --codecov_dir=${binary_coverage_reports_path} --junitxml=${test_results_path}/report.xml +pytest --reruns 2 -m rpc --docker_project_name=${project_name} --codecov_dir=${binary_coverage_reports_path} --junitxml=${test_results_path}/report.xml exit_code=$? # Stop containers diff --git a/tests-functional/clients/status_backend.py b/tests-functional/clients/status_backend.py index 69383df879..dd7a4a8223 100644 --- a/tests-functional/clients/status_backend.py +++ b/tests-functional/clients/status_backend.py @@ -45,8 +45,8 @@ def __init__(self, await_signals=[], privileged=False): url = f"http://127.0.0.1:{host_port}" option.status_backend_port_range.remove(host_port) break - except Exception: - continue + except Exception as ex: + logging.error(f"Error in starting the container: {str(ex)}") else: raise RuntimeError(f"Failed to start container on ports: {ports_tried}") @@ -334,3 +334,20 @@ def kill(self): finally: self.container = None logging.info("Container stopped.") + + @retry(stop=stop_after_delay(10), wait=wait_fixed(0.1), reraise=True) + def change_container_ip(self, new_ip=None): + if not self.container: + raise RuntimeError("Container is not initialized.") + logging.info(f"Trying to change container {self.container.name} IP") + if not new_ip: + new_ip = f"172.11.0.{random.randint(2, 254)}" + docker_project_name = option.docker_project_name + network_name = f"{docker_project_name}_default" + try: + network = self.docker_client.networks.get(network_name) + network.disconnect(self.container) + network.connect(self.container, ipv4_address=new_ip) + logging.info(f"Changed container {self.container.name} IP to {new_ip}") + except Exception as e: + raise RuntimeError(f"Failed to change container IP: {e}") diff --git a/tests-functional/docker-compose.test.reliability.yml b/tests-functional/docker-compose.test.reliability.yml new file mode 100644 index 0000000000..223c788541 --- /dev/null +++ b/tests-functional/docker-compose.test.reliability.yml @@ -0,0 +1,89 @@ +version: "3.9" + +networks: + default: + driver: bridge + ipam: + config: + - subnet: 172.11.0.0/24 + +services: + anvil: + image: ghcr.io/foundry-rs/foundry:latest + platform: linux/amd64 + command: + - anvil --host 0.0.0.0 --block-time 2 + ports: + - 8545:8545 + networks: + - default + + deploy-sntv2: + platform: linux/amd64 + environment: + - API_KEY_ETHERSCAN="" # API_KEY env var is required, but value isn't used + - GITHUB_ORG=status-im + - GITHUB_REPO=status-network-token-v2 + depends_on: + - anvil + build: + context: . + dockerfile: Dockerfile + command: | + forge script script/Deploy.s.sol + --broadcast + --fork-url=http://anvil:8545 + --private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + networks: + - default + + deploy-communities-contracts: + platform: linux/amd64 + environment: + - API_KEY_ETHERSCAN="" + - API_KEY_ARBISCAN="" + - API_KEY_OPTIMISTIC_ETHERSCAN="" + - GITHUB_ORG=status-im + - GITHUB_REPO=communities-contracts + depends_on: + deploy-sntv2: + condition: service_completed_successfully + build: + context: . + dockerfile: Dockerfile + command: | + forge script script/DeployContracts.s.sol + --broadcast + --fork-url=http://anvil:8545 + --private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + --sender=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + networks: + - default + + status-backend: + user: ${INTEGRATION_TESTS_DOCKER_UID} + build: + context: ../ + dockerfile: _assets/build/Dockerfile + args: + build_tags: gowaku_no_rln,enable_private_api + build_target: status-backend + build_flags: -cover + entrypoint: [ + "status-backend", + "--address", "0.0.0.0:3333", + ] + healthcheck: + test: ["CMD-SHELL", "curl -X POST --data '{\"jsonrpc\":\"2.0\",\"method\":\"net_version\",\"params\":[],\"id\":1}' -H 'Content-Type: application/json' http://0.0.0.0:3333 || exit 1"] + interval: 5s + timeout: 2s + retries: 120 + environment: + GOCOVERDIR: "/coverage/binary" + volumes: + - ./coverage/binary:/coverage/binary + ports: + - 3314-3324:3333 + stop_signal: SIGINT + networks: + - default diff --git a/tests-functional/requirements.txt b/tests-functional/requirements.txt index 657053fdf1..da1077a6fb 100644 --- a/tests-functional/requirements.txt +++ b/tests-functional/requirements.txt @@ -11,3 +11,4 @@ pyright~=1.1.388 black~=24.10.0 pre-commit~=3.6.2 pytest-xdist~=3.6.1 +pytest-rerunfailures==13.0 diff --git a/tests-functional/tests/reliability/test_community_messages.py b/tests-functional/tests/reliability/test_community_messages.py index 36eb6134a1..56a80e54ee 100644 --- a/tests-functional/tests/reliability/test_community_messages.py +++ b/tests-functional/tests/reliability/test_community_messages.py @@ -35,3 +35,10 @@ def test_community_messages_with_node_pause_30_seconds(self): self.sender.wakuext_service.send_community_chat_message(message_chat_id, message_text) sleep(30) self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=message_text) + + def test_community_messages_with_ip_change(self): + message_chat_id = self.create_and_join_community() + + self.community_messages(message_chat_id, 1) + self.receiver.change_container_ip() + self.community_messages(message_chat_id, 1) diff --git a/tests-functional/tests/reliability/test_contact_request.py b/tests-functional/tests/reliability/test_contact_request.py index c6c1eb1528..6c404a1089 100644 --- a/tests-functional/tests/reliability/test_contact_request.py +++ b/tests-functional/tests/reliability/test_contact_request.py @@ -37,3 +37,13 @@ def test_contact_request_with_node_pause_30_seconds(self): sleep(30) receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=expected_message.get("id")) sender.wait_for_signal(SignalType.MESSAGE_DELIVERED.value) + + def test_contact_request_with_ip_change(self): + sender = self.initialize_backend(await_signals=self.await_signals, privileged=True) + receiver = self.initialize_backend(await_signals=self.await_signals, privileged=True) + receiver.change_container_ip() + + message_text = f"test_contact_request_{uuid4()}" + response = sender.wakuext_service.send_contact_request(receiver.public_key, message_text) + expected_message = self.get_message_by_content_type(response, content_type=MessageContentType.CONTACT_REQUEST.value)[0] + receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=expected_message.get("id")) diff --git a/tests-functional/tests/reliability/test_create_private_groups.py b/tests-functional/tests/reliability/test_create_private_groups.py index 2e896f1190..ece7c89bda 100644 --- a/tests-functional/tests/reliability/test_create_private_groups.py +++ b/tests-functional/tests/reliability/test_create_private_groups.py @@ -13,7 +13,7 @@ def test_create_private_group_baseline(self, private_groups_count=1): self.make_contacts() self.create_private_group(private_groups_count) - def test_multiple_one_create_private_groups(self): + def test_multiple_create_private_groups(self): self.test_create_private_group_baseline(private_groups_count=50) def test_create_private_groups_with_node_pause_30_seconds(self): @@ -24,3 +24,11 @@ def test_create_private_groups_with_node_pause_30_seconds(self): self.sender.wakuext_service.create_group_chat_with_members([self.receiver.public_key], private_group_name) sleep(30) self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=private_group_name) + + def test_create_private_groups_with_ip_change(self): + self.make_contacts() + self.receiver.change_container_ip() + + private_group_name = f"private_group_{uuid4()}" + self.sender.wakuext_service.create_group_chat_with_members([self.receiver.public_key], private_group_name) + self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=private_group_name) diff --git a/tests-functional/tests/reliability/test_one_to_one_messages.py b/tests-functional/tests/reliability/test_one_to_one_messages.py index 0f3f1d5fe1..7d51ab785d 100644 --- a/tests-functional/tests/reliability/test_one_to_one_messages.py +++ b/tests-functional/tests/reliability/test_one_to_one_messages.py @@ -34,3 +34,8 @@ def test_one_to_one_message_with_node_pause_30_seconds(self): sleep(30) self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=message_text) self.sender.wait_for_signal(SignalType.MESSAGE_DELIVERED.value) + + def test_one_to_one_messages_with_ip_change(self): + self.test_one_to_one_message_baseline() + self.receiver.change_container_ip() + self.test_one_to_one_message_baseline() diff --git a/tests-functional/tests/reliability/test_private_groups_messages.py b/tests-functional/tests/reliability/test_private_groups_messages.py index 4bbbb16784..b725ce0f07 100644 --- a/tests-functional/tests/reliability/test_private_groups_messages.py +++ b/tests-functional/tests/reliability/test_private_groups_messages.py @@ -17,15 +17,15 @@ def test_private_group_messages_baseline(self, message_count=1): def test_multiple_group_chat_messages(self): self.test_private_group_messages_baseline(message_count=50) - def test_multiple_group_chat_messages_with_latency(self): + def test_private_group_chat_messages_with_latency(self): with self.add_latency(self.receiver): self.test_private_group_messages_baseline(message_count=50) - def test_multiple_group_chat_messages_with_packet_loss(self): + def test_private_group_chat_messages_with_packet_loss(self): with self.add_packet_loss(self.receiver): self.test_private_group_messages_baseline(message_count=50) - def test_multiple_group_chat_messages_with_low_bandwidth(self): + def test_private_group_chat_messages_with_low_bandwidth(self): with self.add_low_bandwith(self.receiver): self.test_private_group_messages_baseline(message_count=50) @@ -39,3 +39,10 @@ def test_private_group_messages_with_node_pause_30_seconds(self): sleep(30) self.receiver.find_signal_containing_pattern(SignalType.MESSAGES_NEW.value, event_pattern=message_text) self.sender.wait_for_signal(SignalType.MESSAGE_DELIVERED.value) + + def test_private_group_messages_with_ip_change(self): + self.make_contacts() + self.private_group_id = self.join_private_group() + self.private_group_message(1, self.private_group_id) + self.receiver.change_container_ip() + self.private_group_message(1, self.private_group_id)