From 29e96df0d779815084d38a7bb2551011436563aa Mon Sep 17 00:00:00 2001 From: Colin James Date: Mon, 11 May 2026 11:09:22 +0100 Subject: [PATCH 1/2] Add tracing setup and teardown Signed-off-by: Colin James --- conftest.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/conftest.py b/conftest.py index d5107c241..43c7f57f9 100644 --- a/conftest.py +++ b/conftest.py @@ -116,6 +116,12 @@ def pytest_addoption(parser: pytest.Parser) -> None: default="2GiB", help="Maximum amount of data written to a volume" ) + parser.addoption( + "--tracing-endpoint", + action="store", + default=None, + help="Specify distributed tracing endpoint." + ) def pytest_configure(config: pytest.Config) -> None: global_config.ignore_ssh_banner = config.getoption('--ignore-ssh-banner') @@ -192,6 +198,19 @@ def pytest_runtest_makereport( # END make test results visible from fixtures +def setup_tracing(host: Host, endpoint: str): + logging.info(f'Enabling tracing on {host}, endpoint = {endpoint}') + host.ssh('printf "observer-endpoint-http-enabled=true\nobserver-experimental-components=\\"\\"\n" > /etc/xapi.conf.d/observer.conf') + host.restart_toolstack(verify=True) + observer_uuid = host.xe('observer-create', {'name-label': 'xcpng-test', 'endpoints': endpoint, 'enabled': 'true'}) + host.restart_toolstack(verify=True) + return observer_uuid + +def teardown_tracing(host, observer): + logging.info(f'Disabling tracing on {host}') + host.xe('observer-destroy', {'uuid': observer}) + host.ssh('rm -f /etc/xapi.conf.d/observer.conf') + host.restart_toolstack(verify=True) # fixtures @@ -259,8 +278,20 @@ def cleanup_hosts() -> None: if not host_list: pytest.fail("This test requires at least one --hosts parameter") + + tracing_endpoint = pytestconfig.getoption("--tracing-endpoint") + has_tracing = tracing_endpoint is not None + observers = [] + if has_tracing: + for h in host_list: + observers.append(setup_tracing(h, tracing_endpoint)) + yield host_list + if has_tracing: + for h, o in zip(host_list, observers): + teardown_tracing(h, o) + cleanup_hosts() @pytest.fixture(scope='session') From b8f425d9993df84c53a050712af5f800a0039107 Mon Sep 17 00:00:00 2001 From: Colin James Date: Tue, 12 May 2026 10:53:53 +0100 Subject: [PATCH 2/2] Add tracing test Signed-off-by: Colin James --- tests/misc/test_tracing.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tests/misc/test_tracing.py diff --git a/tests/misc/test_tracing.py b/tests/misc/test_tracing.py new file mode 100644 index 000000000..3e4872d5e --- /dev/null +++ b/tests/misc/test_tracing.py @@ -0,0 +1,45 @@ +import logging +import pytest +import time +import uuid +from urllib.parse import urlparse +import requests + +@pytest.fixture +def tracing_endpoint(request): + endpoint = request.config.getoption("--tracing-endpoint") + if endpoint is None: + pytest.exit("Missing required option: --tracing-endpoint") + return endpoint + +def locate_span(data, operation, tag): + if not data: + return None + + for spans in data: + for span in spans: + if span.get('name') == operation: + if span.get('tags', {}).get('test.tag') == tag: + return span + +def test_tracing(tracing_endpoint, host): + operation = "xe observer-list" + url = urlparse(tracing_endpoint) + api = f"{url.scheme}://{url.netloc}/api/v2/traces" + tag = str(uuid.uuid4()) + logging.info(f"Peforming operation tagged with: {tag}") + o = host.ssh(f'BAGGAGE="test.tag={tag}" {operation}') + params = { "spanName": operation } + + logging.info(f"Querying endpoint to locate our root span") + root_span = None + for i in range(15): + response = requests.get(api, params=params) + data = response.json() + root_span = locate_span(data, operation, tag) + if root_span: + break + time.sleep(5) + + if not root_span: + pytest.fail("Could not find our operation's span in time")