def test_valid_host_type_pass(self): """Validate the available host types.""" with mock.patch(self.REQ_FUNC, return_value=(200, self.HOST_TYPES)): self._set_args({'state': 'present', 'host_type': '0'}) host = NetAppESeriesHost() self.assertTrue(host.valid_host_type) self._set_args({'state': 'present', 'host_type': '28'}) host = NetAppESeriesHost() self.assertTrue(host.valid_host_type) self._set_args({'state': 'present', 'host_type': 'windows'}) host = NetAppESeriesHost() self.assertTrue(host.valid_host_type) self._set_args({'state': 'present', 'host_type': 'linux dm-mp'}) host = NetAppESeriesHost() self.assertTrue(host.valid_host_type)
def test_exos_config_save_modified_false(self): mock_get_startup_config_text = patch( 'ansible.modules.network.exos.exos_config.get_startup_config_text') get_startup_config_text = mock_get_startup_config_text.start() get_startup_config_text.return_value = load_fixture( 'exos_config_config.cfg') set_module_args(dict(save_when='modified')) self.execute_module(changed=False) self.assertEqual(self.run_commands.call_count, 0) self.assertEqual(self.get_config.call_count, 1) self.assertEqual(get_startup_config_text.call_count, 1) self.assertEqual(self.load_config.call_count, 0) mock_get_startup_config_text.stop()
def test_download_file_should_extract_filename_from_headers(self): filename = 'test_file.txt' response = mock.Mock() response.info.return_value = { 'Content-Disposition': 'attachment; filename="%s"' % filename } dummy, response_data = self._connection_response('File content') self.connection_mock.send.return_value = response, response_data open_mock = mock_open() with patch('%s.open' % BUILTINS_NAME, open_mock): self.ftd_plugin.download_file('/files/1', '/tmp/') open_mock.assert_called_once_with('/tmp/%s' % filename, 'wb') open_mock().write.assert_called_once_with(b'File content')
def test_get_error_lines_from_file(self): m = mock_open() m.return_value.readlines.return_value = ['this is line 1\n'] with patch('{0}.open'.format(BUILTINS), m): # this line will be found in the file self.obj.assible_pos = ('foo.yml', 1, 1) e = AssibleError(self.message, self.obj) self.assertEqual( e.message, ("This is the error message\n\nThe error appears to be in 'foo.yml': line 1, column 1, but may\nbe elsewhere in the file depending on " "the exact syntax problem.\n\nThe offending line appears to be:\n\n\nthis is line 1\n^ here\n") ) # this line will not be found, as it is out of the index range self.obj.assible_pos = ('foo.yml', 2, 1) e = AssibleError(self.message, self.obj) self.assertEqual( e.message, ("This is the error message\n\nThe error appears to be in 'foo.yml': line 2, column 1, but may\nbe elsewhere in the file depending on " "the exact syntax problem.\n\n(specified line no longer in file, maybe it changed?)") ) m = mock_open() m.return_value.readlines.return_value = ['this line has unicode \xf0\x9f\x98\xa8 in it!\n'] with patch('{0}.open'.format(BUILTINS), m): # this line will be found in the file self.obj.assible_pos = ('foo.yml', 1, 1) e = AssibleError(self.unicode_message, self.obj) self.assertEqual( e.message, ("This is an error with \xf0\x9f\x98\xa8 in it\n\nThe error appears to be in 'foo.yml': line 1, column 1, but may\nbe elsewhere in the " "file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\nthis line has unicode \xf0\x9f\x98\xa8 in it!\n^ " "here\n") )
def test_plugins__get_package_paths_with_package(self): # the _get_package_paths() call uses __import__ to load a # python library, and then uses the __file__ attribute of # the result for that to get the library path, so we mock # that here and patch the builtin to use our mocked result foo = MagicMock() bar = MagicMock() bam = MagicMock() bam.__file__ = '/path/to/my/foo/bar/bam/__init__.py' bar.bam = bam foo.return_value.bar = bar pl = PluginLoader('test', 'foo.bar.bam', 'test', 'test_plugin') with patch('{0}.__import__'.format(BUILTINS), foo): self.assertEqual(pl._get_package_paths(), ['/path/to/my/foo/bar/bam'])
def setUp(self): super(TestNxosL3InterfacesModule, self).setUp() self.mock_FACT_LEGACY_SUBSETS = patch( 'ansible.module_utils.network.nxos.facts.facts.FACT_LEGACY_SUBSETS' ) self.FACT_LEGACY_SUBSETS = self.mock_FACT_LEGACY_SUBSETS.start() self.mock_get_resource_connection_config = patch( 'ansible.module_utils.network.common.cfg.base.get_resource_connection' ) self.get_resource_connection_config = self.mock_get_resource_connection_config.start( ) self.mock_get_resource_connection_facts = patch( 'ansible.module_utils.network.common.facts.facts.get_resource_connection' ) self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start( ) self.mock_edit_config = patch( 'ansible.module_utils.network.nxos.config.l3_interfaces.l3_interfaces.L3_interfaces.edit_config' ) self.edit_config = self.mock_edit_config.start()
def setUp(self): super(TestOnyxProtocolModule, self).setUp() self.mock_get_config = patch.object( onyx_protocol.OnyxProtocolModule, "_get_protocols") self.get_config = self.mock_get_config.start() self.mock_get_ip_config = patch.object( onyx_protocol.OnyxProtocolModule, "_get_ip_routing") self.get_ip_config = self.mock_get_ip_config.start() self.mock_load_config = patch( 'ansible.module_utils.network.onyx.onyx.load_config') self.load_config = self.mock_load_config.start()
def test_update_fail(self, get_controllers, make_body): """Ensure we fail correctly on receiving a normal failure from the API.""" self._set_args() inst = NetAppESeriesIscsiInterface() # Test a 422 error with a non-busy status with self.assertRaisesRegexp(AnsibleFailJson, r".*?Failed to modify.*") as result: with mock.patch(self.REQ_FUNC, return_value=(422, mock.MagicMock())) as request: with mock.patch.object(inst, 'get_target_interface', side_effect=[{}, mock.MagicMock()]): inst.update() request.assert_called_once() # Test a 401 (authentication) error with self.assertRaisesRegexp(AnsibleFailJson, r".*?Failed to modify.*") as result: with mock.patch(self.REQ_FUNC, return_value=(401, mock.MagicMock())) as request: with mock.patch.object(inst, 'get_target_interface', side_effect=[{}, mock.MagicMock()]): inst.update() request.assert_called_once() # Test with a connection failure with self.assertRaisesRegexp(AnsibleFailJson, r".*?Connection failure.*") as result: with mock.patch(self.REQ_FUNC, side_effect=Exception()) as request: with mock.patch.object(inst, 'get_target_interface', side_effect=[{}, mock.MagicMock()]): inst.update() request.assert_called_once()
def test_update(self, get_controllers): """Validate the good path""" self._set_args() inst = NetAppESeriesIscsiInterface() with self.assertRaises(AnsibleExitJson): with mock.patch(self.REQ_FUNC, return_value=(200, "")) as request: with mock.patch.object(inst, 'get_target_interface', side_effect=[{}, mock.MagicMock()]): with mock.patch.object(inst, 'make_update_body', return_value=(True, {})): inst.update() request.assert_called_once()
def test_delete_certificate_pass(self): """Validate delete_certificate successfully completes""" self._set_args({"certificates": [self.CERTIFICATE_PATH]}) with mock.patch(self.BASE_REQUEST_FUNC, side_effect=[(200, { "version": "03.00.0000.0000" }), (200, { "runningAsProxy": False })]): certificate = NetAppESeriesClientCertificate() with mock.patch(self.REQUEST_FUNC, return_value=(200, [])): certificate.delete_certificate({"alias": "alias1"}) self._set_args({"certificates": [self.CERTIFICATE_PATH]}) with mock.patch(self.BASE_REQUEST_FUNC, side_effect=[(200, { "version": "03.00.0000.0000" }), (200, { "runningAsProxy": False })]): certificate = NetAppESeriesClientCertificate() with mock.patch(self.REQUEST_FUNC, side_effect=[(404, None), (200, [])]): certificate.delete_certificate({"alias": "alias1"})
def test_create_host_fail(self): """Verify create_host produces expected exceptions.""" def _assigned_host_ports(apply_unassigning=False): return None with self.assertRaisesRegexp(AnsibleFailJson, "Failed to create host."): with mock.patch(self.REQ_FUNC, side_effect=[(200, []), Exception()]): self._set_args({'state': 'present', 'name': 'beegfs_metadata1', 'host_type': 'windows', 'force_port': True, 'ports': [{'label': 'beegfs_metadata1_iscsi_1', 'type': 'iscsi', 'port': 'iqn.1993-08.org.debian.beegfs-storage1:01:b0621126818'}]}) host = NetAppESeriesHost() host.assigned_host_ports = _assigned_host_ports host.build_success_payload = lambda x: {} host.create_host() with self.assertRaisesRegexp(AnsibleExitJson, "Host already exists."): with mock.patch(self.REQ_FUNC, side_effect=[(200, self.EXISTING_HOSTS)]): self._set_args({'state': 'present', 'name': 'beegfs_storage1', 'host_type': 'linux dm-mp', 'force_port': True, 'ports': [{'label': 'beegfs_storage1_iscsi_0', 'type': 'iscsi', 'port': 'iqn.1993-08.org.debian.beegfs-storage1:01:b0621126818'}]}) host = NetAppESeriesHost() host.assigned_host_ports = _assigned_host_ports host.build_success_payload = lambda x: {} host.create_host()
def test_set_name(self): """Ensure we can successfully set the name""" self._set_args(dict(name="x")) expected = dict(name='y', status='online') namer = GlobalSettings() # Expecting an update with mock.patch(self.REQ_FUNC, return_value=(200, expected)) as req: with mock.patch.object(namer, 'get_name', return_value='y'): update = namer.update_name() self.assertTrue(update) # Expecting no update with mock.patch(self.REQ_FUNC, return_value=(200, expected)) as req: with mock.patch.object(namer, 'get_name', return_value='x'): update = namer.update_name() self.assertFalse(update) # Expecting an update, but no actual calls, since we're using check_mode=True namer.check_mode = True with mock.patch(self.REQ_FUNC, return_value=(200, expected)) as req: with mock.patch.object(namer, 'get_name', return_value='y'): update = namer.update_name() self.assertEquals(0, req.called) self.assertTrue(update)
def test_update_fail(self): """Verify update throws expected exception.""" # options = {"state": "enabled", "config_method": "static", "address": "192.168.1.100", "subnet_mask": "255.255.255.0", # "gateway": "192.168.1.1", "mtu": 1500} options = {"address": "192.168.1.200"} iface = {"properties": {"provider": "providerInfiniband", "ibProperties": {"ipAddressData": {"addressType": "ipv4", "ipv4Data": {"configState": "configured", "ipv4Address": "192.168.1.100"}}}}, "reference": "2201020000000000000000000000000000000000", "channel": 5, "interface_type": "ib", "controllerRef": "070000000000000000000001", "link_status": "up"} self._set_args(options) nvme = NetAppESeriesNvmeInterface() nvme.get_target_interface = lambda: iface with self.assertRaisesRegexp(AnsibleFailJson, "Failed to configure interface."): with mock.patch(self.REQ_FUNC, return_value=Exception()): nvme.update()
def test_update_fail_busy(self, get_controllers): """Ensure we fail correctly on receiving a busy response from the API.""" self._set_args() inst = NetAppESeriesIscsiInterface() with self.assertRaisesRegexp(AnsibleFailJson, r".*?busy.*") as result: with mock.patch(self.REQ_FUNC, return_value=(422, dict(retcode="3"))) as request: with mock.patch.object(inst, 'get_target_interface', side_effect=[{}, mock.MagicMock()]): with mock.patch.object(inst, 'make_update_body', return_value=(True, {})): inst.update() request.assert_called_once()
def setUp(self): super(TestOnyxOspfModule, self).setUp() self._ospf_exists = True self.mock_get_config = patch.object( onyx_ospf.OnyxOspfModule, "_get_ospf_config") self.get_config = self.mock_get_config.start() self.mock_get_interfaces_config = patch.object( onyx_ospf.OnyxOspfModule, "_get_ospf_interfaces_config") self.get_interfaces_config = self.mock_get_interfaces_config.start() self.mock_load_config = patch( 'ansible.module_utils.network.onyx.onyx.load_config') self.load_config = self.mock_load_config.start()
def test_instance_by_label_cannot_authenticate(capfd, access_token, default_args): set_module_args(default_args) module = linode_v4.initialise_module() client = LinodeClient(module.params['access_token']) target = 'linode_api4.linode_client.LinodeGroup.instances' with mock.patch(target, side_effect=LinodeApiError('foo')): with pytest.raises(SystemExit): linode_v4.maybe_instance_from_label(module, client) out, err = capfd.readouterr() results = json.loads(out) assert results['failed'] is True assert 'Unable to query the Linode API' in results['msg']
def test_controller_property_fail(self): """Verify controllers endpoint request failure causes AnsibleFailJson exception.""" initial = { "state": "enabled", "controller": "A", "port": "1", "address": "192.168.1.1", "subnet_mask": "255.255.255.1", "config_method": "static" } controller_request = [{ "physicalLocation": { "slot": 2 }, "controllerRef": "070000000000000000000002", "networkSettings": { "remoteAccessEnabled": True } }, { "physicalLocation": { "slot": 1 }, "controllerRef": "070000000000000000000001", "networkSettings": { "remoteAccessEnabled": False } }] expected = { 'A': { 'controllerRef': '070000000000000000000001', 'controllerSlot': 1, 'ssh': False }, 'B': { 'controllerRef': '070000000000000000000002', 'controllerSlot': 2, 'ssh': True } } self._set_args(initial) mgmt_interface = NetAppESeriesMgmtInterface() with self.assertRaisesRegexp( AnsibleFailJson, r"Failed to retrieve the controller settings."): with mock.patch(self.REQ_FUNC, return_value=Exception): response = mgmt_interface.get_controllers()
def test_update_configuration(self): """Validate updating the configuration""" initial = dict(alertingEnabled=True, emailServerAddress='localhost', sendAdditionalContactInformation=True, additionalContactInformation='None', emailSenderAddress='[email protected]', recipientEmailAddresses=['[email protected]']) args = dict(state='enabled', server=initial['emailServerAddress'], sender=initial['emailSenderAddress'], contact=initial['additionalContactInformation'], recipients=initial['recipientEmailAddresses']) self._set_args(**args) alerts = NetAppESeriesAlerts() alerts.is_proxy = lambda: False alerts.is_embedded_available = lambda: False # Ensure when trigger updates when each relevant field is changed with mock.patch(self.REQ_FUNC, return_value=(200, None)) as req: with mock.patch.object(alerts, 'get_configuration', return_value=initial): update = alerts.update_configuration() self.assertFalse(update) alerts.sender = '[email protected]' update = alerts.update_configuration() self.assertTrue(update) self._set_args(**args) alerts.recipients = ['[email protected]'] update = alerts.update_configuration() self.assertTrue(update) self._set_args(**args) alerts.contact = 'abc' update = alerts.update_configuration() self.assertTrue(update) self._set_args(**args) alerts.server = 'abc' update = alerts.update_configuration() self.assertTrue(update)
def test_update_configuration(self): """Validate retrieving the ASUP configuration""" self._set_args(dict(asup='enabled')) expected = dict() initial = dict(asupCapable=True, asupEnabled=True, onDemandEnabled=False, remoteDiagsEnabled=False, schedule=dict(daysOfWeek=[], dailyMinTime=0, weeklyMinTime=0, dailyMaxTime=24, weeklyMaxTime=24)) asup = Asup() with mock.patch(self.REQ_FUNC, return_value=(200, expected)) as req: with mock.patch.object(asup, 'get_configuration', return_value=initial): updated = asup.update_configuration() self.assertTrue(req.called) self.assertTrue(updated)
def test_update_configuration_request_exception(self): """Validate exception handling when request throws an exception.""" config_response = dict(asupEnabled=True, onDemandEnabled=True, remoteDiagsEnabled=True, schedule=dict(daysOfWeek=[], dailyMinTime=0, weeklyMinTime=0, dailyMaxTime=24, weeklyMaxTime=24)) self._set_args(dict(state="enabled")) asup = Asup() with self.assertRaises(Exception): with mock.patch.object(asup, 'get_configuration', return_value=config_response): with mock.patch(self.REQ_FUNC, side_effect=Exception): asup.update_configuration()
def test_parse_from_vault_1_1_file(self): vaulted_data = """$ANSIBLE_VAULT;1.1;AES256 33343734386261666161626433386662623039356366656637303939306563376130623138626165 6436333766346533353463636566313332623130383662340a393835656134633665333861393331 37666233346464636263636530626332623035633135363732623332313534306438393366323966 3135306561356164310a343937653834643433343734653137383339323330626437313562306630 3035 """ if PY3: builtins_name = 'builtins' else: builtins_name = '__builtin__' with patch(builtins_name + '.open', mock_open(read_data=vaulted_data.encode('utf-8'))): output = self._loader.load_from_file('dummy_vault.txt') self.assertEqual(output, dict(foo='bar'))
def test_get_configuration(self): """Validate retrieving the current configuration""" self._set_args(state='enabled', server='localhost', sender='[email protected]', recipients=['[email protected]']) expected = 'result' alerts = NetAppESeriesAlerts() alerts.is_proxy = lambda: False alerts.is_embedded_available = lambda: False # Expecting an update with mock.patch(self.REQ_FUNC, return_value=(200, expected)) as req: actual = alerts.get_configuration() self.assertEquals(expected, actual) self.assertEquals(req.call_count, 1)
def test_add_annotation(self): """Check that result is changed""" set_module_args({ 'category': 'test category', 'description': 'test description', 'title': 'test title', 'api_key': str(uuid.uuid4()), }) cid = '/annotation/100000' def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): data = { '_cid': cid, '_created': 1502146995, '_last_modified': 1502146995, '_last_modified_by': '/user/1000', 'category': 'test category', 'description': 'test description', 'rel_metrics': [], 'start': 1502145480, 'stop': None, 'title': 'test title', } raw = to_bytes(json.dumps(data)) resp = HTTPResponse(body=io.BytesIO(raw), preload_content=False) resp.status = 200 resp.reason = 'OK' resp.headers = {'X-Circonus-API-Version': '2.00'} return self.build_response(request, resp) with patch('requests.adapters.HTTPAdapter.send', autospec=True, side_effect=send) as send: with self.assertRaises(AnsibleExitJson) as result: self.module.main() self.assertTrue(result.exception.args[0]['changed']) self.assertEqual(result.exception.args[0]['annotation']['_cid'], cid) self.assertEqual(send.call_count, 1)
def test_get_controllers_pass(self): """Verify dictionary return from get_controllers.""" initial = { "state": "enabled", "controller": "A", "port": "1", "address": "192.168.1.1", "subnet_mask": "255.255.255.1", "config_method": "static" } controller_request = [{ "physicalLocation": { "slot": 2 }, "controllerRef": "070000000000000000000002", "networkSettings": { "remoteAccessEnabled": True } }, { "physicalLocation": { "slot": 1 }, "controllerRef": "070000000000000000000001", "networkSettings": { "remoteAccessEnabled": False } }] expected = { 'A': { 'controllerRef': '070000000000000000000001', 'controllerSlot': 1, 'ssh': False }, 'B': { 'controllerRef': '070000000000000000000002', 'controllerSlot': 2, 'ssh': True } } self._set_args(initial) mgmt_interface = NetAppESeriesMgmtInterface() with mock.patch(self.REQ_FUNC, return_value=(200, controller_request)): response = mgmt_interface.get_controllers() self.assertTrue(response == expected)
def test_no_change_required_pass(self): """Validate is_change_required properly reports false.""" options_list = [{ "servers": [] }, { "servers": [{ "address": "192.168.1.100" }] }, { "servers": [{ "address": "192.168.1.101", "port": 1000 }, { "address": "192.168.1.100", "port": 514 }] }] current_config_list = [{ "syslogReceivers": [] }, { "syslogReceivers": [{ "serverName": "192.168.1.100", "portNumber": 514 }] }, { "syslogReceivers": [{ "serverName": "192.168.1.100", "portNumber": 514 }, { "serverName": "192.168.1.101", "portNumber": 1000 }] }] for index in range(3): self._set_args(options_list[index]) with mock.patch(self.BASE_REQ_FUNC, side_effect=[(200, { "version": "04.00.00.00" }), (200, { "runningAsProxy": False })]): syslog = NetAppESeriesAlertsSyslog() syslog.get_current_configuration = lambda: current_config_list[ index] self.assertFalse(syslog.is_change_required())
def test_apply_target_changes_fail(self): """Ensure apply_iscsi_settings fails properly.""" self._set_args({ "name": "target_name", "ping": True, "unnamed_discovery": True }) iscsi_target = NetAppESeriesIscsiTarget() with self.assertRaisesRegexp( AnsibleFailJson, r"Failed to update the iSCSI target settings."): with mock.patch(self.REQ_FUNC, side_effect=[(200, self.TARGET_REQUEST_RESPONSE), (200, self.ISCSI_ENTRY_DATA_RESPONSE), Exception()]): iscsi_target.apply_target_changes()
def test_instance_already_deleted_no_change(default_args, mock_linode, capfd, access_token): default_args.update({'state': 'absent'}) set_module_args(default_args) target = 'linode_api4.linode_client.LinodeGroup.instances' with mock.patch(target, return_value=[]): with pytest.raises(SystemExit) as sys_exit_exc: linode_v4.main() assert sys_exit_exc.value.code == 0 out, err = capfd.readouterr() results = json.loads(out) assert results['changed'] is False assert results['instance'] == {}
def test_proxy_upload_and_check_compatibility_fail(self): """Verify proxy_upload_and_check_compatibility throws expected exceptions.""" self._set_args({ "firmware": "test_firmware.dlp", "nvsram": "test_nvsram.dlp" }) firmware = NetAppESeriesFirmware() firmware.proxy_check_nvsram_compatibility = lambda: None firmware.proxy_check_firmware_compatibility = lambda: None with self.assertRaisesRegexp( AnsibleFailJson, "Failed to retrieve existing firmware files."): with patch(self.CREATE_MULTIPART_FORMDATA_FUNC, return_value=("headers", "data")): with patch(self.REQUEST_FUNC, return_value=Exception()): firmware.proxy_upload_and_check_compatibility() with self.assertRaisesRegexp(AnsibleFailJson, "Failed to upload NVSRAM file."): with patch(self.CREATE_MULTIPART_FORMDATA_FUNC, return_value=("headers", "data")): with patch(self.REQUEST_FUNC, side_effect=[(200, [{ "version": "XX.XX.XX.XX", "filename": "test" }, { "version": "XXXXXXXXXX", "filename": "test.dlp" }, { "filename": "test_firmware.dlp", "version": "test_firmware" }]), Exception()]): firmware.proxy_upload_and_check_compatibility() with self.assertRaisesRegexp(AnsibleFailJson, "Failed to upload firmware bundle file."): with patch(self.CREATE_MULTIPART_FORMDATA_FUNC, return_value=("headers", "data")): with patch(self.REQUEST_FUNC, side_effect=[(200, [{ "version": "XX.XX.XX.XX", "filename": "test" }, { "version": "test_nvsram", "filename": "test_nvsram.dlp" }, { "version": "XXXXXXXXXX", "filename": "test.dlp" }]), Exception()]): firmware.proxy_upload_and_check_compatibility()
def test_nitro_user_pass_credentials(self): args = copy.deepcopy(module_arguments) args.update(dict( nitro_user='******', nitro_pass='******', )) mock_module_instance = Mock(params=args) expected_headers = { 'Content-Type': 'application/json', 'X-NITRO-USER': '******', 'X-NITRO-PASS': '******', } module_mock = Mock(return_value=mock_module_instance) with patch( 'ansible.modules.network.netscaler.netscaler_nitro_request.AnsibleModule', module_mock): instance = netscaler_nitro_request.NitroAPICaller() self.assertDictEqual(instance._headers, expected_headers)
def test_upload_file(self): self.connection_mock.send.return_value = self._connection_response( {'id': '123'}) open_mock = mock_open() with patch('%s.open' % BUILTINS, open_mock): resp = self.ftd_plugin.upload_file('/tmp/test.txt', '/files') assert {'id': '123'} == resp exp_headers = dict(EXPECTED_BASE_HEADERS) exp_headers['Content-Length'] = len('--Encoded data--') exp_headers['Content-Type'] = 'multipart/form-data' self.connection_mock.send.assert_called_once_with( '/files', data='--Encoded data--', headers=exp_headers, method=HTTPMethod.POST) open_mock.assert_called_once_with('/tmp/test.txt', 'rb')