Skip to content

Commit

Permalink
test_: graceful shutdown for codecov, logs from each container
Browse files Browse the repository at this point in the history
  • Loading branch information
antdanchenko committed Dec 10, 2024
1 parent e78d3a7 commit c9921d4
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ internal/version/GIT_COMMIT
internal/sentry/SENTRY_CONTEXT_NAME
internal/sentry/SENTRY_CONTEXT_VERSION
internal/sentry/SENTRY_PRODUCTION
logs-*

# Don't ignore generated files in the vendor/ directory
!vendor/**/*.pb.go
Expand Down
1 change: 1 addition & 0 deletions _assets/build/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ LABEL source="https://github.com/status-im/status-go"
LABEL description="status-go is an underlying part of Status - a browser, messenger, and gateway to a decentralized world."

RUN apk add --no-cache ca-certificates bash libgcc libstdc++ curl
RUN mkdir -p /status-user
RUN mkdir -p /static/keys
RUN mkdir -p /static/configs

Expand Down
5 changes: 5 additions & 0 deletions _assets/scripts/run_functional_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ coverage_reports_path="${root_path}/coverage"
binary_coverage_reports_path="${coverage_reports_path}/binary"
merged_coverage_reports_path="${coverage_reports_path}/merged"
test_results_path="${root_path}/reports"
status_backend_logs="${root_path}/logs/status-backend"

# Cleanup any previous coverage reports
rm -rf "${coverage_reports_path}"
Expand All @@ -22,13 +23,17 @@ rm -rf "${test_results_path}"
mkdir -p "${binary_coverage_reports_path}"
mkdir -p "${merged_coverage_reports_path}"
mkdir -p "${test_results_path}"
mkdir -p "${status_backend_logs}"

all_compose_files="-f ${root_path}/docker-compose.anvil.yml -f ${root_path}/docker-compose.test.status-go.yml"
project_name="status-go-func-tests-$(date +%s)"

export STATUS_BACKEND_COUNT=1
export STATUS_BACKEND_URLS=$(eval echo http://${project_name}-status-backend-{1..${STATUS_BACKEND_COUNT}}:3333 | tr ' ' ,)

# Remove orphans
docker ps -a --filter "name=status-go-func-tests-*-status-backend-*" --filter "status=exited" -q | xargs -r docker rm

# Run docker
echo -e "${GRN}Running tests${RST}, HEAD: $(git rev-parse HEAD)"
docker compose -p ${project_name} ${all_compose_files} up -d --build --scale status-backend=${STATUS_BACKEND_COUNT} --remove-orphans
Expand Down
63 changes: 45 additions & 18 deletions tests-functional/clients/status_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import threading
import requests
import docker
import os

from tenacity import retry, stop_after_delay, wait_fixed
from clients.signals import SignalClient
from clients.rpc import RpcClient
from datetime import datetime
from conftest import option
from constants import user_1, DEFAULT_DISPLAY_NAME
from constants import user_1, DEFAULT_DISPLAY_NAME, USER_DIR


class StatusBackend(RpcClient, SignalClient):
Expand All @@ -30,7 +31,6 @@ def __init__(self, await_signals=[], new_container=True):
else:
url = option.status_backend_url


self.api_url = f"{url}/statusgo"
self.ws_url = f"{url}".replace("http", "ws")
self.rpc_url = f"{url}/statusgo/CallRPC"
Expand All @@ -51,19 +51,42 @@ def _start_container(self, host_port):
image_name = f"{docker_project_name}-status-backend:latest"
container_name = f"{docker_project_name}-status-backend-{timestamp}"

container = self.docker_client.containers.run(
image_name,
detach=True,
name=container_name,
labels={"com.docker.compose.project": docker_project_name},
entrypoint=[
coverage_path = os.path.abspath("./coverage/binary")
init_folder = os.path.abspath(f"./logs/status-backend/{container_name}")

container_args = {
"image": image_name,
"detach": True,
"name": container_name,
"labels": {"com.docker.compose.project": docker_project_name},
"entrypoint": [
"status-backend",
"--address", "0.0.0.0:3333",
],
ports={"3333/tcp": host_port}
)
"ports": {"3333/tcp": host_port},
"environment": {
"GOCOVERDIR": "/coverage/binary",
},
"volumes": {
coverage_path: {
"bind": "/coverage/binary",
"mode": "rw",
},
init_folder: {
"bind": USER_DIR,
"mode": "rw",
},
},
"stop_signal": "SIGINT"
}

if "FUNCTIONAL_TESTS_DOCKER_UID" in os.environ:
container_args["user"] = os.environ["FUNCTIONAL_TESTS_DOCKER_UID"]

container = self.docker_client.containers.run(**container_args)

network = self.docker_client.networks.get(f"{docker_project_name}_default")
network = self.docker_client.networks.get(
f"{docker_project_name}_default")
network.connect(container)

option.status_backend_containers.append(container.id)
Expand All @@ -83,7 +106,8 @@ def _health_check(self):
def api_request(self, method, data, url=None):
url = url if url else self.api_url
url = f"{url}/{method}"
logging.info(f"Sending POST request to url {url} with data: {json.dumps(data, sort_keys=True, indent=4)}")
logging.info(
f"Sending POST request to url {url} with data: {json.dumps(data, sort_keys=True, indent=4)}")
response = requests.post(url, json=data)
logging.info(f"Got response: {response.content}")
return response
Expand All @@ -93,7 +117,8 @@ def verify_is_valid_api_response(self, response):
assert response.content
logging.info(f"Got response: {response.content}")
try:
assert not response.json()["error"]
error = response.json()["error"]
assert not error, f"Error: {error}"
except json.JSONDecodeError:
raise AssertionError(
f"Invalid JSON in response: {response.content}")
Expand All @@ -105,7 +130,7 @@ def api_valid_request(self, method, data):
self.verify_is_valid_api_response(response)
return response

def init_status_backend(self, data_dir="/"):
def init_status_backend(self, data_dir=USER_DIR):
method = "InitializeApplication"
data = {
"dataDir": data_dir,
Expand All @@ -115,7 +140,7 @@ def init_status_backend(self, data_dir="/"):
}
return self.api_valid_request(method, data)

def create_account_and_login(self, data_dir="/", display_name=DEFAULT_DISPLAY_NAME, password=user_1.password):
def create_account_and_login(self, data_dir=USER_DIR, display_name=DEFAULT_DISPLAY_NAME, password=user_1.password):
method = "CreateAccountAndLogin"
data = {
"rootDataDir": data_dir,
Expand All @@ -128,7 +153,7 @@ def create_account_and_login(self, data_dir="/", display_name=DEFAULT_DISPLAY_NA
}
return self.api_valid_request(method, data)

def restore_account_and_login(self, data_dir="/",display_name=DEFAULT_DISPLAY_NAME, user=user_1,
def restore_account_and_login(self, data_dir=USER_DIR, display_name=DEFAULT_DISPLAY_NAME, user=user_1,
network_id=31337):
method = "RestoreAccountAndLogin"
data = {
Expand Down Expand Up @@ -183,7 +208,8 @@ def restore_account_and_wait_for_rpc_client_to_start(self, timeout=60):
return
except AssertionError:
time.sleep(3)
raise TimeoutError(f"RPC client was not started after {timeout} seconds")
raise TimeoutError(
f"RPC client was not started after {timeout} seconds")

@retry(stop=stop_after_delay(10), wait=wait_fixed(0.5), reraise=True)
def start_messenger(self, params=[]):
Expand Down Expand Up @@ -220,7 +246,8 @@ def get_pubkey(self, display_name):
for account in accounts:
if account.get("name") == display_name:
return account.get("public-key")
raise ValueError(f"Public key not found for display name: {display_name}")
raise ValueError(
f"Public key not found for display name: {display_name}")

def send_contact_request(self, params=[]):
method = "wakuext_sendContactRequest"
Expand Down
2 changes: 1 addition & 1 deletion tests-functional/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def pytest_unconfigure():
for container_id in option.status_backend_containers:
try:
container = docker_client.containers.get(container_id)
container.stop()
container.stop(timeout=30)
container.remove()
except Exception as e:
print(e)
3 changes: 2 additions & 1 deletion tests-functional/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ class Account:
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))
TESTS_DIR = os.path.join(PROJECT_ROOT, "tests-functional")
SIGNALS_DIR = os.path.join(TESTS_DIR, "signals")
LOG_SIGNALS_TO_FILE = False # used for debugging purposes
LOG_SIGNALS_TO_FILE = False # used for debugging purposes
USER_DIR = "/status-user"

0 comments on commit c9921d4

Please sign in to comment.