diff --git a/docs/api.md b/docs/api.md index 8a5ba56..bae1828 100644 --- a/docs/api.md +++ b/docs/api.md @@ -24,6 +24,10 @@ ::: pytest_client_tools.test_config.TestConfig +## `Inventory` + +::: pytest_client_tools.inventory.Inventory + ## `Version` ::: pytest_client_tools.util.Version diff --git a/docs/fixtures.md b/docs/fixtures.md index 178d44b..8b556c5 100644 --- a/docs/fixtures.md +++ b/docs/fixtures.md @@ -135,3 +135,20 @@ This fixture provides the configuration used for the tests. The type of the fixture is the [`TestConfig`][pytest_client_tools.test_config.TestConfig] class. +### `external_inventory` + +This fixture signals that the test needs to connect to the Insights Inventory +server according to the details (e.g. the `insights.base_url` key) in the +configuration. + +The type of the fixture is the [`Inventory`][pytest_client_tools.inventory.Inventory] +class. + +This fixture has a "session" scope. + +Since the Inventory service is what `insights-client` uses, this fixture may be +used only when the `external_candlepin` fixture is used. Also, certain methods +of the fixture (e.g. `this_system()`) require the `insights_client` fixture. + +The usage of this fixture to a test automatically adds a `external_inventory` +marker to that test. diff --git a/pytest_client_tools/inventory.py b/pytest_client_tools/inventory.py new file mode 100644 index 0000000..0c2d2af --- /dev/null +++ b/pytest_client_tools/inventory.py @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: Red Hat +# SPDX-License-Identifier: MIT + +from .restclient import RestClient + + +class Inventory: + """ + Inventory + + This class represents an Inventory server. + """ + + def __init__(self, base_url, verify=True, request=None): + self._rest_client = RestClient( + base_url=base_url, + verify=verify, + cert=( + "/etc/pki/consumer/cert.pem", + "/etc/pki/consumer/key.pem", + ), + ) + self._request = request + + @property + def base_url(self): + """ + The base URL of the Inventory server. + """ + return self._rest_client.base_url + + def get(self, path, **kwargs): + """ + Perform a GET REST call. + """ + return self._rest_client.get(path, **kwargs) + + def this_system(self): + """ + Query Inventory for the current system. + + This assumes the current system is already registered with + `insights-client`. Raises `SystemNotRegisteredError` if the system + is not registered. + + :return: The dict of the current system in Inventory + :rtype: dict + """ + if not self._request: + raise RuntimeError( + "Inventory.this_system(): cannot invoke without a pytest request set" + ) + insights_client = self._request.getfixturevalue("insights_client") + path = f"hosts?insights_id={insights_client.uuid}" + res_json = self.get(path).json() + if res_json["total"] != 1: + raise RuntimeError( + f"Inventory.this_system(): {res_json['total']} hosts returned " + f"for the current UUID ({insights_client.uuid})" + ) + return res_json["results"][0] diff --git a/pytest_client_tools/plugin.py b/pytest_client_tools/plugin.py index c997c5c..ed7898e 100644 --- a/pytest_client_tools/plugin.py +++ b/pytest_client_tools/plugin.py @@ -11,6 +11,7 @@ import pytest from .candlepin import Candlepin, ping_candlepin +from .inventory import Inventory from .insights_client import InsightsClient, INSIGHTS_CLIENT_FILES_TO_SAVE from .logger import LOGGER from .podman import Podman @@ -31,6 +32,7 @@ "subman": "tests for subscription-manager", "insights_client": "tests for insights-client", "rhc": "tests for rhc", + "external_inventory": "tests requiring an external Inventory service", } _CANDLEPIN_FIXTURES = {x for x in _MARKERS.keys() if "candlepin" in x} @@ -230,6 +232,26 @@ def rhc(save_rhc_files, test_config): rhc.disconnect() +@pytest.fixture(scope="session") +def external_inventory(request, test_config): + external_candlepin = request.getfixturevalue("external_candlepin") + if not external_candlepin: + pytest.skip("missing 'external_candlepin' fixture") + # get the CA path: if it is non-empty, then it means that + # the specified path enforces the SSL validation + verify = test_config.get("insights", "ca_path") + if not verify: + # empty/unset CA path: get whether verify the SSL connection + # using the system CA store + verify = not test_config.get("insights", "insecure") + inventory = Inventory( + base_url=test_config.get("insights", "base_url") + "/inventory/v1", + verify=verify, + request=request, + ) + yield inventory + + def pytest_addoption(parser): group = parser.getgroup("client-tools") group.addoption(