blob: a91261bb857aaf6dbbfe1ce65b3aeb808d649ff8 [file] [log] [blame]
Chris McDonald2e9a09c2020-04-03 16:09:32 -06001# -*- coding: utf-8 -*-
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Configuration and fixtures for pytest.
7
8See the following doc link for an explanation of conftest.py and how it is used
9by pytest:
10https://docs.pytest.org/en/latest/fixture.html#conftest-py-sharing-fixture-functions
11"""
12
13from __future__ import print_function
14
Chris McDonaldffe2a412020-04-15 02:27:25 -060015import multiprocessing
16
Chris McDonaldee2fbda2020-04-30 18:10:01 -060017import pytest
Chris McDonald2e9a09c2020-04-03 16:09:32 -060018
19from chromite.lib import cidb
Chris McDonald320ef422020-04-18 04:57:04 -060020from chromite.lib import parallel
Chris McDonald6ce00962020-04-14 04:05:21 -060021from chromite.lib import retry_stats
Chris McDonald2e9a09c2020-04-03 16:09:32 -060022
Chris McDonaldee2fbda2020-04-30 18:10:01 -060023# We use wildcard imports here to make fixtures defined in the test module
24# globally visible.
25# pylint: disable=unused-wildcard-import, wildcard-import
26
27# Importing from *_fixtures.py files into conftest.py is the only time a
28# module should use a wildcard import. *_fixtures.py files should ensure
29# that the only items visible to a wildcard import are pytest fixtures,
30# usually by declaring __all__ if necessary.
31from chromite.test.portage_fixtures import *
32
Chris McDonald2e9a09c2020-04-03 16:09:32 -060033
Chris McDonalde53dde12020-04-07 13:43:14 -060034@pytest.fixture(scope='class', autouse=True)
Chris McDonald2e9a09c2020-04-03 16:09:32 -060035def mock_cidb_connection():
36 """Ensure that the CIDB connection factory is initialized as a mock.
37
38 Unit tests should never connect to any live instances of CIDB and this
39 initialization ensures that they only ever get a mock connection instance.
40
41 Previously cros_test_lib.TestProgram.runTests was responsible for globally
42 initializing this mock and multiple tests are flaky if this mock connection
43 is not initialized before any tests are run.
44 """
Chris McDonalde53dde12020-04-07 13:43:14 -060045 # pylint: disable=protected-access
46 cidb.CIDBConnectionFactory._ClearCIDBSetup()
Chris McDonald2e9a09c2020-04-03 16:09:32 -060047 cidb.CIDBConnectionFactory.SetupMockCidb()
Chris McDonaldffe2a412020-04-15 02:27:25 -060048
49
50@pytest.fixture(scope='class', autouse=True)
51def assert_no_zombies():
52 """Assert that tests have no active child processes after completion.
53
54 This assertion runs after class tearDown methods because of the scope='class'
55 declaration.
56 """
57 yield
58 children = multiprocessing.active_children()
59 if children:
60 pytest.fail('Test has %s active child processes after tearDown: %s' %
61 (len(children), children))
Chris McDonalde13f0242020-04-07 18:37:15 -060062
63
Chris McDonald6ce00962020-04-14 04:05:21 -060064@pytest.fixture(scope='class', autouse=True)
65def clear_retry_stats_manager():
66 """Reset the global state of the stats manager before every test.
67
68 Without this fixture many tests fail due to this global value being set and
69 then not cleared. The child manager process may have been killed but this
70 module level variable is still pointing at it, leading to the test trying to
71 write to a closed pipe.
72 """
73 # pylint: disable=protected-access
74 retry_stats._STATS_COLLECTION = None
75
76
Chris McDonalde13f0242020-04-07 18:37:15 -060077@pytest.fixture
Chris McDonald320ef422020-04-18 04:57:04 -060078def singleton_manager(monkeypatch):
79 """Force tests to use a singleton Manager and automatically clean it up."""
80 m = parallel.Manager()
81
82 def our_manager():
83 return m
84
85 monkeypatch.setattr(parallel, 'Manager', our_manager)
86 yield
87 m.shutdown()
88
89
90@pytest.fixture
Chris McDonalde13f0242020-04-07 18:37:15 -060091def legacy_capture_output(request, capfd):
92 """Adds the `capfd` fixture to TestCase-style test classes.
93
94 This fixture should only be used on cros_test_lib.TestCase test classes, since
95 it doesn't yield anything and just attaches the built-in pytest `capfd`
96 fixture to the requesting class. Tests written as standalone functions should
97 use pytest's built-in `capfd` fixture instead of this. See the documentation
98 for more information on how to use the `capfd` fixture that this provides:
99 https://docs.pytest.org/en/latest/reference.html#capfd
100
101 See the following documentation for an explanation of why fixtures have to be
102 provided to TestCase classes in this manner:
103 https://docs.pytest.org/en/latest/unittest.html#mixing-pytest-fixtures-into-unittest-testcase-subclasses-using-marks
104 """
105 request.cls.capfd = capfd
Chris McDonald6ce00962020-04-14 04:05:21 -0600106
107
108@pytest.fixture
109def testcase_caplog(request, caplog):
110 """Adds the `caplog` fixture to TestCase-style test classes.
111
112 This fixture should only be used on cros_test_lib.TestCase test classes, since
113 it doesn't yield anything and just attaches the built-in pytest `caplog`
114 fixture to the requesting class. Tests written as standalone functions should
115 use pytest's built-in `caplog` fixture instead of this. See the documentation
116 for more information on how to use the `caplog` fixture that this provides:
117 https://docs.pytest.org/en/latest/reference.html#caplog
118
119 See the following documentation for an explanation of why fixtures have to be
120 provided to TestCase classes in this manner:
121 https://docs.pytest.org/en/latest/unittest.html#mixing-pytest-fixtures-into-unittest-testcase-subclasses-using-marks
122 """
123 request.cls.caplog = caplog