File: conftest.py

package info (click to toggle)
lexicon 3.21.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 72,688 kB
  • sloc: python: 20,075; sh: 94; makefile: 7
file content (145 lines) | stat: -rw-r--r-- 4,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import importlib
import pkgutil
from argparse import ArgumentParser
from re import Pattern
from types import ModuleType
from typing import List, Union, cast
from unittest import mock

import pytest


def pytest_addoption(parser):
    """Standard pytest hook invoked to add options to pytest CLI"""
    parser.addoption(
        "--xfail-providers-with-missing-deps",
        action="store_true",
        help="Skip tests on providers with optional dependencies",
    )


def pytest_runtest_setup(item):
    """Standard pytest hook invoked before each test execution"""
    try:
        skip_providers_with_optdeps = getattr(
            item.config.option, "xfail_providers_with_missing_deps"
        )
    except AttributeError:
        pass
    else:
        if skip_providers_with_optdeps:
            from lexicon._private.discovery import find_providers

            providers = find_providers()
            skip = [
                available
                for provider, available in providers.items()
                if provider in item.parent.name.lower()
            ]
            if skip and not skip[0]:
                pytest.xfail(
                    "Test expected to fail because --skip-providers-with-missing-deps "
                    "is set and provider has missing required dependencies."
                )


@pytest.fixture(scope="session")
def mock_provider():
    """
    Create a fake provider module, and mock relevant
    functions to make it appear as a real module.
    """
    from lexicon.interfaces import Provider as BaseProvider

    class Provider(BaseProvider):
        """
        Fake provider to simulate the provider resolution from configuration,
        and to have execution traces when lexicon client is invoked
        """

        @staticmethod
        def get_nameservers() -> Union[List[str], List[Pattern]]:
            return cast(List[str], [])

        @staticmethod
        def configure_parser(parser: ArgumentParser) -> None:
            pass

        def authenticate(self):
            print("Authenticate action")

        def create_record(self, rtype, name, content):
            return {
                "action": "create",
                "domain": self.domain,
                "type": rtype,
                "name": name,
                "content": content,
            }

        def list_records(self, rtype=None, name=None, content=None):
            return {
                "action": "list",
                "domain": self.domain,
                "type": rtype,
                "name": name,
                "content": content,
            }

        def update_record(self, identifier=None, rtype=None, name=None, content=None):
            return {
                "action": "update",
                "domain": self.domain,
                "identifier": identifier,
                "type": rtype,
                "name": name,
                "content": content,
            }

        def delete_record(self, identifier=None, rtype=None, name=None, content=None):
            return {
                "action": "delete",
                "domain": self.domain,
                "identifier": identifier,
                "type": rtype,
                "name": name,
                "content": content,
            }

        def _request(self, action="GET", url="/", data=None, query_params=None):
            # Not use for tests
            pass

    original_iter = pkgutil.iter_modules
    original_import = importlib.import_module

    with mock.patch("lexicon._private.discovery.pkgutil.iter_modules") as mock_iter:
        with mock.patch(
            "lexicon._private.discovery.importlib.import_module"
        ) as mock_import:

            def return_iter(path):
                """
                This will include an adhoc fakeprovider module
                to the normal return of pkgutil.iter_modules.
                """
                modules = list(original_iter(path))
                modules.append((None, "fakeprovider", None))
                return modules

            mock_iter.side_effect = return_iter

            def return_import(module_name):
                """
                This will return a adhoc fakeprovider module if necessary,
                or fallback to the normal return of importlib.import_module.
                """
                if module_name == "lexicon._private.providers.fakeprovider":
                    module = ModuleType("lexicon._private.providers.fakeprovider")
                    setattr(module, "Provider", Provider)
                    return module
                return original_import(module_name)

            mock_import.side_effect = return_import

            yield