]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/ansible/tests/test_output_wizards.py
update download target update for octopus release
[ceph.git] / ceph / src / pybind / mgr / ansible / tests / test_output_wizards.py
1 """ Test output wizards
2 """
3 import unittest
4 import mock
5
6 from ..ansible_runner_svc import EVENT_DATA_URL
7 from ..output_wizards import ProcessHostsList, ProcessPlaybookResult, \
8 ProcessInventory
9
10 class OutputWizardProcessHostsList(unittest.TestCase):
11 """Test ProcessHostsList Output Wizard
12 """
13 RESULT_OK = """
14 {
15 "status": "OK",
16 "msg": "",
17 "data": {
18 "hosts": [
19 "host_a",
20 "host_b",
21 "host_c"
22 ]
23 }
24 }
25 """
26 ar_client = mock.Mock()
27 logger = mock.Mock()
28 test_wizard = ProcessHostsList(ar_client, logger)
29
30 def test_process(self):
31 """Test a normal call"""
32
33 nodes_list = self.test_wizard.process("", self.RESULT_OK)
34 self.assertEqual([node.name for node in nodes_list],
35 ["host_a", "host_b", "host_c"])
36
37 def test_errors(self):
38 """Test different kind of errors processing result"""
39
40 # Malformed json
41 host_list = self.test_wizard.process("", """{"msg": """"")
42 self.assertEqual(host_list, [])
43
44 # key error
45 host_list = self.test_wizard.process("", """{"msg": ""}""")
46 self.assertEqual(host_list, [])
47
48 # Hosts not in iterable
49 host_list = self.test_wizard.process("", """{"data":{"hosts": 123} }""")
50 self.assertEqual(host_list, [])
51
52 class OutputWizardProcessPlaybookResult(unittest.TestCase):
53 """Test ProcessPlaybookResult Output Wizard
54 """
55 # Input to process
56 INVENTORY_EVENTS = {1:"first event", 2:"second event"}
57 EVENT_INFORMATION = "event information\n"
58
59 # Mocked response
60 mocked_response = mock.Mock()
61 mocked_response.text = EVENT_INFORMATION
62
63 # The Ansible Runner Service client
64 ar_client = mock.Mock()
65 ar_client.http_get = mock.MagicMock(return_value=mocked_response)
66
67 logger = mock.Mock()
68
69 test_wizard = ProcessPlaybookResult(ar_client, logger)
70
71 def test_process(self):
72 """Test a normal call
73 """
74
75 operation_id = 24
76 result = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS)
77
78 # Check http request are correct and compose expected result
79 expected_result = ""
80 for key, dummy_data in self.INVENTORY_EVENTS.items():
81 http_request = EVENT_DATA_URL % (operation_id, key)
82 self.ar_client.http_get.assert_any_call(http_request)
83 expected_result += self.EVENT_INFORMATION
84
85 #Check result
86 self.assertEqual(result, expected_result)
87
88 class OutputWizardProcessInventory(unittest.TestCase):
89 """Test ProcessInventory Output Wizard
90 """
91 # Input to process
92 INVENTORY_EVENTS = {'event_uuid_1': {'host': '192.168.121.144',
93 'task': 'list storage inventory',
94 'event': 'runner_on_ok'}}
95 EVENT_DATA = r"""
96 {
97 "status": "OK",
98 "msg": "",
99 "data": {
100 "uuid": "5e96d509-174d-4f5f-bd94-e278c3a5b85b",
101 "counter": 11,
102 "stdout": "changed: [192.168.121.144]",
103 "start_line": 17,
104 "end_line": 18,
105 "runner_ident": "6e98b2ba-3ce1-11e9-be81-2016b900e38f",
106 "created": "2019-03-02T11:50:56.582112",
107 "pid": 482,
108 "event_data": {
109 "play_pattern": "osds",
110 "play": "query each host for storage device inventory",
111 "task": "list storage inventory",
112 "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",
113 "remote_addr": "192.168.121.144",
114 "res": {
115 "_ansible_parsed": true,
116 "stderr_lines": [],
117 "changed": true,
118 "end": "2019-03-02 11:50:56.554937",
119 "_ansible_no_log": false,
120 "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\"}]",
121 "cmd": [
122 "ceph-volume",
123 "inventory",
124 "--format=json"
125 ],
126 "rc": 0,
127 "start": "2019-03-02 11:50:55.150121",
128 "stderr": "",
129 "delta": "0:00:01.404816",
130 "invocation": {
131 "module_args": {
132 "wal_vg": null,
133 "wal": null,
134 "dmcrypt": false,
135 "block_db_size": "-1",
136 "journal": null,
137 "objectstore": "bluestore",
138 "db": null,
139 "batch_devices": [],
140 "db_vg": null,
141 "journal_vg": null,
142 "cluster": "ceph",
143 "osds_per_device": 1,
144 "containerized": "False",
145 "crush_device_class": null,
146 "report": false,
147 "data_vg": null,
148 "data": null,
149 "action": "inventory",
150 "journal_size": "5120"
151 }
152 },
153 "stdout_lines": [
154 "[{\"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\"}]"
155 ]
156 },
157 "pid": 482,
158 "play_uuid": "2016b900-e38f-0e09-19be-00000000000c",
159 "task_uuid": "2016b900-e38f-0e09-19be-000000000012",
160 "event_loop": null,
161 "playbook_uuid": "e80e66f2-4a78-4a96-aaf6-fbe473f11312",
162 "playbook": "storage-inventory.yml",
163 "task_action": "ceph_volume",
164 "host": "192.168.121.144",
165 "task_path": "/usr/share/ansible-runner-service/project/storage-inventory.yml:29"
166 },
167 "event": "runner_on_ok"
168 }
169 }
170 """
171
172 # Mocked response
173 mocked_response = mock.Mock()
174 mocked_response.text = EVENT_DATA
175
176 # The Ansible Runner Service client
177 ar_client = mock.Mock()
178 ar_client.http_get = mock.MagicMock(return_value=mocked_response)
179
180 logger = mock.Mock()
181
182 test_wizard = ProcessInventory(ar_client, logger)
183
184 def test_process(self):
185 """Test a normal call
186 """
187 operation_id = 12
188 nodes_list = self.test_wizard.process(operation_id, self.INVENTORY_EVENTS)
189
190 for key, dummy_data in self.INVENTORY_EVENTS.items():
191 http_request = EVENT_DATA_URL % (operation_id, key)
192 self.ar_client.http_get.assert_any_call(http_request)
193
194
195 # Only one host
196 self.assertTrue(len(nodes_list), 1)
197
198 # Host retrieved OK
199 self.assertEqual(nodes_list[0].name, "192.168.121.144")
200
201 # Devices
202 self.assertTrue(len(nodes_list[0].devices), 4)
203
204 expected_device_ids = ["/dev/sdc", "/dev/sda", "/dev/sdb", "/dev/vda"]
205 device_ids = [dev.id for dev in nodes_list[0].devices]
206
207 self.assertEqual(expected_device_ids, device_ids)