summaryrefslogtreecommitdiff
path: root/conftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'conftest.py')
-rw-r--r--conftest.py116
1 files changed, 102 insertions, 14 deletions
diff --git a/conftest.py b/conftest.py
index faf13804..76e9000a 100644
--- a/conftest.py
+++ b/conftest.py
@@ -1,24 +1,64 @@
+import os
from unittest import mock
import pytest
+import httpretty as _httpretty
-from cloudinit import subp
+from cloudinit import helpers, subp
-def _closest_marker_args_or(request, marker_name: str, default):
- """Get the args for the closest ``marker_name`` or return ``default``"""
- try:
- marker = request.node.get_closest_marker(marker_name)
- except AttributeError:
- # Older versions of pytest don't have the new API
- marker = request.node.get_marker(marker_name)
- if marker is not None:
- return marker.args
- return default
+class _FixtureUtils:
+ """A namespace for fixture helper functions, used by fixture_utils.
+
+ These helper functions are all defined as staticmethods so they are
+ effectively functions; they are defined in a class only to give us a
+ namespace so calling them can look like
+ ``fixture_utils.fixture_util_function()`` in test code.
+ """
+
+ @staticmethod
+ def closest_marker_args_or(request, marker_name: str, default):
+ """Get the args for closest ``marker_name`` or return ``default``
+
+ :param request:
+ A pytest request, as passed to a fixture.
+ :param marker_name:
+ The name of the marker to look for
+ :param default:
+ The value to return if ``marker_name`` is not found.
+
+ :return:
+ The args for the closest ``marker_name`` marker, or ``default``
+ if no such marker is found.
+ """
+ try:
+ marker = request.node.get_closest_marker(marker_name)
+ except AttributeError:
+ # Older versions of pytest don't have the new API
+ marker = request.node.get_marker(marker_name)
+ if marker is not None:
+ return marker.args
+ return default
+
+ @staticmethod
+ def closest_marker_first_arg_or(request, marker_name: str, default):
+ """Get the first arg for closest ``marker_name`` or return ``default``
+
+ This is a convenience wrapper around closest_marker_args_or, see there
+ for full details.
+ """
+ result = _FixtureUtils.closest_marker_args_or(
+ request, marker_name, [default]
+ )
+ if not result:
+ raise TypeError(
+ "Missing expected argument to {} marker".format(marker_name)
+ )
+ return result[0]
@pytest.yield_fixture(autouse=True)
-def disable_subp_usage(request):
+def disable_subp_usage(request, fixture_utils):
"""
Across all (pytest) tests, ensure that subp.subp is not invoked.
@@ -53,10 +93,14 @@ def disable_subp_usage(request):
tests, CiTestCase's allowed_subp does take precedence (and we have
TestDisableSubpUsageInTestSubclass to confirm that).
"""
- allow_subp_for = _closest_marker_args_or(request, "allow_subp_for", None)
+ allow_subp_for = fixture_utils.closest_marker_args_or(
+ request, "allow_subp_for", None
+ )
# Because the mark doesn't take arguments, `allow_all_subp` will be set to
# [] if the marker is present, so explicit None checks are required
- allow_all_subp = _closest_marker_args_or(request, "allow_all_subp", None)
+ allow_all_subp = fixture_utils.closest_marker_args_or(
+ request, "allow_all_subp", None
+ )
if allow_all_subp is not None and allow_subp_for is None:
# Only allow_all_subp specified, don't mock subp.subp
@@ -93,3 +137,47 @@ def disable_subp_usage(request):
with mock.patch("cloudinit.subp.subp", autospec=True) as m_subp:
m_subp.side_effect = side_effect
yield
+
+
+@pytest.fixture(scope="session")
+def fixture_utils():
+ """Return a namespace containing fixture utility functions.
+
+ See :py:class:`_FixtureUtils` for further details."""
+ return _FixtureUtils
+
+
+@pytest.yield_fixture
+def httpretty():
+ """
+ Enable HTTPretty for duration of the testcase, resetting before and after.
+
+ This will also ensure allow_net_connect is set to False, and temporarily
+ unset http_proxy in os.environ if present (to work around
+ https://github.com/gabrielfalcao/HTTPretty/issues/122).
+ """
+ restore_proxy = os.environ.pop("http_proxy", None)
+ _httpretty.HTTPretty.allow_net_connect = False
+ _httpretty.reset()
+ _httpretty.enable()
+
+ yield _httpretty
+
+ _httpretty.disable()
+ _httpretty.reset()
+ if restore_proxy is not None:
+ os.environ["http_proxy"] = restore_proxy
+
+
+@pytest.fixture
+def paths(tmpdir):
+ """
+ Return a helpers.Paths object configured to use a tmpdir.
+
+ (This uses the builtin tmpdir fixture.)
+ """
+ dirs = {
+ "cloud_dir": tmpdir.mkdir("cloud_dir").strpath,
+ "run_dir": tmpdir.mkdir("run_dir").strpath,
+ }
+ return helpers.Paths(dirs)