File: conftest.py

package info (click to toggle)
python-bugzilla 3.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,116 kB
  • sloc: python: 6,160; makefile: 7
file content (163 lines) | stat: -rw-r--r-- 5,580 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.

import locale
import logging
import os
import re

import pytest
import responses

import tests
import tests.utils

import bugzilla


# pytest plugin adding custom options. Hooks are documented here:
# https://docs.pytest.org/en/latest/writing_plugins.html

def pytest_addoption(parser):
    parser.addoption("--ro-integration", action="store_true", default=False,
                     help="Run readonly tests against local Bugzilla instance.")
    parser.addoption("--ro-functional", action="store_true", default=False,
            help=("Run readonly functional tests against actual "
                  "bugzilla instances. This will be very slow."))
    parser.addoption("--rw-functional", action="store_true", default=False,
            help=("Run read/write functional tests against actual bugzilla "
                  "instances. As of now this only runs against "
                  "bugzilla.stage.redhat.com, which requires an RH "
                  "bugzilla account with cached login creds. This will "
                  "also be very slow."))
    parser.addoption("--redhat-url",
            help="Redhat bugzilla URL to use for ro/rw_functional tests")
    parser.addoption("--pybz-debug", action="store_true", default=False,
            help=("Enable python-bugzilla debug output. This may break "
                  "output comparison tests."))
    parser.addoption("--regenerate-output",
            action="store_true", default=False,
            help=("Force regeneration of generated test output"))
    parser.addoption("--only-rest", action="store_true", default=False)
    parser.addoption("--only-xmlrpc", action="store_true", default=False)


def pytest_ignore_collect(collection_path, config):
    has_ro = config.getoption("--ro-functional")
    has_ro_i = config.getoption("--ro-integration")
    has_rw = config.getoption("--rw-functional")

    base = os.path.basename(str(collection_path))
    is_ro = base == "test_ro_functional.py"
    is_ro_i = "tests/integration/ro" in str(collection_path)
    is_rw = base == "test_rw_functional.py"

    if is_ro_i and not has_ro_i:
        return True

    if is_ro and not has_ro:
        return True
    if is_rw and not has_rw:
        return True


def pytest_configure(config):
    # Needed for test reproducibility on any system not using a UTF-8 locale
    locale.setlocale(locale.LC_ALL, "C")
    for loc in ["C.UTF-8", "C.utf8", "UTF-8", "en_US.UTF-8"]:
        try:
            locale.setlocale(locale.LC_CTYPE, loc)
            break
        except locale.Error:
            pass
    else:
        raise locale.Error("No UTF-8 locale found")

    if config.getoption("--redhat-url"):
        tests.CLICONFIG.REDHAT_URL = config.getoption("--redhat-url")
    if config.getoption("--pybz-debug"):
        logging.getLogger(bugzilla.__name__).setLevel(logging.DEBUG)
        os.environ["__BUGZILLA_UNITTEST_DEBUG"] = "1"
    if config.getoption("--regenerate-output"):
        tests.CLICONFIG.REGENERATE_OUTPUT = config.getoption(
            "--regenerate-output")
    if config.getoption("--only-rest"):
        tests.CLICONFIG.ONLY_REST = True
    if config.getoption("--only-xmlrpc"):
        tests.CLICONFIG.ONLY_XMLRPC = True

    if (config.getoption("--ro-functional") or
        config.getoption("--rw-functional")):
        config.option.verbose = 2


def pytest_generate_tests(metafunc):
    """
    If a test requests the 'backends' fixture, run that test with both
    force_rest=True and force_xmlrpc=True Bugzilla options
    """
    if 'backends' in metafunc.fixturenames:
        values = []
        ids = []
        if not tests.CLICONFIG.ONLY_REST:
            values.append({"force_xmlrpc": True})
            ids.append("XMLRPC")
        if not tests.CLICONFIG.ONLY_XMLRPC:
            values.append({"force_rest": True})
            ids.append("REST")
        metafunc.parametrize("backends", values, ids=ids, scope="session")


@pytest.fixture
def run_cli(capsys, monkeypatch):
    """
    Custom pytest fixture to pass a function for testing
    a bugzilla cli command.
    """
    def _do_run(*args, **kwargs):
        return tests.utils.do_run_cli(capsys, monkeypatch, *args, **kwargs)
    return _do_run


@pytest.fixture
def mocked_responses():
    """
    Mock responses

    * Quickly return error responses
    * Pass through requests to live instances
    * Provide an incorrect XMLRPC response
    """
    passthrough = ()
    status_pattern = re.compile(r"https://httpstat.us/(?P<status>\d+).*")

    def status_callback(request):
        match = status_pattern.match(request.url)
        status_code = 400
        if match:
            status_code = int(match.group("status"))

        return status_code, {}, "<html><body><h1>Lorem ipsum</h1></body></html>"

    test_url = os.getenv("BUGZILLA_URL")
    if test_url:
        passthrough += (test_url, )
    with responses.RequestsMock(passthru_prefixes=passthrough,
                                assert_all_requests_are_fired=False) as mock:
        mock.add_callback(
            method=responses.GET,
            url=status_pattern,
            callback=status_callback
        )
        mock.add_callback(
            method=responses.POST,
            url=status_pattern,
            callback=status_callback
        )
        mock.add(
            method=responses.POST,
            url="https://example.com/#xmlrpc",
            status=200,
            body="This is no XML"
        )
        yield mock