diff options
Diffstat (limited to 'src/pybind/mgr/ansible/tests/test_output_wizards.py')
-rw-r--r-- | src/pybind/mgr/ansible/tests/test_output_wizards.py | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/pybind/mgr/ansible/tests/test_output_wizards.py b/src/pybind/mgr/ansible/tests/test_output_wizards.py new file mode 100644 index 00000000..2a3a9017 --- /dev/null +++ b/src/pybind/mgr/ansible/tests/test_output_wizards.py @@ -0,0 +1,207 @@ +""" Test output wizards +""" +import unittest +import mock + +from ..ansible_runner_svc import EVENT_DATA_URL +from ..output_wizards import ProcessHostsList, ProcessPlaybookResult, \ + ProcessInventory + +class OutputWizardProcessHostsList(unittest.TestCase): + """Test ProcessHostsList Output Wizard + """ + RESULT_OK = """ + { + "status": "OK", + "msg": "", + "data": { + "hosts": [ + "host_a", + "host_b", + "host_c" + ] + } + } + """ + ar_client = mock.Mock() + logger = mock.Mock() + test_wizard = ProcessHostsList(ar_client, logger) + + def test_process(self): + """Test a normal call""" + + nodes_list = self.test_wizard.process("", self.RESULT_OK) + self.assertEqual([node.name for node in nodes_list], + ["host_a", "host_b", "host_c"]) + + def test_errors(self): + """Test different kind of errors processing result""" + + # Malformed json + host_list = self.test_wizard.process("", """{"msg": """"") + self.assertEqual(host_list, []) + + # key error + host_list = self.test_wizard.process("", """{"msg": ""}""") + self.assertEqual(host_list, []) + + # Hosts not in iterable + host_list = self.test_wizard.process("", """{"data":{"hosts": 123} }""") + self.assertEqual(host_list, []) + +class OutputWizardProcessPlaybookResult(unittest.TestCase): + """Test ProcessPlaybookResult Output Wizard + """ + # Input to process + INVENTORY_EVENTS = {1:"first event", 2:"second event"} + EVENT_INFORMATION = "event information\n" + + # Mocked response + mocked_response = mock.Mock() + mocked_response.text = EVENT_INFORMATION + + # The Ansible Runner Service client + ar_client = mock.Mock() + ar_client.http_get = mock.MagicMock(return_value=mocked_response) + + logger = mock.Mock() + + test_wizard = ProcessPlaybookResult(ar_client, logger) + + def test_process(self): + """Test a normal call + """ + + operation_id = 24 + result = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS) + + # Check http request are correct and compose expected result + expected_result = "" + for key, dummy_data in self.INVENTORY_EVENTS.items(): + http_request = EVENT_DATA_URL % (operation_id, key) + self.ar_client.http_get.assert_any_call(http_request) + expected_result += self.EVENT_INFORMATION + + #Check result + self.assertEqual(result, expected_result) + +class OutputWizardProcessInventory(unittest.TestCase): + """Test ProcessInventory Output Wizard + """ + # Input to process + INVENTORY_EVENTS = {'event_uuid_1': {'host': '192.168.121.144', + 'task': 'list storage inventory', + 'event': 'runner_on_ok'}} + EVENT_DATA = r""" + { + "status": "OK", + "msg": "", + "data": { + "uuid": "5e96d509-174d-4f5f-bd94-e278c3a5b85b", + "counter": 11, + "stdout": "changed: [192.168.121.144]", + "start_line": 17, + "end_line": 18, + "runner_ident": "6e98b2ba-3ce1-11e9-be81-2016b900e38f", + "created": "2019-03-02T11:50:56.582112", + "pid": 482, + "event_data": { + "play_pattern": "osds", + "play": "query each host for storage device inventory", + "task": "list storage inventory", + "task_args": "_ansible_version=2.6.5, _ansible_selinux_special_fs=['fuse', 'nfs', 'vboxsf', 'ramfs', '9p'], _ansible_no_log=False, _ansible_module_name=ceph_volume, _ansible_debug=False, _ansible_verbosity=0, _ansible_keep_remote_files=False, _ansible_syslog_facility=LOG_USER, _ansible_socket=None, action=inventory, _ansible_diff=False, _ansible_remote_tmp=~/.ansible/tmp, _ansible_shell_executable=/bin/sh, _ansible_check_mode=False, _ansible_tmpdir=None", + "remote_addr": "192.168.121.144", + "res": { + "_ansible_parsed": true, + "stderr_lines": [], + "changed": true, + "end": "2019-03-02 11:50:56.554937", + "_ansible_no_log": false, + "stdout": "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]", + "cmd": [ + "ceph-volume", + "inventory", + "--format=json" + ], + "rc": 0, + "start": "2019-03-02 11:50:55.150121", + "stderr": "", + "delta": "0:00:01.404816", + "invocation": { + "module_args": { + "wal_vg": null, + "wal": null, + "dmcrypt": false, + "block_db_size": "-1", + "journal": null, + "objectstore": "bluestore", + "db": null, + "batch_devices": [], + "db_vg": null, + "journal_vg": null, + "cluster": "ceph", + "osds_per_device": 1, + "containerized": "False", + "crush_device_class": null, + "report": false, + "data_vg": null, + "data": null, + "action": "inventory", + "journal_size": "5120" + } + }, + "stdout_lines": [ + "[{\"available\": true, \"rejected_reasons\": [], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 0, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdc\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [], \"path\": \"/dev/sdc\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sda\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-dcf8a88c-5546-42d2-afa4-b36f7fb23b66\", \"osd_id\": \"3\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"fVqujC-9dgh-cN9W-1XD4-zVx1-1UdA-fUS3ha\", \"osd_fsid\": \"8b7cbeba-5e86-44ff-a5f3-2e7df77753fe\"}], \"path\": \"/dev/sda\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"noop\", \"rotational\": \"1\", \"vendor\": \"ATA\", \"human_readable_size\": \"50.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {}, \"rev\": \"2.5+\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/sdb\", \"support_discard\": \"\", \"model\": \"QEMU HARDDISK\", \"ro\": \"0\", \"nr_requests\": \"128\", \"size\": 53687091200.0}, \"lvs\": [{\"cluster_name\": \"ceph\", \"name\": \"osd-data-8c92e986-bd97-4b3d-ba77-2cb88e15d80f\", \"osd_id\": \"1\", \"cluster_fsid\": \"30d61f3e-7ee4-4bdc-8fe7-2ad5bb3f5317\", \"type\": \"block\", \"block_uuid\": \"mgzO7O-vUfu-H3mf-4R3K-2f97-ZMRH-SngBFP\", \"osd_fsid\": \"6d067688-3e1b-45f9-ad03-8abd19e9f117\"}], \"path\": \"/dev/sdb\"}, {\"available\": false, \"rejected_reasons\": [\"locked\"], \"sys_api\": {\"scheduler_mode\": \"mq-deadline\", \"rotational\": \"1\", \"vendor\": \"0x1af4\", \"human_readable_size\": \"41.00 GB\", \"sectors\": 0, \"sas_device_handle\": \"\", \"partitions\": {\"vda1\": {\"start\": \"2048\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2048\", \"size\": \"1024.00 KB\"}, \"vda3\": {\"start\": \"2101248\", \"holders\": [\"dm-0\", \"dm-1\"], \"sectorsize\": 512, \"sectors\": \"81784832\", \"size\": \"39.00 GB\"}, \"vda2\": {\"start\": \"4096\", \"holders\": [], \"sectorsize\": 512, \"sectors\": \"2097152\", \"size\": \"1024.00 MB\"}}, \"rev\": \"\", \"sas_address\": \"\", \"locked\": 1, \"sectorsize\": \"512\", \"removable\": \"0\", \"path\": \"/dev/vda\", \"support_discard\": \"\", \"model\": \"\", \"ro\": \"0\", \"nr_requests\": \"256\", \"size\": 44023414784.0}, \"lvs\": [{\"comment\": \"not used by ceph\", \"name\": \"LogVol00\"}, {\"comment\": \"not used by ceph\", \"name\": \"LogVol01\"}], \"path\": \"/dev/vda\"}]" + ] + }, + "pid": 482, + "play_uuid": "2016b900-e38f-0e09-19be-00000000000c", + "task_uuid": "2016b900-e38f-0e09-19be-000000000012", + "event_loop": null, + "playbook_uuid": "e80e66f2-4a78-4a96-aaf6-fbe473f11312", + "playbook": "storage-inventory.yml", + "task_action": "ceph_volume", + "host": "192.168.121.144", + "task_path": "/usr/share/ansible-runner-service/project/storage-inventory.yml:29" + }, + "event": "runner_on_ok" + } + } + """ + + # Mocked response + mocked_response = mock.Mock() + mocked_response.text = EVENT_DATA + + # The Ansible Runner Service client + ar_client = mock.Mock() + ar_client.http_get = mock.MagicMock(return_value=mocked_response) + + logger = mock.Mock() + + test_wizard = ProcessInventory(ar_client, logger) + + def test_process(self): + """Test a normal call + """ + operation_id = 12 + nodes_list = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS) + + for key, dummy_data in self.INVENTORY_EVENTS.items(): + http_request = EVENT_DATA_URL % (operation_id, key) + self.ar_client.http_get.assert_any_call(http_request) + + + # Only one host + self.assertTrue(len(nodes_list), 1) + + # Host retrieved OK + self.assertEqual(nodes_list[0].name, "192.168.121.144") + + # Devices + self.assertTrue(len(nodes_list[0].devices), 4) + + expected_device_ids = ["/dev/sdc", "/dev/sda", "/dev/sdb", "/dev/vda"] + device_ids = [dev.id for dev in nodes_list[0].devices] + + self.assertEqual(expected_device_ids, device_ids) |