Files
status-app/test/e2e/conftest.py

190 lines
6.0 KiB
Python

import logging
import configs
import os
import allure
import pytest
import shortuuid
import sys
import subprocess
from tests import test_data
from configs.system import get_platform
from fixtures.path import generate_test_info
from scripts.utils.benchmark_report import finalize_structured_benchmark_result
from scripts.utils.failure_screenshot import attach_failure_screenshot
from scripts.utils.system_path import SystemPath
# Root logging: pytest.ini uses -p no:logging, so we configure file + stderr here.
_log_level_name = os.getenv('LOG_LEVEL', 'INFO').upper()
_log_level = getattr(logging, _log_level_name, logging.INFO)
log_dir = os.path.dirname(configs.PYTEST_LOG)
os.makedirs(log_dir, exist_ok=True)
_log_fmt = logging.Formatter(
'[%(asctime)s] (%(filename)18s:%(lineno)-3s) [%(levelname)-7s] %(name)s --- %(message)s'
)
_file_handler = logging.FileHandler(filename=configs.PYTEST_LOG, encoding='utf-8')
_file_handler.setFormatter(_log_fmt)
_stream_handler = logging.StreamHandler(sys.stderr)
_stream_handler.setFormatter(_log_fmt)
logging.basicConfig(
level=_log_level,
handlers=[_file_handler, _stream_handler],
force=True,
)
LOG = logging.getLogger(__name__)
LOG.info('Logging to stderr and %s (level=%s)', configs.PYTEST_LOG, _log_level_name)
pytest_plugins = [
'fixtures.aut',
'fixtures.keycard',
'fixtures.path',
'fixtures.squish',
]
def get_git_commit():
"""Get git commit hash from parent repository"""
# Try to get git commit from parent repository (status-app)
try:
# Get parent directory (status-app)
parent_repo = configs.testpath.ROOT.parent.parent
result = subprocess.run(
['git', 'rev-parse', 'HEAD'],
cwd=str(parent_repo),
capture_output=True,
text=True,
timeout=5
)
if result.returncode == 0:
commit_hash = result.stdout.strip()
return commit_hash
except (subprocess.TimeoutExpired, FileNotFoundError, Exception) as e:
LOG.debug(f'Could not get git commit: {e}')
return None
def get_status_go_commit():
"""Get git commit hash from status-go repository"""
# Try to get git commit from status-go repository (vendor/status-go)
try:
# Get status-go directory (vendor/status-go)
status_go_repo = configs.testpath.ROOT.parent.parent / 'vendor' / 'status-go'
result = subprocess.run(
['git', 'rev-parse', 'HEAD'],
cwd=str(status_go_repo),
capture_output=True,
text=True,
timeout=5
)
if result.returncode == 0:
commit_hash = result.stdout.strip()
return commit_hash
except (subprocess.TimeoutExpired, FileNotFoundError, Exception) as e:
LOG.debug(f'Could not get status-go git commit: {e}')
return None
@pytest.fixture(scope='session', autouse=True)
def generate_allure_environment():
"""Generate allure environment.properties with dynamic platform information"""
env_dir = configs.testpath.ROOT / 'ext' / 'allure_files'
env_file = env_dir / 'environment.properties'
# Ensure directory exists
env_dir.mkdir(parents=True, exist_ok=True)
platform_name = get_platform()
python_version = f"Python {sys.version_info.major}.{sys.version_info.minor}"
git_commit = get_git_commit()
status_go_commit = get_status_go_commit()
lines = [f"os_platform = {platform_name}"]
if git_commit:
lines.append(f"status app commit hash = {git_commit}")
if status_go_commit:
lines.append(f"status-go commit hash = {status_go_commit}")
lines.append(f"python_version = {python_version}")
content = "\n".join(lines) + "\n"
env_file.write_text(content)
LOG.info(f'Generated allure environment.properties with platform={platform_name}, status app commit hash={git_commit}, status-go commit hash={status_go_commit}, python={python_version}')
yield
@pytest.fixture(scope='session', autouse=True)
def setup_session_scope(
generate_allure_environment,
prepare_test_directory,
start_squish_server
):
LOG.info('Session startup...')
yield
@pytest.fixture(autouse=True)
def setup_function_scope(
caplog,
generate_test_data,
application_logs,
):
# FIXME: broken due to KeyError: <_pytest.stash.StashKey object at 0x7fd1ba6d78c0>
# caplog.set_level(configs.LOG_LEVEL)
yield
def pytest_runtest_setup(item):
test_data.test_name = item.name
test_data.error = []
test_data.steps = []
test_data.aut_screenshot_attached = False
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
setattr(item, 'rep_' + rep.when, rep)
if rep.when == 'call':
if rep.failed:
test_data.error = rep.longreprtext
elif rep.outcome == 'passed':
if test_data.error:
rep.outcome = 'failed'
error_text = str()
for line in test_data.error:
error_text += f"{line}; \n ---- soft assert ---- \n\n"
rep.longrepr = error_text
elif rep.failed:
test_data.error = rep.longreprtext
if rep.when == 'call' and item.get_closest_marker('benchmark') is not None:
finalize_structured_benchmark_result(
item.nodeid,
item.name,
status='passed' if rep.outcome == 'passed' else 'failed',
duration_seconds=rep.duration,
)
def pytest_exception_interact(node, call, report):
if call.when != 'call':
return
if test_data.aut_screenshot_attached:
return
test_path, test_name, test_params = generate_test_info(node)
node_dir: SystemPath = configs.testpath.RUN / test_path / test_name / test_params
node_dir.mkdir(parents=True, exist_ok=True)
screenshot = node_dir / f'screenshot_{shortuuid.ShortUUID().random(length=10)}.png'
attach_failure_screenshot(screenshot)
test_data.aut_screenshot_attached = True