From 4e25b350345f534edd24476ea3069409bda3f64f Mon Sep 17 00:00:00 2001 From: Stavros Sachtouris Date: Tue, 10 Dec 2013 15:24:58 +0200 Subject: [PATCH] Fix unittests in kamaki.clients, subnet arg bug --- docs/commands.rst | 9 +- kamaki/cli/commands/network.py | 29 ++- kamaki/cli/commands/pithos.py | 6 + kamaki/clients/cyclades/__init__.py | 66 +----- kamaki/clients/cyclades/rest_api.py | 107 +--------- kamaki/clients/cyclades/test.py | 393 +---------------------------------- kamaki/clients/network/test.py | 6 +- kamaki/clients/pithos/test.py | 20 +- kamaki/clients/utils/test.py | 43 +--- 9 files changed, 69 insertions(+), 610 deletions(-) diff --git a/docs/commands.rst b/docs/commands.rst index 9576561..64c6f20 100644 --- a/docs/commands.rst +++ b/docs/commands.rst @@ -8,9 +8,8 @@ Kamaki commands follow this scheme:: In this context, objects are not services, but virtual objects like a server, a file or an image. The action concerns objects of the specified type. Some actions (e.g. "delete" or "info") need to operate on an existing object. The -identifiers strictly identify this object and they can have the form of an id -(e.g., `server delete `) or a foreign key (e.g., -`port create `) +identifiers strictly identify this object and they should have the form of an id +(e.g., `server delete `). The examples bellow showcase some commands. The kamaki-shell (check `Usage section `_ for details) is chosen as the @@ -351,7 +350,7 @@ Showcase: Connect a network to a VM * Try network-connect (to get help) * [network]: connect Syntax error - usage: connect [-s] [-h] [-i] [--config CONFIG] + usage: connect --device-id [-s] [-h] [-i] [--config CONFIG] Connect a server to a network @@ -364,7 +363,7 @@ Showcase: Connect a network to a VM -v,--verbose: More info at response * Connect VM with id 11687 to network with id 1409 - [network]: connect 11687 1409 --wait + [network]: connect 11687 --device-id=1409 --wait Creating port between network 1409 and server 11687 New port: 8 diff --git a/kamaki/cli/commands/network.py b/kamaki/cli/commands/network.py index da5ca7e..7855b47 100644 --- a/kamaki/cli/commands/network.py +++ b/kamaki/cli/commands/network.py @@ -55,8 +55,9 @@ _commands = [network_cmds, port_cmds, subnet_cmds, ip_cmds] about_authentication = '\nUser Authentication:\ - \n* to check authentication: /user authenticate\ - \n* to set authentication token: /config set cloud..token ' + \n to check authentication: [kamaki] ]user authenticate\ + \n to set authentication token: \ + [kamaki] config set cloud..token ' class _port_wait(_service_wait): @@ -292,6 +293,8 @@ class AllocationPoolArgument(RepeatableArgument): @value.setter def value(self, new_pools): + if not new_pools: + return new_list = [] for pool in new_pools: start, comma, end = pool.partition(',') @@ -635,7 +638,11 @@ class network_connect(_port_create): ip_address=ValueArgument( 'IP address for subnet id (used with --subnet-id', '--ip-address'), wait=FlagArgument('Wait network to connect', ('-w', '--wait')), + device_id=RepeatableArgument( + 'Connect this device to the network (can be repeated)', + '--device-id') ) + required = ('device_id', ) @errors.generic.all @errors.cyclades.connection @@ -646,9 +653,10 @@ class network_connect(_port_create): network_id, server_id)) self.connect(network_id, server_id) - def main(self, network_id, device_id): + def main(self, network_id): super(self.__class__, self)._run() - self._run(network_id=network_id, server_id=device_id) + for sid in self['device_id']: + self._run(network_id=network_id, server_id=sid) @command(network_cmds) @@ -663,8 +671,12 @@ class network_disconnect(_init_network, _port_wait, _optional_json): return CycladesClient(URL, self.client.token) arguments = dict( - wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')) + wait=FlagArgument('Wait network to disconnect', ('-w', '--wait')), + device_id=RepeatableArgument( + 'Disconnect device from the network (can be repeated)', + '--device-id') ) + required = ('device_id', ) @errors.generic.all @errors.cyclades.connection @@ -673,7 +685,7 @@ class network_disconnect(_init_network, _port_wait, _optional_json): def _run(self, network_id, server_id): vm = self._cyclades_client().get_server_details(server_id) ports = [port for port in vm['attachments'] if ( - port['network_id'] not in ('network_id', ))] + port['network_id'] in (network_id, ))] if not ports: raiseCLIError('Network %s is not connected to device %s' % ( network_id, server_id)) @@ -692,6 +704,7 @@ class network_disconnect(_init_network, _port_wait, _optional_json): raise self.error('Port %s is deleted' % port['id']) - def main(self, network_id, device_id): + def main(self, network_id): super(self.__class__, self)._run() - self._run(network_id=network_id, server_id=device_id) + for sid in self['device_id']: + self._run(network_id=network_id, server_id=sid) diff --git a/kamaki/cli/commands/pithos.py b/kamaki/cli/commands/pithos.py index 598aad5..cc7f15b 100644 --- a/kamaki/cli/commands/pithos.py +++ b/kamaki/cli/commands/pithos.py @@ -300,6 +300,12 @@ class file_list(_pithos_container, _optional_json, _name_filter): if_unmodified_since=self['if_unmodified_since'], until=self['until'], meta=self['meta']) + + # REMOVE THIS if version >> 0.12 + if not r.json: + self.error(' NOTE: Since v0.12, use / for containers e.g.,') + self.error(' [kamaki] file list /pithos') + files = self._filter_by_name(r.json) if self['more']: outbu, self._out = self._out, StringIO() diff --git a/kamaki/clients/cyclades/__init__.py b/kamaki/clients/cyclades/__init__.py index 96ca6b4..7dd7dd2 100644 --- a/kamaki/clients/cyclades/__init__.py +++ b/kamaki/clients/cyclades/__init__.py @@ -112,44 +112,6 @@ class CycladesClient(CycladesRestClient, Waiter): r = self.servers_action_post(server_id, json_data=req, success=200) return r.json['console'] - def get_firewall_profile(self, server_id): - """ - :param server_id: integer (str or int) - - :returns: (str) ENABLED | DISABLED | PROTECTED - - :raises ClientError: 520 No Firewall Profile - """ - r = self.get_server_details(server_id) - try: - return r['attachments'][0]['firewallProfile'] - except KeyError: - raise ClientError( - 'No Firewall Profile', - details='Server %s is missing a firewall profile' % server_id) - - def set_firewall_profile(self, server_id, profile): - """Set the firewall profile for the public interface of a server - - :param server_id: integer (str or int) - - :param profile: (str) ENABLED | DISABLED | PROTECTED - - :returns: (dict) response headers - """ - req = {'firewallProfile': {'profile': profile}} - r = self.servers_action_post(server_id, json_data=req, success=202) - return r.headers - - def list_server_nics(self, server_id): - """ - :param server_id: integer (str or int) - - :returns: (dict) network interface connections - """ - r = self.servers_ips_get(server_id) - return r.json['attachments'] - def get_server_stats(self, server_id): """ :param server_id: integer (str or int) @@ -186,30 +148,6 @@ class CycladesClient(CycladesRestClient, Waiter): return self._wait( server_id, current_status, get_status, delay, max_wait, wait_cb) - def wait_firewall( - self, server_id, - current_status='DISABLED', delay=1, max_wait=100, wait_cb=None): - """Wait while the public network firewall status is current_status - - :param server_id: integer (str or int) - - :param current_status: (str) DISABLED | ENABLED | PROTECTED - - :param delay: time interval between retries - - :max_wait: (int) timeout in secconds - - :param wait_cb: if set a progressbar is used to show progress - - :returns: (str) the new mode if succesfull, (bool) False if timed out - """ - - def get_status(self, server_id): - return self.get_firewall_profile(server_id), None - - return self._wait( - server_id, current_status, get_status, delay, max_wait, wait_cb) - class CycladesNetworkClient(NetworkClient): """Cyclades Network API extentions""" @@ -252,9 +190,7 @@ class CycladesNetworkClient(NetworkClient): if fixed_ips: for fixed_ip in fixed_ips or []: if not 'ip_address' in fixed_ip: - raise ValueError( - 'Invalid format for "fixed_ips"', details=[ - 'fixed_ips format: [{"ip_address": IPv4}, ...]']) + raise ValueError('Invalid fixed_ip [%s]' % fixed_ip) port['fixed_ips'] = fixed_ips r = self.ports_post(json_data=dict(port=port), success=201) return r.json['port'] diff --git a/kamaki/clients/cyclades/rest_api.py b/kamaki/clients/cyclades/rest_api.py index 55852da..0bb4a90 100644 --- a/kamaki/clients/cyclades/rest_api.py +++ b/kamaki/clients/cyclades/rest_api.py @@ -33,115 +33,12 @@ from kamaki.clients.compute import ComputeClient from kamaki.clients.utils import path4url -import json class CycladesRestClient(ComputeClient): """Synnefo Cyclades REST API Client""" - def servers_stats_get(self, server_id, success=200, **kwargs): + def servers_stats_get(self, server_id, **kwargs): """GET base_url/servers//stats""" path = path4url('servers', server_id, 'stats') - return self.get(path, success=success, **kwargs) - - # def networks_get( - # self, - # network_id='', - # command='', - # success=(200, 203), - # **kwargs): - # """GET base_url/networks[/network_id][/command] request - - # :param network_id: integer (str or int) - - # :param command: (str) 'detail' or '' - - # :param success: success code or list or tuple of accepted success - # codes. if server response code is not in this list, a ClientError - # raises - - # :returns: request response - # """ - # path = path4url('networks', network_id, command) - # return self.get(path, success=success, **kwargs) - - # def networks_delete( - # self, - # network_id='', - # command='', - # success=204, - # **kwargs): - # """DEL ETE base_url/networks[/network_id][/command] request - - # :param network_id: integer (str or int) - - # :param command: (str) 'detail' or '' - - # :param success: success code or list or tuple of accepted success - # codes. if server response code is not in this list, a ClientError - # raises - - # :returns: request response - # """ - # path = path4url('networks', network_id, command) - # return self.delete(path, success=success, **kwargs) - - # def networks_post( - # self, - # network_id='', - # command='', - # json_data=None, - # success=202, - # **kwargs): - # """POST base_url/servers[/server_id]/[command] request - - # :param network_id: integer (str or int) - - # :param command: (str) 'detail' or '' - - # :param json_data: (dict) will be send as data - - # :param success: success code or list or tuple of accepted success - # codes. if server response code is not in this list, a ClientError - # raises - - # :returns: request response - # """ - # data = json_data - # if json_data is not None: - # data = json.dumps(json_data) - # self.set_header('Content-Type', 'application/json') - # self.set_header('Content-Length', len(data)) - - # path = path4url('networks', network_id, command) - # return self.post(path, data=data, success=success, **kwargs) - - # def networks_put( - # self, - # network_id='', - # command='', - # json_data=None, - # success=204, - # **kwargs): - # """PUT base_url/servers[/server_id]/[command] request - - # :param network_id: integer (str or int) - - # :param command: (str) 'detail' or '' - - # :param json_data: (dict) will be send as data - - # :param success: success code or list or tuple of accepted success - # codes. if server response code is not in this list, a ClientError - # raises - - # :returns: request response - # """ - # data = json_data - # if json_data is not None: - # data = json.dumps(json_data) - # self.set_header('Content-Type', 'application/json') - # self.set_header('Content-Length', len(data)) - - # path = path4url('networks', network_id, command) - # return self.put(path, data=data, success=success, **kwargs) + return self.get(path, success=200, **kwargs) diff --git a/kamaki/clients/cyclades/test.py b/kamaki/clients/cyclades/test.py index 6026869..d96817d 100644 --- a/kamaki/clients/cyclades/test.py +++ b/kamaki/clients/cyclades/test.py @@ -94,149 +94,17 @@ cyclades_pkg = 'kamaki.clients.cyclades.CycladesClient' class CycladesRestClient(TestCase): - """Set up a Cyclades thorough test""" def setUp(self): self.url = 'http://cyclades.example.com' self.token = 'cyc14d3s70k3n' self.client = cyclades.CycladesRestClient(self.url, self.token) - def tearDown(self): - FR.json = vm_recv - - @patch('%s.get' % rest_pkg, return_value=FR()) - def test_networks_get(self, get): - for args in product( - ('', 'net_id'), - ('', 'cmd'), - (200, 204), - ({}, {'k': 'v'})): - (srv_id, command, success, kwargs) = args - self.client.networks_get(*args[:3], **kwargs) - srv_str = '/%s' % srv_id if srv_id else '' - cmd_str = '/%s' % command if command else '' - self.assertEqual(get.mock_calls[-1], call( - '/networks%s%s' % (srv_str, cmd_str), - success=success, - **kwargs)) - - @patch('%s.delete' % rest_pkg, return_value=FR()) - def test_networks_delete(self, delete): - for args in product( - ('', 'net_id'), - ('', 'cmd'), - (202, 204), - ({}, {'k': 'v'})): - (srv_id, command, success, kwargs) = args - self.client.networks_delete(*args[:3], **kwargs) - srv_str = '/%s' % srv_id if srv_id else '' - cmd_str = '/%s' % command if command else '' - self.assertEqual(delete.mock_calls[-1], call( - '/networks%s%s' % (srv_str, cmd_str), - success=success, - **kwargs)) - - @patch('%s.set_header' % rest_pkg) - @patch('%s.post' % rest_pkg, return_value=FR()) - def test_networks_post(self, post, SH): - for args in product( - ('', 'net_id'), - ('', 'cmd'), - (None, [dict(json="data"), dict(data="json")]), - (202, 204), - ({}, {'k': 'v'})): - (srv_id, command, json_data, success, kwargs) = args - self.client.networks_post(*args[:4], **kwargs) - vm_str = '/%s' % srv_id if srv_id else '' - cmd_str = '/%s' % command if command else '' - if json_data: - json_data = dumps(json_data) - self.assertEqual(SH.mock_calls[-2:], [ - call('Content-Type', 'application/json'), - call('Content-Length', len(json_data))]) - self.assertEqual(post.mock_calls[-1], call( - '/networks%s%s' % (vm_str, cmd_str), - data=json_data, success=success, - **kwargs)) - - @patch('%s.set_header' % rest_pkg) - @patch('%s.put' % rest_pkg, return_value=FR()) - def test_networks_put(self, put, SH): - for args in product( - ('', 'net_id'), - ('', 'cmd'), - (None, [dict(json="data"), dict(data="json")]), - (202, 204), - ({}, {'k': 'v'})): - (srv_id, command, json_data, success, kwargs) = args - self.client.networks_put(*args[:4], **kwargs) - vm_str = '/%s' % srv_id if srv_id else '' - cmd_str = '/%s' % command if command else '' - if json_data: - json_data = dumps(json_data) - self.assertEqual(SH.mock_calls[-2:], [ - call('Content-Type', 'application/json'), - call('Content-Length', len(json_data))]) - self.assertEqual(put.mock_calls[-1], call( - '/networks%s%s' % (vm_str, cmd_str), - data=json_data, success=success, - **kwargs)) - - @patch('%s.get' % rest_pkg, return_value=FR()) - def test_floating_ip_pools_get(self, get): - for args in product( - (200, 204), - ({}, {'k': 'v'})): - success, kwargs = args - r = self.client.floating_ip_pools_get(success, **kwargs) - self.assertTrue(isinstance(r, FR)) - self.assertEqual(get.mock_calls[-1], call( - '/os-floating-ip-pools', success=success, **kwargs)) - - @patch('%s.get' % rest_pkg, return_value=FR()) - def test_floating_ips_get(self, get): - for args in product( - ('fip', ''), - (200, 204), - ({}, {'k': 'v'})): - fip, success, kwargs = args - r = self.client.floating_ips_get(fip, success, **kwargs) - self.assertTrue(isinstance(r, FR)) - expected = '' if not fip else '/%s' % fip - self.assertEqual(get.mock_calls[-1], call( - '/os-floating-ips%s' % expected, success=success, **kwargs)) - - @patch('%s.set_header' % rest_pkg) - @patch('%s.post' % rest_pkg, return_value=FR()) - def test_floating_ips_post(self, post, SH): - for args in product( - (None, [dict(json="data"), dict(data="json")]), - ('fip', ''), - (202, 204), - ({}, {'k': 'v'})): - json_data, fip, success, kwargs = args - self.client.floating_ips_post(*args[:3], **kwargs) - if json_data: - json_data = dumps(json_data) - self.assertEqual(SH.mock_calls[-2:], [ - call('Content-Type', 'application/json'), - call('Content-Length', len(json_data))]) - expected = '' if not fip else '/%s' % fip - self.assertEqual(post.mock_calls[-1], call( - '/os-floating-ips%s' % expected, - data=json_data, success=success, - **kwargs)) - - @patch('%s.delete' % rest_pkg, return_value=FR()) - def test_floating_ips_delete(self, delete): - for args in product( - ('fip1', 'fip2'), - (200, 204), - ({}, {'k': 'v'})): - fip, success, kwargs = args - r = self.client.floating_ips_delete(fip, success, **kwargs) - self.assertTrue(isinstance(r, FR)) - self.assertEqual(delete.mock_calls[-1], call( - '/os-floating-ips/%s' % fip, success=success, **kwargs)) + @patch('kamaki.clients.Client.get', return_value='ret') + def test_servers_stats_get(self, get): + server_id = 'server id' + self.assertEqual(self.client.servers_stats_get(server_id), 'ret') + get.assert_called_once_with( + '/servers/%s/stats' % server_id, success=200) class CycladesNetworkClient(TestCase): @@ -286,12 +154,12 @@ class CycladesNetworkClient(TestCase): ('port name', None), ([1, 2, 3], None), ( - dict(subnet_id='sid', ip_address='ipa'), - dict(subnet_id='sid'), dict(ip_address='ipa'), + [dict(subnet_id='sid', ip_address='ipa')], + [dict(subnet_id='sid')], [dict(ip_address='ipa')], None)): if fixed_ips: - diff = set(['subnet_id', 'ip_address']).difference(fixed_ips) + diff = set(['ip_address', ]).difference(fixed_ips[0]) if diff: self.assertRaises( ValueError, self.client.create_port, @@ -360,249 +228,6 @@ class CycladesClient(TestCase): vm_id, json_data=dict(console=dict(type='vnc')), success=200) self.assert_dicts_are_equal(r, cnsl['console']) - def test_get_firewall_profile(self): - vm_id = vm_recv['server']['id'] - v = firewalls['attachments'][0]['firewallProfile'] - with patch.object( - cyclades.CycladesClient, 'get_server_details', - return_value=firewalls) as GSD: - r = self.client.get_firewall_profile(vm_id) - GSD.assert_called_once_with(vm_id) - self.assertEqual(r, v) - with patch.object( - cyclades.CycladesClient, 'get_server_details', - return_value=dict()): - self.assertRaises( - ClientError, - self.client.get_firewall_profile, - vm_id) - - @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR()) - def test_set_firewall_profile(self, SP): - vm_id = vm_recv['server']['id'] - v = firewalls['attachments'][0]['firewallProfile'] - self.client.set_firewall_profile(vm_id, v) - SP.assert_called_once_with(vm_id, json_data=dict( - firewallProfile=dict(profile=v)), success=202) - - @patch('%s.networks_post' % cyclades_pkg, return_value=FR()) - def test_create_network(self, NP): - net_name = net_send['network']['name'] - FR.json = net_recv - full_args = dict( - cidr='192.168.0.0/24', - gateway='192.168.0.1', - type='MAC_FILTERED', - dhcp=True) - test_args = dict(full_args) - test_args.update(dict(empty=None, full=None)) - net_exp = dict(dhcp=False, name=net_name, type='MAC_FILTERED') - for arg, val in test_args.items(): - kwargs = {} if arg == 'empty' else full_args if ( - arg == 'full') else {arg: val} - expected = dict(network=dict(net_exp)) - expected['network'].update(kwargs) - r = self.client.create_network(net_name, **kwargs) - self.assertEqual( - NP.mock_calls[-1], - call(json_data=expected, success=202)) - self.assert_dicts_are_equal(r, net_recv['network']) - - @patch('%s.networks_post' % cyclades_pkg, return_value=FR()) - def test_connect_server(self, NP): - vm_id = vm_recv['server']['id'] - net_id = net_recv['network']['id'] - self.client.connect_server(vm_id, net_id) - NP.assert_called_once_with( - net_id, 'action', - json_data=dict(add=dict(serverRef=vm_id))) - - @patch('%s.networks_post' % cyclades_pkg, return_value=FR()) - def test_disconnect_server(self, NP): - net_id, vm_id = net_recv['network']['id'], vm_recv['server']['id'] - nic_id = 'nic-%s-%s' % (net_id, vm_id) - vm_nics = [ - dict(id=nic_id, network_id=net_id), - dict(id='another-nic-id', network_id='another-net-id'), - dict(id=nic_id * 2, network_id=net_id * 2)] - with patch.object( - cyclades.CycladesClient, - 'list_server_nics', - return_value=vm_nics) as LSN: - r = self.client.disconnect_server(vm_id, nic_id) - LSN.assert_called_once_with(vm_id) - NP.assert_called_once_with( - net_id, 'action', - json_data=dict(remove=dict(attachment=nic_id))) - self.assertEqual(r, 1) - - @patch('%s.servers_ips_get' % cyclades_pkg, return_value=FR()) - def test_list_server_nics(self, SG): - vm_id = vm_recv['server']['id'] - nics = dict(attachments=[dict(id='nic1'), dict(id='nic2')]) - FR.json = nics - r = self.client.list_server_nics(vm_id) - SG.assert_called_once_with(vm_id) - expected = nics['attachments'] - for i in range(len(r)): - self.assert_dicts_are_equal(r[i], expected[i]) - self.assertEqual(i + 1, len(r)) - - @patch('%s.networks_get' % cyclades_pkg, return_value=FR()) - def test_list_networks(self, NG): - FR.json = net_list - expected = net_list['networks'] - for detail in ('', 'detail'): - r = self.client.list_networks(detail=True if detail else False) - self.assertEqual(NG.mock_calls[-1], call(command=detail)) - for i, net in enumerate(expected): - self.assert_dicts_are_equal(r[i], net) - self.assertEqual(i + 1, len(r)) - - @patch('%s.networks_get' % cyclades_pkg, return_value=FR()) - def test_list_network_nics(self, NG): - net_id = net_recv['network']['id'] - FR.json = net_recv - r = self.client.list_network_nics(net_id) - NG.assert_called_once_with(network_id=net_id) - expected = net_recv['network']['attachments'] - for i in range(len(r)): - self.assert_dicts_are_equal(r[i], expected[i]) - - @patch('%s.networks_post' % cyclades_pkg, return_value=FR()) - def test_disconnect_network_nics(self, NP): - net_id = net_recv['network']['id'] - nics = ['nic1', 'nic2', 'nic3'] - with patch.object( - cyclades.CycladesClient, - 'list_network_nics', - return_value=nics) as LNN: - self.client.disconnect_network_nics(net_id) - LNN.assert_called_once_with(net_id) - for i in range(len(nics)): - expected = call(net_id, 'action', json_data=dict( - remove=dict(attachment=nics[i]))) - self.assertEqual(expected, NP.mock_calls[i]) - - @patch('%s.networks_get' % cyclades_pkg, return_value=FR()) - def test_get_network_details(self, NG): - FR.json = net_recv - net_id = net_recv['network']['id'] - r = self.client.get_network_details(net_id) - NG.assert_called_once_with(network_id=net_id) - self.assert_dicts_are_equal(r, net_recv['network']) - - @patch('%s.networks_put' % cyclades_pkg, return_value=FR()) - def test_update_network_name(self, NP): - net_id = net_recv['network']['id'] - new_name = '%s_new' % net_id - self.client.update_network_name(net_id, new_name) - NP.assert_called_once_with( - network_id=net_id, - json_data=dict(network=dict(name=new_name))) - - def test_delete_network(self): - net_id = net_recv['network']['id'] - with patch.object( - cyclades.CycladesClient, 'networks_delete', - return_value=FR()) as ND: - self.client.delete_network(net_id) - ND.assert_called_once_with(net_id) - with patch.object( - cyclades.CycladesClient, 'networks_delete', - side_effect=ClientError('A 421 Error', 421)): - try: - self.client.delete_network(421) - except ClientError as err: - self.assertEqual(err.status, 421) - self.assertEqual(err.details, [ - 'Network may be still connected to at least one server']) - - @patch('%s.floating_ip_pools_get' % cyclades_pkg, return_value=FR()) - def test_get_floating_ip_pools(self, get): - r = self.client.get_floating_ip_pools() - self.assert_dicts_are_equal(r, FR.json) - self.assertEqual(get.mock_calls[-1], call()) - - @patch('%s.floating_ips_get' % cyclades_pkg, return_value=FR()) - def test_get_floating_ips(self, get): - r = self.client.get_floating_ips() - self.assert_dicts_are_equal(r, FR.json) - self.assertEqual(get.mock_calls[-1], call()) - - @patch('%s.floating_ips_post' % cyclades_pkg, return_value=FR()) - def test_alloc_floating_ip(self, post): - FR.json = dict(floating_ip=dict( - fixed_ip='fip', - id=1, - instance_id='lala', - ip='102.0.0.1', - pool='pisine')) - for args in product( - (None, 'pisine'), - (None, 'Iwannanip')): - r = self.client.alloc_floating_ip(*args) - pool, address = args - self.assert_dicts_are_equal(r, FR.json['floating_ip']) - json_data = dict() - if pool: - json_data['pool'] = pool - if address: - json_data['address'] = address - self.assertEqual(post.mock_calls[-1], call(json_data)) - - @patch('%s.floating_ips_get' % cyclades_pkg, return_value=FR()) - def test_get_floating_ip(self, get): - FR.json = dict(floating_ip=dict( - fixed_ip='fip', - id=1, - instance_id='lala', - ip='102.0.0.1', - pool='pisine')) - self.assertRaises(AssertionError, self.client.get_floating_ip, None) - fip = 'fip' - r = self.client.get_floating_ip(fip) - self.assert_dicts_are_equal(r, FR.json['floating_ip']) - self.assertEqual(get.mock_calls[-1], call(fip)) - - @patch('%s.floating_ips_delete' % cyclades_pkg, return_value=FR()) - def test_delete_floating_ip(self, delete): - self.assertRaises(AssertionError, self.client.delete_floating_ip, None) - fip = 'fip' - r = self.client.delete_floating_ip(fip) - self.assert_dicts_are_equal(r, FR.headers) - self.assertEqual(delete.mock_calls[-1], call(fip)) - - @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR()) - def test_attach_floating_ip(self, spost): - vmid, addr = 42, 'anIpAddress' - for err, args in { - ValueError: ['not a server id', addr], - TypeError: [None, addr], - AssertionError: [vmid, None], - AssertionError: [vmid, '']}.items(): - self.assertRaises( - err, self.client.attach_floating_ip, *args) - r = self.client.attach_floating_ip(vmid, addr) - self.assert_dicts_are_equal(r, FR.headers) - expected = dict(addFloatingIp=dict(address=addr)) - self.assertEqual(spost.mock_calls[-1], call(vmid, json_data=expected)) - - @patch('%s.servers_action_post' % cyclades_pkg, return_value=FR()) - def test_detach_floating_ip(self, spost): - vmid, addr = 42, 'anIpAddress' - for err, args in { - ValueError: ['not a server id', addr], - TypeError: [None, addr], - AssertionError: [vmid, None], - AssertionError: [vmid, '']}.items(): - self.assertRaises( - err, self.client.detach_floating_ip, *args) - r = self.client.detach_floating_ip(vmid, addr) - self.assert_dicts_are_equal(r, FR.headers) - expected = dict(removeFloatingIp=dict(address=addr)) - self.assertEqual(spost.mock_calls[-1], call(vmid, json_data=expected)) - if __name__ == '__main__': from sys import argv diff --git a/kamaki/clients/network/test.py b/kamaki/clients/network/test.py index 1a5dfcf..14bbd75 100644 --- a/kamaki/clients/network/test.py +++ b/kamaki/clients/network/test.py @@ -490,9 +490,9 @@ class NetworkClient(TestCase): 'kamaki.clients.network.NetworkClient.ports_get', return_value=FakeObject()) def test_get_port_details(self, ports_get): - portid, FakeObject.json = 'portid', dict(ports='ret val') + portid, FakeObject.json = 'portid', dict(port='ret val') self.assertEqual(self.client.get_port_details(portid), 'ret val') - ports_get.assert_called_once_with(portid, success=201) + ports_get.assert_called_once_with(portid, success=200) @patch( 'kamaki.clients.network.NetworkClient.ports_delete', @@ -523,7 +523,7 @@ class NetworkClient(TestCase): for k, v in kwargs.items(): if v: req[k] = v - expargs = dict(json_data=dict(port=req), success=201) + expargs = dict(json_data=dict(port=req), success=200) self.assertEqual( ports_put.mock_calls[-1], call(port_id, **expargs)) diff --git a/kamaki/clients/pithos/test.py b/kamaki/clients/pithos/test.py index 22fefcf..0e6df54 100644 --- a/kamaki/clients/pithos/test.py +++ b/kamaki/clients/pithos/test.py @@ -197,12 +197,13 @@ class PithosRestClient(TestCase): @patch('%s.set_header' % rest_pkg) @patch('%s.get' % rest_pkg, return_value=FR()) def test_account_get(self, get, SH, SP): - keys = ('limit', 'marker', 'format', 'shared', 'until') + keys = ('limit', 'marker', 'format', 'shared', 'public', 'until') for params in product( (None, 42), (None, 'X'), ('json', 'xml'), (False, True), + (False, True), (None, '50m3-d473'), (None, '50m3-07h3r-d473'), (None, 'y37-4n7h3r-d473'), @@ -211,11 +212,10 @@ class PithosRestClient(TestCase): args, kwargs = params[-2], params[-1] params = params[:-2] self.client.account_get(*(params + args), **kwargs) - self.assertEqual(SP.mock_calls[-5:], - [call(keys[i], iff=X) if ( - i == 3) else call( - keys[i], X, iff=X) for i, X in enumerate(params[:5])]) - IMS, IUS = params[5], params[6] + self.assertEqual(SP.mock_calls[-6:], + [call(keys[i], iff=X) if (i in (3, 4)) else call( + keys[i], X, iff=X) for i, X in enumerate(params[:6])]) + IMS, IUS = params[6], params[7] self.assertEqual(SH.mock_calls[-2:], [ call('If-Modified-Since', IMS), call('If-Unmodified-Since', IUS)]) @@ -297,6 +297,7 @@ class PithosRestClient(TestCase): ('json', 'some-format'), ([], ['k1', 'k2', 'k3']), (False, True), + (False, True), (None, 'unt1l-d473'), (None, 'y37-4n47h3r'), (None, '4n47h3r-d473'), @@ -305,12 +306,15 @@ class PithosRestClient(TestCase): args, kwargs = pm[-2:] pm = pm[:-2] self.client.container_get(*(pm + args), **kwargs) - lmt, mrk, prfx, dlm, path, frmt, meta, shr, unt = pm[:-2] + lmt, mrk, prfx, dlm, path, frmt, meta, shr, pbl, unt = pm[:-2] exp = [call('limit', lmt, iff=lmt), call('marker', mrk, iff=mrk)] exp += [call('path', path)] if path else [ call('prefix', prfx, iff=prfx), call('delimiter', dlm, iff=dlm)] - exp += [call('format', frmt, iff=frmt), call('shared', iff=shr)] + exp += [ + call('format', frmt, iff=frmt), + call('shared', iff=shr), + call('public', iff=pbl)] if meta: exp += [call('meta', ','.join(meta))] exp += [call('until', unt, iff=unt)] diff --git a/kamaki/clients/utils/test.py b/kamaki/clients/utils/test.py index 50395d5..9615335 100644 --- a/kamaki/clients/utils/test.py +++ b/kamaki/clients/utils/test.py @@ -34,6 +34,8 @@ #from mock import patch, call from unittest import TestCase +from tempfile import TemporaryFile + from kamaki.clients import utils @@ -128,38 +130,15 @@ class Utils(TestCase): self.assertEqual(utils.path4url(*args), expected) def test_readall(self): - - class fakefile(object): - - responses = ['1', '2', '3', '4', '5', '6', '7'] - failures = [False, ] * 7 - - def __init__(self): - def _read_gen(self): - for i, r in enumerate(self.responses): - if self.failures[i]: - yield '' - yield r - self._reader = _read_gen(self) - - def read(self, size=None): - return self._reader.next() - - fileobj = fakefile() - self.assertEqual( - ''.join(fakefile.responses), utils.readall(fileobj, 7)) - fileobj = fakefile() - self.assertEqual( - ''.join(fakefile.responses[:4]), utils.readall(fileobj, 4)) - fileobj = fakefile() - self.assertRaises(IOError, utils.readall, fileobj, 10) - fileobj = fakefile() - fileobj.failures[1] = True - self.assertRaises(IOError, utils.readall, fileobj, 7) - fileobj = fakefile() - fileobj.failures[1] = True - self.assertEqual( - ''.join(fakefile.responses), utils.readall(fileobj, 7, 8)) + tstr = '1234567890' + with TemporaryFile() as f: + f.write(tstr) + f.flush() + f.seek(0) + self.assertEqual(utils.readall(f, 5), tstr[:5]) + self.assertEqual(utils.readall(f, 10), tstr[5:]) + self.assertEqual(utils.readall(f, 1), '') + self.assertRaises(IOError, utils.readall, f, 1, 0) if __name__ == '__main__': from sys import argv -- 1.7.10.4