blob: 88ce8cfc0714d51a00adfeab27f3fa3e0ef46d9a [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 McDonalde53dde12020-04-07 13:43:14 -060017import pytest # pylint: disable=import-error
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 McDonald2e9a09c2020-04-03 16:09:32 -060021
22
Chris McDonalde53dde12020-04-07 13:43:14 -060023@pytest.fixture(scope='class', autouse=True)
Chris McDonald2e9a09c2020-04-03 16:09:32 -060024def mock_cidb_connection():
25 """Ensure that the CIDB connection factory is initialized as a mock.
26
27 Unit tests should never connect to any live instances of CIDB and this
28 initialization ensures that they only ever get a mock connection instance.
29
30 Previously cros_test_lib.TestProgram.runTests was responsible for globally
31 initializing this mock and multiple tests are flaky if this mock connection
32 is not initialized before any tests are run.
33 """
Chris McDonalde53dde12020-04-07 13:43:14 -060034 # pylint: disable=protected-access
35 cidb.CIDBConnectionFactory._ClearCIDBSetup()
Chris McDonald2e9a09c2020-04-03 16:09:32 -060036 cidb.CIDBConnectionFactory.SetupMockCidb()
Chris McDonaldffe2a412020-04-15 02:27:25 -060037
38
39@pytest.fixture(scope='class', autouse=True)
40def assert_no_zombies():
41 """Assert that tests have no active child processes after completion.
42
43 This assertion runs after class tearDown methods because of the scope='class'
44 declaration.
45 """
46 yield
47 children = multiprocessing.active_children()
48 if children:
49 pytest.fail('Test has %s active child processes after tearDown: %s' %
50 (len(children), children))
Chris McDonalde13f0242020-04-07 18:37:15 -060051
52
53@pytest.fixture
Chris McDonald320ef422020-04-18 04:57:04 -060054def singleton_manager(monkeypatch):
55 """Force tests to use a singleton Manager and automatically clean it up."""
56 m = parallel.Manager()
57
58 def our_manager():
59 return m
60
61 monkeypatch.setattr(parallel, 'Manager', our_manager)
62 yield
63 m.shutdown()
64
65
66@pytest.fixture
Chris McDonalde13f0242020-04-07 18:37:15 -060067def legacy_capture_output(request, capfd):
68 """Adds the `capfd` fixture to TestCase-style test classes.
69
70 This fixture should only be used on cros_test_lib.TestCase test classes, since
71 it doesn't yield anything and just attaches the built-in pytest `capfd`
72 fixture to the requesting class. Tests written as standalone functions should
73 use pytest's built-in `capfd` fixture instead of this. See the documentation
74 for more information on how to use the `capfd` fixture that this provides:
75 https://docs.pytest.org/en/latest/reference.html#capfd
76
77 See the following documentation for an explanation of why fixtures have to be
78 provided to TestCase classes in this manner:
79 https://docs.pytest.org/en/latest/unittest.html#mixing-pytest-fixtures-into-unittest-testcase-subclasses-using-marks
80 """
81 request.cls.capfd = capfd