]> git.proxmox.com Git - ceph.git/blame - ceph/src/cephadm/tests/fixtures.py
update ceph source to reef 18.2.1
[ceph.git] / ceph / src / cephadm / tests / fixtures.py
CommitLineData
f67539c2 1import mock
f67539c2 2import os
b3b6e05e 3import pytest
f67539c2
TL
4import time
5
b3b6e05e
TL
6from contextlib import contextmanager
7from pyfakefs import fake_filesystem
8
1e59de90 9from typing import Dict, List, Optional
b3b6e05e
TL
10
11
1e59de90
TL
12def import_cephadm():
13 """Import cephadm as a module."""
14 import cephadm as _cephadm
15
16 return _cephadm
f67539c2
TL
17
18
b3b6e05e 19def 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
26def 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
34def _daemon_path():
35 return os.getcwd()
36
37
33c7a0ef
TL
38def 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
49def _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
56def _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()
64def 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()
105def 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
132def 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