]>
Commit | Line | Data |
---|---|---|
f67539c2 | 1 | import mock |
f67539c2 | 2 | import os |
b3b6e05e | 3 | import pytest |
f67539c2 TL |
4 | import time |
5 | ||
b3b6e05e TL |
6 | from contextlib import contextmanager |
7 | from pyfakefs import fake_filesystem | |
8 | ||
1e59de90 | 9 | from typing import Dict, List, Optional |
b3b6e05e TL |
10 | |
11 | ||
1e59de90 TL |
12 | def import_cephadm(): |
13 | """Import cephadm as a module.""" | |
14 | import cephadm as _cephadm | |
15 | ||
16 | return _cephadm | |
f67539c2 TL |
17 | |
18 | ||
b3b6e05e | 19 | def mock_docker(): |
1e59de90 TL |
20 | _cephadm = import_cephadm() |
21 | docker = mock.Mock(_cephadm.Docker) | |
b3b6e05e TL |
22 | docker.path = '/usr/bin/docker' |
23 | return docker | |
24 | ||
25 | ||
26 | def mock_podman(): | |
1e59de90 TL |
27 | _cephadm = import_cephadm() |
28 | podman = mock.Mock(_cephadm.Podman) | |
b3b6e05e TL |
29 | podman.path = '/usr/bin/podman' |
30 | podman.version = (2, 1, 0) | |
31 | return podman | |
32 | ||
33 | ||
f67539c2 TL |
34 | def _daemon_path(): |
35 | return os.getcwd() | |
36 | ||
37 | ||
33c7a0ef TL |
38 | def mock_bad_firewalld(): |
39 | def raise_bad_firewalld(): | |
40 | raise Exception('Called bad firewalld') | |
1e59de90 TL |
41 | |
42 | _cephadm = import_cephadm() | |
43 | f = mock.Mock(_cephadm.Firewalld) | |
44 | f.enable_service_for = lambda _: raise_bad_firewalld() | |
45 | f.apply_rules = lambda: raise_bad_firewalld() | |
46 | f.open_ports = lambda _: raise_bad_firewalld() | |
47 | ||
33c7a0ef | 48 | |
f67539c2 TL |
49 | def _mock_scrape_host(obj, interval): |
50 | try: | |
51 | raise ValueError("wah") | |
52 | except Exception as e: | |
53 | obj._handle_thread_exception(e, 'host') | |
54 | ||
55 | ||
56 | def _mock_run(obj): | |
57 | t = obj._create_thread(obj._scrape_host_facts, 'host', 5) | |
58 | time.sleep(1) | |
59 | if not t.is_alive(): | |
60 | obj.cephadm_cache.update_health('host', "inactive", "host thread stopped") | |
b3b6e05e TL |
61 | |
62 | ||
63 | @pytest.fixture() | |
64 | def cephadm_fs( | |
65 | fs: fake_filesystem.FakeFilesystem, | |
66 | ): | |
67 | """ | |
68 | use pyfakefs to stub filesystem calls | |
69 | """ | |
70 | uid = os.getuid() | |
71 | gid = os.getgid() | |
72 | ||
aee94f69 TL |
73 | def fchown(fd, _uid, _gid): |
74 | """pyfakefs doesn't provide a working fchown or fchmod. | |
75 | In order to get permissions working generally across renames | |
76 | we need to provide our own implemenation. | |
77 | """ | |
78 | file_obj = fs.get_open_file(fd).get_object() | |
79 | file_obj.st_uid = _uid | |
80 | file_obj.st_gid = _gid | |
81 | ||
1e59de90 | 82 | _cephadm = import_cephadm() |
aee94f69 | 83 | with mock.patch('os.fchown', side_effect=fchown), \ |
522d829b TL |
84 | mock.patch('os.fchmod'), \ |
85 | mock.patch('platform.processor', return_value='x86_64'), \ | |
b3b6e05e TL |
86 | mock.patch('cephadm.extract_uid_gid', return_value=(uid, gid)): |
87 | ||
1e59de90 TL |
88 | try: |
89 | if not fake_filesystem.is_root(): | |
90 | fake_filesystem.set_uid(0) | |
91 | except AttributeError: | |
92 | pass | |
93 | ||
94 | fs.create_dir(_cephadm.DATA_DIR) | |
95 | fs.create_dir(_cephadm.LOG_DIR) | |
96 | fs.create_dir(_cephadm.LOCK_DIR) | |
97 | fs.create_dir(_cephadm.LOGROTATE_DIR) | |
98 | fs.create_dir(_cephadm.UNIT_DIR) | |
39ae355f TL |
99 | fs.create_dir('/sys/block') |
100 | ||
101 | yield fs | |
b3b6e05e TL |
102 | |
103 | ||
1e59de90 TL |
104 | @pytest.fixture() |
105 | def host_sysfs(fs: fake_filesystem.FakeFilesystem): | |
106 | """Create a fake filesystem to represent sysfs""" | |
107 | enc_path = '/sys/class/scsi_generic/sg2/device/enclosure/0:0:1:0' | |
108 | dev_path = '/sys/class/scsi_generic/sg2/device' | |
109 | slot_count = 12 | |
110 | fs.create_dir(dev_path) | |
111 | fs.create_file(os.path.join(dev_path, 'vendor'), contents="EnclosuresInc") | |
112 | fs.create_file(os.path.join(dev_path, 'model'), contents="D12") | |
113 | fs.create_file(os.path.join(enc_path, 'id'), contents='1') | |
114 | fs.create_file(os.path.join(enc_path, 'components'), contents=str(slot_count)) | |
115 | for slot_num in range(slot_count): | |
116 | slot_dir = os.path.join(enc_path, str(slot_num)) | |
117 | fs.create_file(os.path.join(slot_dir, 'locate'), contents='0') | |
118 | fs.create_file(os.path.join(slot_dir, 'fault'), contents='0') | |
119 | fs.create_file(os.path.join(slot_dir, 'slot'), contents=str(slot_num)) | |
120 | if slot_num < 6: | |
121 | fs.create_file(os.path.join(slot_dir, 'status'), contents='Ok') | |
122 | slot_dev = os.path.join(slot_dir, 'device') | |
123 | fs.create_dir(slot_dev) | |
124 | fs.create_file(os.path.join(slot_dev, 'vpd_pg80'), contents=f'fake{slot_num:0>3}') | |
125 | else: | |
126 | fs.create_file(os.path.join(slot_dir, 'status'), contents='not installed') | |
127 | ||
128 | yield fs | |
129 | ||
130 | ||
b3b6e05e TL |
131 | @contextmanager |
132 | def with_cephadm_ctx( | |
133 | cmd: List[str], | |
1e59de90 | 134 | list_networks: Optional[Dict[str, Dict[str, List[str]]]] = None, |
b3b6e05e TL |
135 | hostname: Optional[str] = None, |
136 | ): | |
137 | """ | |
138 | :param cmd: cephadm command argv | |
b3b6e05e TL |
139 | :param list_networks: mock 'list-networks' return |
140 | :param hostname: mock 'socket.gethostname' return | |
141 | """ | |
b3b6e05e TL |
142 | if not hostname: |
143 | hostname = 'host1' | |
144 | ||
1e59de90 | 145 | _cephadm = import_cephadm() |
522d829b | 146 | with mock.patch('cephadm.attempt_bind'), \ |
b3b6e05e | 147 | mock.patch('cephadm.call', return_value=('', '', 0)), \ |
522d829b | 148 | mock.patch('cephadm.call_timeout', return_value=0), \ |
b3b6e05e | 149 | mock.patch('cephadm.find_executable', return_value='foo'), \ |
33c7a0ef | 150 | mock.patch('cephadm.get_container_info', return_value=None), \ |
1e59de90 | 151 | mock.patch('cephadm.is_available', return_value=True), \ |
b3b6e05e | 152 | mock.patch('cephadm.json_loads_retry', return_value={'epoch' : 1}), \ |
1e59de90 | 153 | mock.patch('cephadm.logger'), \ |
b3b6e05e | 154 | mock.patch('socket.gethostname', return_value=hostname): |
1e59de90 TL |
155 | ctx: _cephadm.CephadmContext = _cephadm.cephadm_init_ctx(cmd) |
156 | ctx.container_engine = mock_podman() | |
522d829b TL |
157 | if list_networks is not None: |
158 | with mock.patch('cephadm.list_networks', return_value=list_networks): | |
159 | yield ctx | |
160 | else: | |
161 | yield ctx | |
162 |