summaryrefslogtreecommitdiffstats
path: root/src/cephadm/tests/fixtures.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/cephadm/tests/fixtures.py')
-rw-r--r--src/cephadm/tests/fixtures.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/cephadm/tests/fixtures.py b/src/cephadm/tests/fixtures.py
new file mode 100644
index 000000000..76ac0b44c
--- /dev/null
+++ b/src/cephadm/tests/fixtures.py
@@ -0,0 +1,162 @@
+import mock
+import os
+import pytest
+import time
+
+from contextlib import contextmanager
+from pyfakefs import fake_filesystem
+
+from typing import Dict, List, Optional
+
+
+def import_cephadm():
+ """Import cephadm as a module."""
+ import cephadm as _cephadm
+
+ return _cephadm
+
+
+def mock_docker():
+ _cephadm = import_cephadm()
+ docker = mock.Mock(_cephadm.Docker)
+ docker.path = '/usr/bin/docker'
+ return docker
+
+
+def mock_podman():
+ _cephadm = import_cephadm()
+ podman = mock.Mock(_cephadm.Podman)
+ podman.path = '/usr/bin/podman'
+ podman.version = (2, 1, 0)
+ return podman
+
+
+def _daemon_path():
+ return os.getcwd()
+
+
+def mock_bad_firewalld():
+ def raise_bad_firewalld():
+ raise Exception('Called bad firewalld')
+
+ _cephadm = import_cephadm()
+ f = mock.Mock(_cephadm.Firewalld)
+ f.enable_service_for = lambda _: raise_bad_firewalld()
+ f.apply_rules = lambda: raise_bad_firewalld()
+ f.open_ports = lambda _: raise_bad_firewalld()
+
+
+def _mock_scrape_host(obj, interval):
+ try:
+ raise ValueError("wah")
+ except Exception as e:
+ obj._handle_thread_exception(e, 'host')
+
+
+def _mock_run(obj):
+ t = obj._create_thread(obj._scrape_host_facts, 'host', 5)
+ time.sleep(1)
+ if not t.is_alive():
+ obj.cephadm_cache.update_health('host', "inactive", "host thread stopped")
+
+
+@pytest.fixture()
+def cephadm_fs(
+ fs: fake_filesystem.FakeFilesystem,
+):
+ """
+ use pyfakefs to stub filesystem calls
+ """
+ uid = os.getuid()
+ gid = os.getgid()
+
+ def fchown(fd, _uid, _gid):
+ """pyfakefs doesn't provide a working fchown or fchmod.
+ In order to get permissions working generally across renames
+ we need to provide our own implemenation.
+ """
+ file_obj = fs.get_open_file(fd).get_object()
+ file_obj.st_uid = _uid
+ file_obj.st_gid = _gid
+
+ _cephadm = import_cephadm()
+ with mock.patch('os.fchown', side_effect=fchown), \
+ mock.patch('os.fchmod'), \
+ mock.patch('platform.processor', return_value='x86_64'), \
+ mock.patch('cephadm.extract_uid_gid', return_value=(uid, gid)):
+
+ try:
+ if not fake_filesystem.is_root():
+ fake_filesystem.set_uid(0)
+ except AttributeError:
+ pass
+
+ fs.create_dir(_cephadm.DATA_DIR)
+ fs.create_dir(_cephadm.LOG_DIR)
+ fs.create_dir(_cephadm.LOCK_DIR)
+ fs.create_dir(_cephadm.LOGROTATE_DIR)
+ fs.create_dir(_cephadm.UNIT_DIR)
+ fs.create_dir('/sys/block')
+
+ yield fs
+
+
+@pytest.fixture()
+def host_sysfs(fs: fake_filesystem.FakeFilesystem):
+ """Create a fake filesystem to represent sysfs"""
+ enc_path = '/sys/class/scsi_generic/sg2/device/enclosure/0:0:1:0'
+ dev_path = '/sys/class/scsi_generic/sg2/device'
+ slot_count = 12
+ fs.create_dir(dev_path)
+ fs.create_file(os.path.join(dev_path, 'vendor'), contents="EnclosuresInc")
+ fs.create_file(os.path.join(dev_path, 'model'), contents="D12")
+ fs.create_file(os.path.join(enc_path, 'id'), contents='1')
+ fs.create_file(os.path.join(enc_path, 'components'), contents=str(slot_count))
+ for slot_num in range(slot_count):
+ slot_dir = os.path.join(enc_path, str(slot_num))
+ fs.create_file(os.path.join(slot_dir, 'locate'), contents='0')
+ fs.create_file(os.path.join(slot_dir, 'fault'), contents='0')
+ fs.create_file(os.path.join(slot_dir, 'slot'), contents=str(slot_num))
+ if slot_num < 6:
+ fs.create_file(os.path.join(slot_dir, 'status'), contents='Ok')
+ slot_dev = os.path.join(slot_dir, 'device')
+ fs.create_dir(slot_dev)
+ fs.create_file(os.path.join(slot_dev, 'vpd_pg80'), contents=f'fake{slot_num:0>3}')
+ else:
+ fs.create_file(os.path.join(slot_dir, 'status'), contents='not installed')
+
+ yield fs
+
+
+@contextmanager
+def with_cephadm_ctx(
+ cmd: List[str],
+ list_networks: Optional[Dict[str, Dict[str, List[str]]]] = None,
+ hostname: Optional[str] = None,
+):
+ """
+ :param cmd: cephadm command argv
+ :param list_networks: mock 'list-networks' return
+ :param hostname: mock 'socket.gethostname' return
+ """
+ if not hostname:
+ hostname = 'host1'
+
+ _cephadm = import_cephadm()
+ with mock.patch('cephadm.attempt_bind'), \
+ mock.patch('cephadm.call', return_value=('', '', 0)), \
+ mock.patch('cephadm.call_timeout', return_value=0), \
+ mock.patch('cephadm.find_executable', return_value='foo'), \
+ mock.patch('cephadm.get_container_info', return_value=None), \
+ mock.patch('cephadm.is_available', return_value=True), \
+ mock.patch('cephadm.json_loads_retry', return_value={'epoch' : 1}), \
+ mock.patch('cephadm.logger'), \
+ mock.patch('socket.gethostname', return_value=hostname):
+ ctx: _cephadm.CephadmContext = _cephadm.cephadm_init_ctx(cmd)
+ ctx.container_engine = mock_podman()
+ if list_networks is not None:
+ with mock.patch('cephadm.list_networks', return_value=list_networks):
+ yield ctx
+ else:
+ yield ctx
+