def testAutoRetryFor412(self, patched_sleep): url = 'https://server1.ibmc.com/redfish/v1/fakepath' payload = {'fake': 'payload'} response_json = {'message': 'hello ibmc.'} self.start_mocked_http_server([ responses.Response(method=GET, url=url, headers={"ETag": self.etag}), responses.Response(method=PATCH, url=url, status=412), responses.Response(method=GET, url=url, headers={"ETag": self.etag}), responses.Response(method=PATCH, url=url, json=response_json) ]) with ibmc_client.connect(**self.server) as client: resp = client.connector.request(PATCH, url, json=payload) req = self.get_test_api_request(2) self.assertEqual(req.method, PATCH) self.assertEqual(req.headers['Content-Type'], 'application/json') self.assertEqual(req.headers['X-Auth-Token'], self.token) self.assertEqual(req.headers['If-Match'], self.etag) retry_req = self.get_test_api_request(4) self.assertEqual(retry_req.method, PATCH) self.assertEqual(retry_req.headers['Content-Type'], 'application/json') self.assertEqual(retry_req.headers['X-Auth-Token'], self.token) self.assertEqual(retry_req.headers['If-Match'], self.etag) self.assertEqual(json.loads(self.get_request_body(retry_req)), payload) self.assertEqual(resp.json(), response_json) self.assertEqual(patched_sleep.call_count, 1)
def testGetInitialTask(self): get_task_url = ('https://server1.ibmc.com/redfish/v1/TaskService' '/Tasks/1') response_list = [ responses.Response( method=GET, url=get_task_url, json=self.load_json_file('get-initial-task-response.json')) ] self.start_mocked_http_server(response_list) with ibmc_client.connect(**self.server) as client: task = client.task.get('1') self.assertEqual(task.id, '1') self.assertEqual(task.name, 'mock task') self.assertEqual(task.state, 'Running') self.assertEqual(task.start_time, '2020-04-28T08:17:41+08:00') self.assertIsNone(task.end_time) self.assertIsNone(task.percentage) self.assertEqual(task.messages, {}) self.assertIsNone(task.message_id) self.assertIsNone(task.message) self.assertIsNone(task.message_args) self.assertIsNone(task.resolution) self.assertIsNone(task.severity)
def testSetBootSourceOverride(self): response_data = self.load_json_file('system-v5.json') self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=response_data, headers={ "ETag": self.etag } ), responses.Response( method=PATCH, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=response_data ) ]) with ibmc_client.connect(**self.server) as client: client.system.set_boot_source(constants.BOOT_SOURCE_TARGET_PXE, constants.BOOT_SOURCE_MODE_BIOS, constants.BOOT_SOURCE_ENABLED_ONCE) req = self.get_test_api_request(2) self.assertEqual(req.method, PATCH) self.assertEqual(req.headers['Content-Type'], 'application/json') self.assertEqual(req.headers['X-Auth-Token'], self.token) self.assertEqual(req.headers['If-Match'], self.etag) boot = { 'BootSourceOverrideTarget': constants.BOOT_SOURCE_TARGET_PXE, 'BootSourceOverrideEnabled': constants.BOOT_SOURCE_ENABLED_ONCE, 'BootSourceOverrideMode': constants.BOOT_SOURCE_MODE_BIOS } self.assertEqual(json.loads(self.get_request_body(req)), {'Boot': boot})
def testListDrive(self): storage_id = 'RAIDStorage0' resp_list = [ responses.Response( method=constants.GET, url=('https://server1.ibmc.com/redfish/v1/Systems/1' '/Storages/%s' % storage_id), json=self.load_json_file('get-raid-storage-0.json')) ] drive_idx_list = list(range(0, 8)) + [40, 41] for idx in drive_idx_list: resp_list.append( responses.Response( method=constants.GET, url=( 'https://server1.ibmc.com/redfish/v1/Chassis/1/Drives/' 'HDDPlaneDisk%d' % idx), json=self.load_json_file('get-drive-%d.json' % idx))) self.start_mocked_http_server(resp_list) with ibmc_client.connect(**self.server) as client: drives = client.chassis.drive.list(storage_id) self.assertEqual(len(drives), 10) drive0 = drives[0] self._assertDrive0(drive0) drive40 = drives[-2] self._assertDrive40(drive40)
def testSetDrive(self): resp = self.new_mocked_response('get-drive-0.json') self.start_mocked_http_server([ responses.Response( method=constants.PATCH, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=resp.json()) ]) with ibmc_client.connect(**self.server) as client: drive = Drive(resp, ibmc_client=client) drive.set(firmware_state=constants.DRIVE_FM_STATE_UNCONFIG_GOOD, hotspare_type=constants.HOT_SPARE_NONE) patch_req = self.get_test_api_request(1) payload = { "HotspareType": constants.HOT_SPARE_NONE, 'Oem': { 'Huawei': { 'FirmwareStatus': constants.DRIVE_FM_STATE_UNCONFIG_GOOD } } } self.assertEqual(json.loads(self.get_request_body(patch_req)), payload)
def testGetDrive(self): self.start_mocked_http_server([ responses.Response( method=constants.GET, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=self.load_json_file('get-drive-0.json')) ]) with ibmc_client.connect(**self.server) as client: drive = client.chassis.drive.get('HDDPlaneDisk0') self._assertDrive0(drive)
def testGetPowerStateForV5Server(self): self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('system-v5.json')) ]) with ibmc_client.connect(**self.server) as client: system = client.system.get() self.assertEqual(system.power_state, 'On', 'power state is not match')
def testIsStorageReadyReturnTrue(self): self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('get-system-with-storage-ready.json') ) ]) with ibmc_client.connect(**self.server) as client: system = client.system.get() ready = system.is_storage_ready self.assertTrue(ready)
def testGetBootSequenceForV3(self): response_data = self.load_json_file('system-v3.json') self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=response_data), ]) with ibmc_client.connect(**self.server) as client: system = client.system.get() self.assertEqual(system.boot_sequence, response_data['Oem']['Huawei']['BootupSequence'], 'Boot Sequence not match')
def testRestoreNothing(self): resp = self.new_mocked_response('get-drive-fm-good-response.json') self.start_mocked_http_server([ responses.Response( method=constants.PATCH, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=resp.json()) ]) with ibmc_client.connect(**self.server) as client: drive = Drive(resp, ibmc_client=client) with patch.object(drive, 'set') as patched_set: drive.restore() self.assertFalse(patched_set.called)
def testRestoreHotSparedDrive(self): resp = self.new_mocked_response('get-drive-fm-spare-response.json') self.start_mocked_http_server([ responses.Response( method=constants.PATCH, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=resp.json()) ]) with ibmc_client.connect(**self.server) as client: drive = Drive(resp, ibmc_client=client) with patch.object(drive, 'set') as patched_set: drive.restore() patched_set.assert_called_with( hotspare_type=constants.HOT_SPARE_NONE)
def testRestoreJbodDrive(self): resp = self.new_mocked_response('get-drive-fm-jbod-response.json') self.start_mocked_http_server([ responses.Response( method=constants.PATCH, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=resp.json()) ]) with ibmc_client.connect(**self.server) as client: drive = Drive(resp, ibmc_client=client) with patch.object(drive, 'set') as patched_set: drive.restore() patched_set.assert_called_with( firmware_state=constants.DRIVE_FM_STATE_UNCONFIG_GOOD)
def testSetDriveHotSpareType(self): resp = self.new_mocked_response('get-drive-0.json') self.start_mocked_http_server([ responses.Response( method=constants.PATCH, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives' '/HDDPlaneDisk0'), json=resp.json()) ]) with ibmc_client.connect(**self.server) as client: drive = Drive(resp, ibmc_client=client) drive.set(hotspare_type=constants.HOT_SPARE_GLOBAL) patch_req = self.get_test_api_request(1) self.assertEqual(json.loads(self.get_request_body(patch_req)), {"HotspareType": constants.HOT_SPARE_GLOBAL})
def testIsStorageReadyNotSupported(self): self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('system-v5.json') ) ]) with self.assertRaises(exceptions.FeatureNotSupported) as c: with ibmc_client.connect(**self.server) as client: system = client.system.get() system.is_storage_ready self.assertIn('Feature is not supported by this iBMC server: get' ' StorageConfigReady attribute from System Resource, ' 'please check the version of this iBMC server.', c.exception.message)
def testConnect(self): self.start_mocked_http_server([]) with ibmc_client.connect(**self.server) as client: assert len(responses.calls) == 3 request0 = responses.calls[0].request self.assertEqual(request0.url, '%s/redfish/v1' % self.address) self.assertEqual(client.connector.system_base_url, '/redfish/v1/Systems/1') self.assertEqual(client.connector.manager_base_url, '/redfish/v1/Managers/1') session_service_path = '/redfish/v1/SessionService' self.assertEqual(client.connector.session_service_base_url, session_service_path) request1 = responses.calls[1].request session_path = "%s%s/Sessions" % (client.connector.address, session_service_path) self.assertEqual(request1.url, session_path) self.assertEqual(request1.method, POST) self.assertEqual(request1.headers['Content-Type'], 'application/json') self.assertEqual(json.loads(self.get_request_body(request1)), { 'UserName': self.username, 'Password': self.password }) session = client.connector.session self.assertEqual(session, { 'address': self.address, 'token': self.token, 'location': '/redfish/v1/SessionService/Sessions/' + self.token }) request2 = responses.calls[2].request self.assertEqual(request2.url, '%s/redfish/v1/Managers' % self.address) self.assertEqual(client.connector.resource_id, '1') assert len(responses.calls) == 4 request3 = responses.calls[3].request self.assertEqual(request3.url, '%s%s' % (self.address, session['location'])) self.assertEqual(request3.method, DELETE)
def testGetBootSourceOverride(self): self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('system-v5.json')) ]) with ibmc_client.connect(**self.server) as client: system = client.system.get() boot_source_override = system.boot_source_override self.assertEqual(boot_source_override.enabled, constants.BOOT_SOURCE_ENABLED_DISABLED) self.assertEqual(boot_source_override.target, constants.BOOT_SOURCE_TARGET_NONE) self.assertEqual(boot_source_override.mode, constants.BOOT_SOURCE_MODE_BIOS) self.assertEqual( boot_source_override.supported_boot_devices, ["None", "Pxe", "Floppy", "Cd", "Hdd", "BiosSetup"])
def testAutoRetryFor401(self): url = 'https://server1.ibmc.com/redfish/v1/fakepath' response_json = {'message': 'hello ibmc.'} self.start_mocked_http_server([ responses.Response(method=GET, url=url, status=401, json=self.load_json_file('401.json')), self.get_mocked_new_session_response(self.session_location), responses.Response(method=GET, url=url, json=response_json), ]) with ibmc_client.connect(**self.server) as client: resp = client.connector.request(GET, url) req = self.get_test_api_request(1) self.assertEqual(req.method, GET) self.assertEqual(req.headers['X-Auth-Token'], self.token) retry_req = self.get_test_api_request(3) self.assertEqual(retry_req.method, GET) self.assertEqual(retry_req.url, url) self.assertEqual(retry_req.headers['X-Auth-Token'], self.token) self.assertEqual(resp.json(), response_json)
def testWaitTask(self, patched_time_sleep): resp_list = [ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/TaskService/Tasks/1', json=self.load_json_file('delete-volume-task-response.json')) ] * 10 resp_list.append( responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/TaskService/Tasks/1', json=self.load_json_file( 'delete-volume-task-finished-response.json'))) self.start_mocked_http_server(resp_list) with ibmc_client.connect(**self.server) as client: task = client.task.wait_task_by_id('1') self.assertEqual(patched_time_sleep.call_count, 10) self.assertEqual(task.state, 'Completed')
def testGetChassis(self): get_task_url = 'https://server1.ibmc.com/redfish/v1/Chassis/1' response_list = [ responses.Response(method=GET, url=get_task_url, json=self.load_json_file( 'get-chassis-response.json')) ] drive_idx_list = list(range(0, 8)) + [40, 41] for idx in drive_idx_list: response_list.append(responses.Response( method=GET, url=('https://server1.ibmc.com/redfish/v1/Chassis/1/Drives/' 'HDDPlaneDisk%d' % idx), json=self.load_json_file('get-drive-%d.json' % idx) )) self.start_mocked_http_server(response_list) with ibmc_client.connect(**self.server) as client: chassis = client.chassis.get() self.assertEqual(len(chassis.drives), 10)
def testResetPower(self): response_data = self.load_json_file('bios.json') self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('system-v5.json')), responses.Response( method=POST, url=('https://server1.ibmc.com' '/redfish/v1/Systems/1/Actions/ComputerSystem.Reset'), json=response_data) ]) with ibmc_client.connect(**self.server) as client: client.system.reset(constants.RESET_FORCE_RESTART) req = self.get_test_api_request(2) self.assertEqual(req.method, POST) self.assertEqual(req.headers['Content-Type'], 'application/json') self.assertEqual(req.headers['X-Auth-Token'], self.token) self.assertEqual(json.loads(self.get_request_body(req)), { 'ResetType': constants.RESET_FORCE_RESTART, })
def testGetBootSequenceForV5(self): response_data = self.load_json_file('bios.json') self.start_mocked_http_server([ responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1', json=self.load_json_file('system-v5.json') ), responses.Response( method=GET, url='https://server1.ibmc.com/redfish/v1/Systems/1/Bios', json=response_data ) ]) with ibmc_client.connect(**self.server) as client: system = client.system.get() attrs = response_data['Attributes'] _orders = [attrs['BootTypeOrder0'], attrs['BootTypeOrder1'], attrs['BootTypeOrder2'], attrs['BootTypeOrder3']] boot_seq = [_BOOT_SEQUENCE_MAP.get(t, t) for t in _orders] self.assertEqual(system.boot_sequence, boot_seq, 'Boot Sequence not match')
def testGetCompleteTask(self): get_task_url = ('https://server1.ibmc.com/redfish/v1/TaskService' '/Tasks/4') task_json = self.load_json_file('get-complete-task-response.json') response_list = [ responses.Response(method=GET, url=get_task_url, json=task_json) ] self.start_mocked_http_server(response_list) with ibmc_client.connect(**self.server) as client: task = client.task.get('4') self.assertEqual(task.id, '4') self.assertEqual(task.name, 'volume creation task') self.assertEqual(task.state, 'Completed') self.assertEqual(task.start_time, '2020-04-28T10:50:12+08:00') self.assertEqual(task.end_time, '2020-04-28T10:50:17+08:00') self.assertIsNone(task.percentage) messages = task_json.get('Messages') self.assertEqual(task.messages, messages) self.assertEqual(task.message_id, 'iBMC.1.0.VolumeCreationSuccess') self.assertEqual(task.message, messages['Message']) self.assertEqual(task.message_args, messages['MessageArgs']) self.assertEqual(task.resolution, messages['Resolution']) self.assertEqual(task.severity, messages['Severity'])
def testConnectFailed(self): self.start_mocked_http_server([]) with self.assertRaises(exceptions.IBMCConnectionError): with ibmc_client.connect(**self.server) as client: client.system.get()