diff options
Diffstat (limited to 'src/pybind/mgr/orchestrator/tests')
-rw-r--r-- | src/pybind/mgr/orchestrator/tests/__init__.py | 0 | ||||
-rw-r--r-- | src/pybind/mgr/orchestrator/tests/test_orchestrator.py | 220 |
2 files changed, 220 insertions, 0 deletions
diff --git a/src/pybind/mgr/orchestrator/tests/__init__.py b/src/pybind/mgr/orchestrator/tests/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/pybind/mgr/orchestrator/tests/__init__.py diff --git a/src/pybind/mgr/orchestrator/tests/test_orchestrator.py b/src/pybind/mgr/orchestrator/tests/test_orchestrator.py new file mode 100644 index 000000000..7fe32e559 --- /dev/null +++ b/src/pybind/mgr/orchestrator/tests/test_orchestrator.py @@ -0,0 +1,220 @@ +from __future__ import absolute_import + +import json +import textwrap + +import pytest +import yaml + +from ceph.deployment.service_spec import ServiceSpec +from ceph.deployment import inventory +from ceph.utils import datetime_now +from mgr_module import HandleCommandResult + +from test_orchestrator import TestOrchestrator as _TestOrchestrator + +from orchestrator import InventoryHost, DaemonDescription, ServiceDescription, DaemonDescriptionStatus, OrchResult +from orchestrator import OrchestratorValidationError +from orchestrator.module import to_format, Format, OrchestratorCli, preview_table_osd +from unittest import mock + + +def _test_resource(data, resource_class, extra=None): + # ensure we can deserialize and serialize + rsc = resource_class.from_json(data) + assert rsc.to_json() == resource_class.from_json(rsc.to_json()).to_json() + + if extra: + # if there is an unexpected data provided + data_copy = data.copy() + data_copy.update(extra) + with pytest.raises(OrchestratorValidationError): + resource_class.from_json(data_copy) + + +def test_inventory(): + json_data = { + 'name': 'host0', + 'addr': '1.2.3.4', + 'devices': [ + { + 'sys_api': { + 'rotational': '1', + 'size': 1024, + }, + 'path': '/dev/sda', + 'available': False, + 'rejected_reasons': [], + 'lvs': [] + } + ] + } + _test_resource(json_data, InventoryHost, {'abc': False}) + for devices in json_data['devices']: + _test_resource(devices, inventory.Device) + + json_data = [{}, {'name': 'host0', 'addr': '1.2.3.4'}, {'devices': []}] + for data in json_data: + with pytest.raises(OrchestratorValidationError): + InventoryHost.from_json(data) + + +def test_daemon_description(): + json_data = { + 'hostname': 'test', + 'daemon_type': 'mon', + 'daemon_id': 'a', + 'status': -1, + } + _test_resource(json_data, DaemonDescription, {'abc': False}) + + dd = DaemonDescription.from_json(json_data) + assert dd.status.value == DaemonDescriptionStatus.error.value + + +def test_apply(): + to = _TestOrchestrator('', 0, 0) + completion = to.apply([ + ServiceSpec(service_type='nfs', service_id='foo'), + ServiceSpec(service_type='nfs', service_id='foo'), + ServiceSpec(service_type='nfs', service_id='foo'), + ]) + res = '<NFSServiceSpec for service_name=nfs.foo>' + assert completion.result == [res, res, res] + + +def test_yaml(): + y = """daemon_type: crash +daemon_id: ubuntu +daemon_name: crash.ubuntu +hostname: ubuntu +status: 1 +status_desc: starting +is_active: false +events: +- 2020-06-10T10:08:22.933241Z daemon:crash.ubuntu [INFO] "Deployed crash.ubuntu on + host 'ubuntu'" +--- +service_type: crash +service_name: crash +placement: + host_pattern: '*' +status: + container_image_id: 74803e884bea289d2d2d3ebdf6d37cd560499e955595695b1390a89800f4e37a + container_image_name: docker.io/ceph/daemon-base:latest-master-devel + created: '2020-06-10T10:37:31.051288Z' + last_refresh: '2020-06-10T10:57:40.715637Z' + running: 1 + size: 1 +events: +- 2020-06-10T10:37:31.139159Z service:crash [INFO] "service was created" +""" + types = (DaemonDescription, ServiceDescription) + + for y, cls in zip(y.split('---\n'), types): + data = yaml.safe_load(y) + object = cls.from_json(data) + + assert to_format(object, Format.yaml, False, cls) == y + assert to_format([object], Format.yaml, True, cls) == y + + j = json.loads(to_format(object, Format.json, False, cls)) + assert to_format(cls.from_json(j), Format.yaml, False, cls) == y + + +def test_event_multiline(): + from .._interface import OrchestratorEvent + e = OrchestratorEvent(datetime_now(), 'service', 'subject', 'ERROR', 'message') + assert OrchestratorEvent.from_json(e.to_json()) == e + + e = OrchestratorEvent(datetime_now(), 'service', + 'subject', 'ERROR', 'multiline\nmessage') + assert OrchestratorEvent.from_json(e.to_json()) == e + + +def test_handle_command(): + cmd = { + 'prefix': 'orch daemon add', + 'daemon_type': 'mon', + 'placement': 'smithi044:[v2:172.21.15.44:3301,v1:172.21.15.44:6790]=c', + } + m = OrchestratorCli('orchestrator', 0, 0) + r = m._handle_command(None, cmd) + assert r == HandleCommandResult( + retval=-2, stdout='', stderr='No orchestrator configured (try `ceph orch set backend`)') + + +r = OrchResult([ServiceDescription(spec=ServiceSpec(service_type='osd'), running=123)]) + + +@mock.patch("orchestrator.OrchestratorCli.describe_service", return_value=r) +def test_orch_ls(_describe_service): + cmd = { + 'prefix': 'orch ls', + } + m = OrchestratorCli('orchestrator', 0, 0) + r = m._handle_command(None, cmd) + out = 'NAME PORTS RUNNING REFRESHED AGE PLACEMENT \n' \ + 'osd 123 - - ' + assert r == HandleCommandResult(retval=0, stdout=out, stderr='') + + cmd = { + 'prefix': 'orch ls', + 'format': 'yaml', + } + m = OrchestratorCli('orchestrator', 0, 0) + r = m._handle_command(None, cmd) + out = textwrap.dedent(""" + service_type: osd + service_name: osd + spec: + filter_logic: AND + objectstore: bluestore + status: + running: 123 + size: 0 + """).lstrip() + assert r == HandleCommandResult(retval=0, stdout=out, stderr='') + + +def test_preview_table_osd_smoke(): + data = [ + { + 'service_type': 'osd', + 'data': + { + 'foo host': + [ + { + 'osdspec': 'foo', + 'error': '', + 'data': + [ + { + "block_db": "/dev/nvme0n1", + "block_db_size": "66.67 GB", + "data": "/dev/sdb", + "data_size": "300.00 GB", + "encryption": "None" + }, + { + "block_db": "/dev/nvme0n1", + "block_db_size": "66.67 GB", + "data": "/dev/sdc", + "data_size": "300.00 GB", + "encryption": "None" + }, + { + "block_db": "/dev/nvme0n1", + "block_db_size": "66.67 GB", + "data": "/dev/sdd", + "data_size": "300.00 GB", + "encryption": "None" + } + ] + } + ] + } + } + ] + preview_table_osd(data) |