ILO: Add unit tests for ris.RISOperations._rest_op
This commit adds the unit test cases for the main method ris.RISOperations._rest_op which handles the REST interactions with the iLO. Change-Id: I1dea76aaed8a7f92c2ccc6b91ea7cb8fc03a9969
This commit is contained in:
parent
34218d260a
commit
ac01ccb3f5
|
@ -45,6 +45,8 @@ class RISOperations(operations.IloOperations):
|
|||
"""Generic REST Operation handler."""
|
||||
|
||||
url = urlparse.urlparse('https://' + self.host + suburi)
|
||||
# Used for logging on redirection error.
|
||||
start_url = url.geturl()
|
||||
|
||||
if request_headers is None:
|
||||
request_headers = dict()
|
||||
|
@ -54,7 +56,7 @@ class RISOperations(operations.IloOperations):
|
|||
hr = "BASIC " + base64.b64encode(self.login + ":" + self.password)
|
||||
request_headers['Authorization'] = hr
|
||||
|
||||
redir_count = 4
|
||||
redir_count = 5
|
||||
while redir_count:
|
||||
conn = None
|
||||
if url.scheme == 'https':
|
||||
|
@ -86,6 +88,11 @@ class RISOperations(operations.IloOperations):
|
|||
redir_count -= 1
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# Redirected for 5th time. Throw error
|
||||
msg = ("URL Redirected 5 times continuously. "
|
||||
"URL incorrect: %s" % start_url)
|
||||
raise exception.IloConnectionError(msg)
|
||||
|
||||
response = dict()
|
||||
try:
|
||||
|
|
|
@ -19,3 +19,264 @@ MODULE = "RIS"
|
|||
HTTP_BOOT_URL = {
|
||||
"UefiShellStartupUrl": "http://10.10.1.30:8081/startup.nsh"
|
||||
}
|
||||
|
||||
RESPONSE_BODY_FOR_REST_OP = """
|
||||
{
|
||||
"AssetTag": "",
|
||||
"AvailableActions": [
|
||||
{
|
||||
"Action": "Reset",
|
||||
"Capabilities": [
|
||||
{
|
||||
"AllowableValues": [
|
||||
"On",
|
||||
"ForceOff",
|
||||
"ForceRestart",
|
||||
"Nmi",
|
||||
"PushPowerButton"
|
||||
],
|
||||
"PropertyName": "ResetType"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Bios": {
|
||||
"Current": {
|
||||
"VersionString": "I36 v1.40 (01/28/2015)"
|
||||
}
|
||||
},
|
||||
"Boot": {
|
||||
"BootSourceOverrideEnabled": "Disabled",
|
||||
"BootSourceOverrideSupported": [
|
||||
"None",
|
||||
"Cd",
|
||||
"Hdd",
|
||||
"Usb",
|
||||
"Utilities",
|
||||
"Diags",
|
||||
"BiosSetup",
|
||||
"Pxe",
|
||||
"UefiShell",
|
||||
"UefiTarget"
|
||||
],
|
||||
"BootSourceOverrideTarget": "None",
|
||||
"UefiTargetBootSourceOverride": "None",
|
||||
"UefiTargetBootSourceOverrideSupported": [
|
||||
"HD.Emb.1.2",
|
||||
"Generic.USB.1.1",
|
||||
"NIC.FlexLOM.1.1.IPv4",
|
||||
"NIC.FlexLOM.1.1.IPv6",
|
||||
"CD.Virtual.2.1"
|
||||
]
|
||||
},
|
||||
"Description": "Computer System View",
|
||||
"HostCorrelation": {
|
||||
"HostMACAddress": [
|
||||
"6c:c2:17:39:fe:80",
|
||||
"6c:c2:17:39:fe:88"
|
||||
],
|
||||
"HostName": "",
|
||||
"IPAddress": [
|
||||
"",
|
||||
""
|
||||
]
|
||||
},
|
||||
"IndicatorLED": "Off",
|
||||
"Manufacturer": "HP",
|
||||
"Memory": {
|
||||
"TotalSystemMemoryGB": 16
|
||||
},
|
||||
"Model": "ProLiant BL460c Gen9",
|
||||
"Name": "Computer System",
|
||||
"Oem": {
|
||||
"Hp": {
|
||||
"AvailableActions": [
|
||||
{
|
||||
"Action": "PowerButton",
|
||||
"Capabilities": [
|
||||
{
|
||||
"AllowableValues": [
|
||||
"Press",
|
||||
"PressAndHold"
|
||||
],
|
||||
"PropertyName": "PushType"
|
||||
},
|
||||
{
|
||||
"AllowableValues": [
|
||||
"/Oem/Hp"
|
||||
],
|
||||
"PropertyName": "Target"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Action": "SystemReset",
|
||||
"Capabilities": [
|
||||
{
|
||||
"AllowableValues": [
|
||||
"ColdBoot"
|
||||
],
|
||||
"PropertyName": "ResetType"
|
||||
},
|
||||
{
|
||||
"AllowableValues": [
|
||||
"/Oem/Hp"
|
||||
],
|
||||
"PropertyName": "Target"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Battery": [],
|
||||
"Bios": {
|
||||
"Backup": {
|
||||
"Date": "v1.40 (01/28/2015)",
|
||||
"Family": "I36",
|
||||
"VersionString": "I36 v1.40 (01/28/2015)"
|
||||
},
|
||||
"Current": {
|
||||
"Date": "01/28/2015",
|
||||
"Family": "I36",
|
||||
"VersionString": "I36 v1.40 (01/28/2015)"
|
||||
},
|
||||
"UefiClass": 2
|
||||
},
|
||||
"DeviceDiscoveryComplete": {
|
||||
"AMSDeviceDiscovery": "NoAMS",
|
||||
"SmartArrayDiscovery": "Initial",
|
||||
"vAuxDeviceDiscovery": "DataIncomplete",
|
||||
"vMainDeviceDiscovery": "ServerOff"
|
||||
},
|
||||
"PostState": "PowerOff",
|
||||
"PowerAllocationLimit": 500,
|
||||
"PowerAutoOn": "PowerOn",
|
||||
"PowerOnDelay": "Minimum",
|
||||
"PowerRegulatorMode": "Dynamic",
|
||||
"PowerRegulatorModesSupported": [
|
||||
"OSControl",
|
||||
"Dynamic",
|
||||
"Max",
|
||||
"Min"
|
||||
],
|
||||
"ServerSignature": 0,
|
||||
"Type": "HpComputerSystemExt.0.10.1",
|
||||
"VirtualProfile": "Inactive",
|
||||
"VirtualUUID": null,
|
||||
"links": {
|
||||
"BIOS": {
|
||||
"href": "/rest/v1/systems/1/bios"
|
||||
},
|
||||
"MEMORY": {
|
||||
"href": "/rest/v1/Systems/1/Memory"
|
||||
},
|
||||
"PCIDevices": {
|
||||
"href": "/rest/v1/Systems/1/PCIDevices"
|
||||
},
|
||||
"PCISlots": {
|
||||
"href": "/rest/v1/Systems/1/PCISlots"
|
||||
},
|
||||
"SecureBoot": {
|
||||
"href": "/rest/v1/Systems/1/SecureBoot"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Power": "Off",
|
||||
"Processors": {
|
||||
"Count": 1,
|
||||
"ProcessorFamily": "Intel(R) Xeon(R) CPU E5-2609 v3 @ 1.90GHz",
|
||||
"Status": {
|
||||
"HealthRollUp": "OK"
|
||||
}
|
||||
},
|
||||
"SKU": "727021-B21",
|
||||
"SerialNumber": "SGH449WNL3",
|
||||
"Status": {
|
||||
"Health": "OK",
|
||||
"State": "Disabled"
|
||||
},
|
||||
"SystemType": "Physical",
|
||||
"Type": "ComputerSystem.0.9.6",
|
||||
"UUID": "30373237-3132-4753-4834-3439574E4C33",
|
||||
"links": {
|
||||
"Chassis": [
|
||||
{
|
||||
"href": "/rest/v1/Chassis/1"
|
||||
}
|
||||
],
|
||||
"Logs": {
|
||||
"href": "/rest/v1/Systems/1/Logs"
|
||||
},
|
||||
"ManagedBy": [
|
||||
{
|
||||
"href": "/rest/v1/Managers/1"
|
||||
}
|
||||
],
|
||||
"self": {
|
||||
"href": "/rest/v1/Systems/1"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
BASE64_GZIPPED_RESPONSE = """
|
||||
H4sIAHN9ClUC/+1YW2/iOBR+51dEeZqR2pAQCoWnhUALGm5qSndXoz6YYMAaEyPHoWVH/e9r50JJ7ARajVbzsH0p8rnZ5xx/53MqPysa/9M7QQDZI1jrbU3Xr5K1PUAYLDDseAwRP+Cy75FE/P08/op1IxVh/QC5p8TFUeyAHVggjBiCWTdqd+9uMSYvYgtPAIcFpkflqZ8Lm5HeEerB6Wp1VocfgAHKyvQmW1QmnoXBZkZeIO2GjPGsKDWf1Q70GSU7SNlhArbwmM/Hww7Kbt4yK8+V7HoSQO8iIhL3nmHdCSmFPsssRoInSANeRpdR5EetMLQb2t4y6qb2xbSqtdtqzbRuvuq5SG9pJEKyTqMVl4Qi83tIKVrCvi/KuRTOeyiIf1+VGbjhbkcoi0yyxdcnxIdSpy3zK4OltDQPFtISS9szJ+ghsJYWRU5dyMJdXjB7lXY0hyvkbiDGKsEjoGt+XSqKrlDkItFuS0c/8SVbfVS/JOODntHfLgzLqOUPcw99SJFnzN0uF1t58WToGHcYvo6mYyE2hrN9/QKdhlTenvGEKAsBNmo8SiXb/Gkj9mDgUbRLIckh213IINXcQ8DgVntC8CUFuQEJmEP4fcAgUT9pXyEcd5zOcklhIKOP3vDaXq1tNdt2q72C7Vszv928wq260iJOet9PqzScFYbORypKxdBfIg8wQkf9nnD/joD6GPjhCngspJAK0WB2lMAtoYdsLh4JAzhOYCy+73IFq5GJNiZLiIUvjmIjBHymdUf1hulpvD1aqff0pLmypOIp/5mtwk5GqtLZdG6oHGfVKUgXwPHZyVUe7FOT7GQWiNpfXajY8ZcDgpd6qfpzuTdp/IhZpp4+xxlw9Z/mpMr7o8pb4peeMg/D5ZNWnrgluTjbhHH3q2jT79GEDu+paLL/0oyX0Jr/G+v5HNXL0xHAOI4KwP7+rGAqEnwmRt6PcKeUxUMUsOgICv5X0KZ3YIvwIeGNRUof5pgl7VDIZKVDvHv+fTYvOJiDQTTda5USbc5n9siDnC97hHO0gxicGEYHU9S1M3Zz+jEB5OuKY+nulj92OpSCQ0Z/6HO0AVhlse+Er4oIPNVg6Hvp3lSGY4B8haULKf8pmElpFmacJbksKWg0uuXnXLwu7r8X8bkR2iLRHjemqVQMGZm+UwHpBZku9zg9jLY6Rj7ahlul2gNch1hQLcGCoowcfN5U3nnloJhyx5TIdYjPKFGWQx0lYXivymWUe5PmQSMuiIvWPhDskG8qn70IuQVn3KUsLh5j/VdmmIZlyi+AhLZzgFwhDOMW4+QT7WGB5nw+FIzVDzHOKWDk/ygCteHULUaDDYUrEbnK6RKr7q1qEG06qFrVhcDJi67tuD+ePvz9gSDuMUjCqy8KM3OG8VUJPhXqxPzScC4m7NPBYuOLQrnQ400lfSy4NNiJ+Zkx+VbwnSK6gLnHEO9LnquA0Py3EhJG88U6eZYddU9mhs8g/vLwVfsLEl/8d2ZzrX9zXWuYLW1va39oltEy7wf/nD7vBJiFcsb1AQSYbR4IxvNdtM1vRV9c3G9zodCsNc2add2tpbdO3GCO3pNwu4hP6t4P6vXWn5ORfdSQgyeBk5C5jcLMJ5vsLqLapJAw2xwC/uRMseoIFVmg4CjRMtI5qyd3XbdNu2nX7Oa1bdm163rzxr6u39r1a7tut26a9X7dsY8HkFFAdzZ8miKZ7ymAQmqwxLZq6QU9dPpgH5G1om4lTRsZVBS3QrzCwRouu4dP7Tq2phduO4B49ZFtS21Xeav8C14gvWoyFgAA
|
||||
"""
|
||||
|
||||
HEADERS_FOR_REST_OP = [('content-length', '2729'),
|
||||
('server', 'HP-iLO-Server/1.30'),
|
||||
('etag', 'W/"B61EB245"'),
|
||||
('allow', 'GET, HEAD, POST, PATCH'),
|
||||
('cache-control', 'no-cache'),
|
||||
('date', 'Thu, 19 Mar 2015 06:55:59 GMT'),
|
||||
('x_hp-chrp-service-version', '1.0.3'),
|
||||
('content-type', 'application/json')]
|
||||
|
||||
COLLECTIONS_SAMPLE = """
|
||||
{
|
||||
"Description": "iLO User Accounts",
|
||||
"links": {
|
||||
"Member": [
|
||||
{
|
||||
"href": "/rest/v1/AccountService/Accounts/1"
|
||||
}
|
||||
],
|
||||
"self": {
|
||||
"href": "/rest/v1/AccountService/Accounts"
|
||||
}
|
||||
},
|
||||
"Items": [
|
||||
{
|
||||
"UserName": "Administrator",
|
||||
"Description": "iLO User Account",
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "/rest/v1/AccountService/Accounts/1"
|
||||
}
|
||||
},
|
||||
"Oem": {
|
||||
"Hp": {
|
||||
"Privileges": {
|
||||
"RemoteConsolePriv": "true",
|
||||
"iLOConfigPriv": "true",
|
||||
"VirtualMediaPriv": "true",
|
||||
"UserConfigPriv": "true",
|
||||
"VirtualPowerAndResetPriv": "true",
|
||||
"LoginPriv": "true"
|
||||
},
|
||||
"LoginName": "Administrator",
|
||||
"Type": "HpiLOAccount.0.9.7"
|
||||
}
|
||||
},
|
||||
"Password": null,
|
||||
"Type": "ManagerAccount.0.9.7",
|
||||
"Name": "User Account"
|
||||
}
|
||||
],
|
||||
"MemberType": "ManagerAccount.0",
|
||||
"Total": 1,
|
||||
"Type": "Collection.0.9.5",
|
||||
"Name": "Accounts"
|
||||
}
|
||||
"""
|
||||
|
|
|
@ -15,28 +15,31 @@
|
|||
|
||||
"""Test class for RIS Module."""
|
||||
|
||||
import unittest
|
||||
import base64
|
||||
import httplib
|
||||
import json
|
||||
|
||||
import mock
|
||||
import ris_sample_outputs as ris_constants
|
||||
import testtools
|
||||
|
||||
from proliantutils import exception
|
||||
from proliantutils.ilo import ris
|
||||
from proliantutils.tests.ilo import ris_sample_outputs as ris_outputs
|
||||
|
||||
|
||||
class IloRisTestCase(unittest.TestCase):
|
||||
class IloRisTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(IloRisTestCase, self).setUp()
|
||||
self.ilo = ris.RISOperations("x.x.x.x", "Administrator", "admin", None)
|
||||
self.client = ris.RISOperations("1.2.3.4", "admin", "Admin")
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_get_bios_setting')
|
||||
@mock.patch.object(ris.RISOperations, '_validate_uefi_boot_mode')
|
||||
def test_get_http_boot_url_uefi(self, _validate_uefi_boot_mode_mock,
|
||||
get_bios_settings_mock):
|
||||
get_bios_settings_mock.return_value = ris_constants.HTTP_BOOT_URL
|
||||
get_bios_settings_mock.return_value = ris_outputs.HTTP_BOOT_URL
|
||||
_validate_uefi_boot_mode_mock.return_value = True
|
||||
result = self.ilo.get_http_boot_url()
|
||||
result = self.client.get_http_boot_url()
|
||||
_validate_uefi_boot_mode_mock.assert_called_once_with()
|
||||
self.assertEqual(
|
||||
'http://10.10.1.30:8081/startup.nsh', result['UefiShellStartupUrl']
|
||||
|
@ -47,7 +50,7 @@ class IloRisTestCase(unittest.TestCase):
|
|||
def test_set_http_boot_url_uefi(self, _validate_uefi_boot_mode_mock,
|
||||
change_bios_setting_mock):
|
||||
_validate_uefi_boot_mode_mock.return_value = True
|
||||
self.ilo.set_http_boot_url('http://10.10.1.30:8081/startup.nsh')
|
||||
self.client.set_http_boot_url('http://10.10.1.30:8081/startup.nsh')
|
||||
_validate_uefi_boot_mode_mock.assert_called_once_with()
|
||||
change_bios_setting_mock.assert_called_once_with({
|
||||
"UefiShellStartupUrl": "http://10.10.1.30:8081/startup.nsh"
|
||||
|
@ -57,23 +60,204 @@ class IloRisTestCase(unittest.TestCase):
|
|||
def test_get_http_boot_url_bios(self, _validate_uefi_boot_mode_mock):
|
||||
_validate_uefi_boot_mode_mock.return_value = False
|
||||
self.assertRaises(exception.IloCommandNotSupportedInBiosError,
|
||||
self.ilo.get_http_boot_url)
|
||||
self.client.get_http_boot_url)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_validate_uefi_boot_mode')
|
||||
def test_set_http_boot_url_bios(self, _validate_uefi_boot_mode_mock):
|
||||
_validate_uefi_boot_mode_mock.return_value = False
|
||||
self.assertRaises(exception.IloCommandNotSupportedInBiosError,
|
||||
self.ilo.set_http_boot_url,
|
||||
self.client.set_http_boot_url,
|
||||
'http://10.10.1.30:8081/startup.nsh')
|
||||
|
||||
|
||||
class TestRISOperationsPrivateMethods(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRISOperationsPrivateMethods, self).setUp()
|
||||
self.client = ris.RISOperations("1.2.3.4", "admin", "Admin")
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_current_boot_mode')
|
||||
def test__validate_uefi_boot_mode_uefi(self, get_current_boot_mode_mock):
|
||||
get_current_boot_mode_mock.return_value = 'UEFI'
|
||||
result = self.ilo._validate_uefi_boot_mode()
|
||||
result = self.client._validate_uefi_boot_mode()
|
||||
self.assertTrue(result)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_current_boot_mode')
|
||||
def test__validate_uefi_boot_mode_bios(self, get_current_boot_mode_mock):
|
||||
get_current_boot_mode_mock.return_value = 'LEGACY'
|
||||
result = self.ilo._validate_uefi_boot_mode()
|
||||
result = self.client._validate_uefi_boot_mode()
|
||||
self.assertFalse(result)
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_okay(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj = mock.MagicMock(status=200)
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.return_value = response_mock_obj
|
||||
|
||||
sample_response_body = ris_outputs.RESPONSE_BODY_FOR_REST_OP
|
||||
response_mock_obj.read.return_value = sample_response_body
|
||||
|
||||
sample_headers = ris_outputs.HEADERS_FOR_REST_OP
|
||||
response_mock_obj.getheaders.return_value = sample_headers
|
||||
exp_headers = dict((x.lower(), y) for x, y in sample_headers)
|
||||
|
||||
status, headers, response = self.client._rest_op(
|
||||
'GET', '/v1/foo', None, None)
|
||||
|
||||
self.assertEqual(200, status)
|
||||
self.assertEqual(exp_headers, headers)
|
||||
self.assertEqual(json.loads(sample_response_body), response)
|
||||
|
||||
https_con_mock.assert_called_once_with(host='1.2.3.4', strict=True)
|
||||
connection_mock_obj.request.assert_called_once_with(
|
||||
'GET', '/v1/foo',
|
||||
# base64 encoded username + password for admin/Admin
|
||||
headers={'Authorization': 'BASIC YWRtaW46QWRtaW4='},
|
||||
body="null")
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_request_error(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.request.side_effect = RuntimeError("boom")
|
||||
exc = self.assertRaises(exception.IloConnectionError,
|
||||
self.client._rest_op,
|
||||
'GET', '/v1/foo', {}, None)
|
||||
https_con_mock.assert_called_once_with(host='1.2.3.4', strict=True)
|
||||
self.assertIn("boom", str(exc))
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_get_response_error(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.side_effect = RuntimeError("boom")
|
||||
exc = self.assertRaises(exception.IloConnectionError,
|
||||
self.client._rest_op,
|
||||
'GET', '/v1/foo', None, None)
|
||||
https_con_mock.assert_called_once_with(host='1.2.3.4', strict=True)
|
||||
connection_mock_obj.request.assert_called_once_with(
|
||||
'GET', '/v1/foo',
|
||||
headers={'Authorization': 'BASIC YWRtaW46QWRtaW4='},
|
||||
body="null")
|
||||
self.assertIn("boom", str(exc))
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_response_read_error(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj = mock.MagicMock(status=200)
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.return_value = response_mock_obj
|
||||
response_mock_obj.read.side_effect = RuntimeError("boom")
|
||||
exc = self.assertRaises(exception.IloConnectionError,
|
||||
self.client._rest_op,
|
||||
'GET', '/v1/foo', None, None)
|
||||
self.assertIn("boom", str(exc))
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_continous_redirection(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj = mock.MagicMock(status=301)
|
||||
https_con_mock.side_effect = [connection_mock_obj,
|
||||
connection_mock_obj,
|
||||
connection_mock_obj,
|
||||
connection_mock_obj,
|
||||
connection_mock_obj]
|
||||
|
||||
connection_mock_obj.getresponse.return_value = response_mock_obj
|
||||
|
||||
sample_response_body = ris_outputs.RESPONSE_BODY_FOR_REST_OP
|
||||
response_mock_obj.read.return_value = sample_response_body
|
||||
|
||||
sample_headers = ris_outputs.HEADERS_FOR_REST_OP
|
||||
sample_headers.append(('location', 'https://foo'))
|
||||
response_mock_obj.getheaders.return_value = sample_headers
|
||||
|
||||
exc = self.assertRaises(exception.IloConnectionError,
|
||||
self.client._rest_op,
|
||||
'GET', '/v1/foo', {}, None)
|
||||
self.assertEqual(5, https_con_mock.call_count)
|
||||
self.assertEqual(5, connection_mock_obj.request.call_count)
|
||||
self.assertIn('https://1.2.3.4/v1/foo', str(exc))
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPConnection')
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_one_redirection(self, https_con_mock,
|
||||
http_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj1 = mock.MagicMock(status=301)
|
||||
response_mock_obj2 = mock.MagicMock(status=200)
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
http_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.side_effect = [response_mock_obj1,
|
||||
response_mock_obj2]
|
||||
|
||||
sample_response_body = ris_outputs.RESPONSE_BODY_FOR_REST_OP
|
||||
response_mock_obj1.read.return_value = sample_response_body
|
||||
response_mock_obj2.read.return_value = sample_response_body
|
||||
|
||||
sample_headers1 = ris_outputs.HEADERS_FOR_REST_OP
|
||||
sample_headers2 = ris_outputs.HEADERS_FOR_REST_OP
|
||||
sample_headers1.append(('location', 'http://5.6.7.8/v1/foo'))
|
||||
response_mock_obj1.getheaders.return_value = sample_headers1
|
||||
response_mock_obj2.getheaders.return_value = sample_headers2
|
||||
|
||||
status, headers, response = self.client._rest_op(
|
||||
'GET', '/v1/foo', {}, None)
|
||||
|
||||
exp_headers = dict((x.lower(), y) for x, y in sample_headers1)
|
||||
self.assertEqual(200, status)
|
||||
self.assertEqual(exp_headers, headers)
|
||||
self.assertEqual(json.loads(sample_response_body), response)
|
||||
|
||||
https_con_mock.assert_any_call(host='1.2.3.4', strict=True)
|
||||
http_con_mock.assert_any_call(host='5.6.7.8', strict=True)
|
||||
self.assertEqual(2, connection_mock_obj.request.call_count)
|
||||
self.assertTrue(response_mock_obj1.read.called)
|
||||
self.assertTrue(response_mock_obj2.read.called)
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_response_decode_error(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj = mock.MagicMock(status=200)
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.return_value = response_mock_obj
|
||||
|
||||
sample_response_body = "{[wrong json"
|
||||
response_mock_obj.read.return_value = sample_response_body
|
||||
|
||||
sample_headers = ris_outputs.HEADERS_FOR_REST_OP
|
||||
response_mock_obj.getheaders.return_value = sample_headers
|
||||
|
||||
self.assertRaises(exception.IloError,
|
||||
self.client._rest_op,
|
||||
'GET', '/v1/foo', {}, None)
|
||||
https_con_mock.assert_called_once_with(host='1.2.3.4', strict=True)
|
||||
connection_mock_obj.request.assert_called_once_with(
|
||||
'GET', '/v1/foo',
|
||||
# base64 encoded username + password for admin/Admin
|
||||
headers={'Authorization': 'BASIC YWRtaW46QWRtaW4='},
|
||||
body="null")
|
||||
|
||||
@mock.patch.object(httplib, 'HTTPSConnection')
|
||||
def test__rest_op_response_gzipped_response(self, https_con_mock):
|
||||
connection_mock_obj = mock.MagicMock()
|
||||
response_mock_obj = mock.MagicMock(status=200)
|
||||
https_con_mock.return_value = connection_mock_obj
|
||||
connection_mock_obj.getresponse.return_value = response_mock_obj
|
||||
|
||||
sample_response_body = ris_outputs.RESPONSE_BODY_FOR_REST_OP
|
||||
gzipped_response_body = base64.b64decode(
|
||||
ris_outputs.BASE64_GZIPPED_RESPONSE)
|
||||
response_mock_obj.read.return_value = gzipped_response_body
|
||||
|
||||
sample_headers = ris_outputs.HEADERS_FOR_REST_OP
|
||||
response_mock_obj.getheaders.return_value = sample_headers
|
||||
exp_headers = dict((x.lower(), y) for x, y in sample_headers)
|
||||
|
||||
status, headers, response = self.client._rest_op(
|
||||
'GET', '/v1/foo', {}, None)
|
||||
|
||||
self.assertEqual(200, status)
|
||||
self.assertEqual(exp_headers, headers)
|
||||
self.assertEqual(json.loads(sample_response_body), response)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
mock
|
||||
hacking>=0.9.2,<0.10
|
||||
testrepository>=0.0.18
|
||||
testtools>=0.9.36,!=1.2.0
|
||||
|
|
Loading…
Reference in New Issue