Remove py33 incompatibilities

Except py33 compatibility changes were added unittests
to cover changed code.

Partially-implements blueprint py3-compatibility
Change-Id: Ib51e02ec69100a842ea1092e9f659ab1ebede671
This commit is contained in:
vponomaryov
2014-06-25 11:48:37 +03:00
committed by Valeriy Ponomaryov
parent 47d7a288a1
commit 0ccdb38dd2
25 changed files with 166 additions and 78 deletions

View File

@@ -23,6 +23,8 @@ import contextlib
import hashlib import hashlib
import os import os
import six
from manilaclient import exceptions from manilaclient import exceptions
from manilaclient.openstack.common import strutils from manilaclient.openstack.common import strutils
from manilaclient import utils from manilaclient import utils
@@ -104,7 +106,8 @@ class Manager(utils.HookableMixin):
# pair # pair
username = utils.env('OS_USERNAME', 'MANILA_USERNAME') username = utils.env('OS_USERNAME', 'MANILA_USERNAME')
url = utils.env('OS_URL', 'MANILA_URL') url = utils.env('OS_URL', 'MANILA_URL')
uniqifier = hashlib.md5(username + url).hexdigest() uniqifier = hashlib.md5(username.encode('utf-8') +
url.encode('utf-8')).hexdigest()
cache_dir = os.path.expanduser(os.path.join(base_dir, uniqifier)) cache_dir = os.path.expanduser(os.path.join(base_dir, uniqifier))
@@ -197,7 +200,7 @@ class ManagerWithFind(Manager):
the Python side. the Python side.
""" """
found = [] found = []
searches = kwargs.items() searches = list(kwargs.items())
for obj in self.list(): for obj in self.list():
try: try:
@@ -251,7 +254,7 @@ class Resource(object):
return None return None
def _add_details(self, info): def _add_details(self, info):
for (k, v) in info.iteritems(): for (k, v) in six.iteritems(info):
try: try:
setattr(self, k, v) setattr(self, k, v)
except AttributeError: except AttributeError:
@@ -270,7 +273,7 @@ class Resource(object):
return self.__dict__[k] return self.__dict__[k]
def __repr__(self): def __repr__(self):
reprkeys = sorted(k for k in self.__dict__.keys() if k[0] != '_' and reprkeys = sorted(k for k in self.__dict__ if k[0] != '_' and
k != 'manager') k != 'manager')
info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys) info = ", ".join("%s=%s" % (k, getattr(self, k)) for k in reprkeys)
return "<%s %s>" % (self.__class__.__name__, info) return "<%s %s>" % (self.__class__.__name__, info)

View File

@@ -11,7 +11,11 @@ from __future__ import print_function
import logging import logging
import os import os
import urlparse try:
import urlparse
except ImportError:
import urllib.parse as urlparse
try: try:
from eventlet import sleep from eventlet import sleep
except ImportError: except ImportError:
@@ -380,7 +384,7 @@ def get_client_class(version):
client_path = version_map[str(version)] client_path = version_map[str(version)]
except (KeyError, ValueError): except (KeyError, ValueError):
msg = "Invalid client version '%s'. must be one of: %s" % ( msg = "Invalid client version '%s'. must be one of: %s" % (
(version, ', '.join(version_map.keys()))) (version, ', '.join(version_map)))
raise exceptions.UnsupportedVersion(msg) raise exceptions.UnsupportedVersion(msg)
return utils.import_class(client_path) return utils.import_class(client_path)

View File

@@ -142,7 +142,7 @@ def from_response(response, body):
message = "n/a" message = "n/a"
details = "n/a" details = "n/a"
if hasattr(body, 'keys'): if hasattr(body, 'keys'):
error = body[body.keys()[0]] error = body[list(body)[0]]
message = error.get('message', None) message = error.get('message', None)
details = error.get('details', None) details = error.get('details', None)
return cls(code=response.status_code, message=message, details=details, return cls(code=response.status_code, message=message, details=details,

View File

@@ -29,7 +29,7 @@ class Extension(utils.HookableMixin):
def _parse_extension_module(self): def _parse_extension_module(self):
self.manager_class = None self.manager_class = None
for attr_name, attr_value in self.module.__dict__.items(): for attr_name, attr_value in list(self.module.__dict__.items()):
if attr_name in self.SUPPORTED_HOOKS: if attr_name in self.SUPPORTED_HOOKS:
self.add_hook(attr_name, attr_value) self.add_hook(attr_name, attr_value)
elif utils.safe_issubclass(attr_value, base.Manager): elif utils.safe_issubclass(attr_value, base.Manager):

View File

@@ -29,6 +29,8 @@ import os
import pkgutil import pkgutil
import sys import sys
import six
from manilaclient import client from manilaclient import client
from manilaclient import exceptions as exc from manilaclient import exceptions as exc
import manilaclient.extension import manilaclient.extension
@@ -422,9 +424,9 @@ class OpenStackManilaShell(object):
""" """
commands = set() commands = set()
options = set() options = set()
for sc_str, sc in self.subcommands.items(): for sc_str, sc in list(self.subcommands.items()):
commands.add(sc_str) commands.add(sc_str)
for option in sc._optionals._option_string_actions.keys(): for option in sc._optionals._option_string_actions:
options.add(option) options.add(option)
commands.remove('bash-completion') commands.remove('bash-completion')
@@ -455,14 +457,18 @@ class OpenStackHelpFormatter(argparse.HelpFormatter):
def main(): def main():
try: try:
OpenStackManilaShell().main(map(strutils.safe_decode, sys.argv[1:])) if sys.version_info >= (3, 0):
OpenStackManilaShell().main(sys.argv[1:])
else:
OpenStackManilaShell().main(
map(strutils.safe_decode, sys.argv[1:]))
except KeyboardInterrupt: except KeyboardInterrupt:
print("... terminating manila client", file=sys.stderr) print("... terminating manila client", file=sys.stderr)
sys.exit(130) sys.exit(130)
except Exception as e: except Exception as e:
logger.debug(e, exc_info=1) logger.debug(e, exc_info=1)
message = e.message message = e.message
if not isinstance(message, basestring): if not isinstance(message, six.string_types):
message = str(message) message = str(message)
print("ERROR: %s" % strutils.safe_encode(message), file=sys.stderr) print("ERROR: %s" % strutils.safe_encode(message), file=sys.stderr)
sys.exit(1) sys.exit(1)

View File

@@ -5,6 +5,7 @@ import sys
import uuid import uuid
import prettytable import prettytable
import six
from manilaclient import exceptions from manilaclient import exceptions
from manilaclient.openstack.common import strutils from manilaclient.openstack.common import strutils
@@ -70,7 +71,7 @@ def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False):
hook_name = hook.__name__ hook_name = hook.__name__
hook_kwargs = hook(args) hook_kwargs = hook(args)
conflicting_keys = set(hook_kwargs.keys()) & set(extra_kwargs.keys()) conflicting_keys = set(list(hook_kwargs)) & set(list(extra_kwargs))
if conflicting_keys and not allow_conflicts: if conflicting_keys and not allow_conflicts:
msg = ("Hook '%(hook_name)s' is attempting to redefine attributes " msg = ("Hook '%(hook_name)s' is attempting to redefine attributes "
"'%(conflicting_keys)s'" % { "'%(conflicting_keys)s'" % {
@@ -129,7 +130,14 @@ def pretty_choice_list(l):
return ', '.join("'%s'" % i for i in l) return ', '.join("'%s'" % i for i in l)
def print_list(objs, fields, formatters={}): def _print(pt, order):
if sys.version_info >= (3, 0):
print(pt.get_string(sortby=order))
else:
print(strutils.safe_encode(pt.get_string(sortby=order)))
def print_list(objs, fields, formatters={}, order_by=None):
mixed_case_fields = ['serverId'] mixed_case_fields = ['serverId']
pt = prettytable.PrettyTable([f for f in fields], caching=False) pt = prettytable.PrettyTable([f for f in fields], caching=False)
pt.aligns = ['l' for f in fields] pt.aligns = ['l' for f in fields]
@@ -148,14 +156,17 @@ def print_list(objs, fields, formatters={}):
row.append(data) row.append(data)
pt.add_row(row) pt.add_row(row)
print(strutils.safe_encode(pt.get_string(sortby=fields[0]))) if order_by is None:
order_by = fields[0]
_print(pt, order_by)
def print_dict(d, property="Property"): def print_dict(d, property="Property"):
pt = prettytable.PrettyTable([property, 'Value'], caching=False) pt = prettytable.PrettyTable([property, 'Value'], caching=False)
pt.aligns = ['l', 'l'] pt.aligns = ['l', 'l']
[pt.add_row(list(r)) for r in d.iteritems()] [pt.add_row(list(r)) for r in six.iteritems(d)]
print(strutils.safe_encode(pt.get_string(sortby=property))) _print(pt, property)
def find_resource(manager, name_or_id): def find_resource(manager, name_or_id):
@@ -167,9 +178,12 @@ def find_resource(manager, name_or_id):
except exceptions.NotFound: except exceptions.NotFound:
pass pass
if sys.version_info <= (3, 0):
name_or_id = strutils.safe_decode(name_or_id)
# now try to get entity as uuid # now try to get entity as uuid
try: try:
uuid.UUID(strutils.safe_decode(name_or_id)) uuid.UUID(name_or_id)
return manager.get(name_or_id) return manager.get(name_or_id)
except (ValueError, exceptions.NotFound): except (ValueError, exceptions.NotFound):
pass pass
@@ -208,7 +222,7 @@ def find_share(cs, share):
def _format_servers_list_networks(server): def _format_servers_list_networks(server):
output = [] output = []
for (network, addresses) in server.networks.items(): for (network, addresses) in list(server.networks.items()):
if len(addresses) == 0: if len(addresses) == 0:
continue continue
addresses_csv = ', '.join(addresses) addresses_csv = ', '.join(addresses)

View File

@@ -11,7 +11,7 @@ class Limits(base.Resource):
@property @property
def absolute(self): def absolute(self):
for (name, value) in self._info['absolute'].items(): for (name, value) in list(self._info['absolute'].items()):
yield AbsoluteLimit(name, value) yield AbsoluteLimit(name, value)
@property @property

View File

@@ -51,7 +51,7 @@ class QuotaClassSetManager(base.ManagerWithFind):
} }
} }
for key in body['quota_class_set'].keys(): for key in list(body['quota_class_set']):
if body['quota_class_set'][key] is None: if body['quota_class_set'][key] is None:
body['quota_class_set'].pop(key) body['quota_class_set'].pop(key)

View File

@@ -53,7 +53,7 @@ class QuotaSetManager(base.ManagerWithFind):
}, },
} }
for key in body['quota_set'].keys(): for key in list(body['quota_set']):
if body['quota_set'][key] is None: if body['quota_set'][key] is None:
body['quota_set'].pop(key) body['quota_set'].pop(key)
if user_id: if user_id:

View File

@@ -12,7 +12,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import urllib
try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
from manilaclient import exceptions from manilaclient import exceptions
@@ -131,10 +135,8 @@ class SecurityServiceManager(base.Manager):
:rtype: list of :class:`SecurityService` :rtype: list of :class:`SecurityService`
""" """
if search_opts: if search_opts:
query_string = urllib.urlencode([(key, value) query_string = urlencode(
for (key, value) sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
in search_opts.items()
if value])
if query_string: if query_string:
query_string = "?%s" % query_string query_string = "?%s" % query_string
else: else:

View File

@@ -13,7 +13,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import urllib import six
try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
@@ -38,10 +42,8 @@ class ServiceManager(base.Manager):
""" """
query_string = '' query_string = ''
if search_opts: if search_opts:
query_string = urllib.urlencode([(key, value) query_string = urlencode(
for (key, value) sorted([(k, v) for (k, v) in six.iteritems(search_opts) if v]))
in search_opts.items()
if value])
if query_string: if query_string:
query_string = "?%s" % query_string query_string = "?%s" % query_string
return self._list(RESOURCES_PATH + query_string, RESOURCES_NAME) return self._list(RESOURCES_PATH + query_string, RESOURCES_NAME)

View File

@@ -12,7 +12,11 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import urllib
try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
from manilaclient import exceptions from manilaclient import exceptions
@@ -142,10 +146,8 @@ class ShareNetworkManager(base.ManagerWithFind):
:rtype: list of :class:`NetworkInfo` :rtype: list of :class:`NetworkInfo`
""" """
if search_opts: if search_opts:
query_string = urllib.urlencode([(key, value) query_string = urlencode(
for (key, value) sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
in search_opts.items()
if value])
if query_string: if query_string:
query_string = "?%s" % query_string query_string = "?%s" % query_string
else: else:

View File

@@ -13,7 +13,11 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import urllib import six
try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
@@ -52,7 +56,7 @@ class ShareServerManager(base.Manager):
# +---------------------+------------------------------------+ # +---------------------+------------------------------------+
# | details:instance_id |35203a78-c733-4b1f-b82c-faded312e537| # | details:instance_id |35203a78-c733-4b1f-b82c-faded312e537|
# +---------------------+------------------------------------+ # +---------------------+------------------------------------+
for k, v in server._info["backend_details"].iteritems(): for k, v in six.iteritems(server._info["backend_details"]):
server._info["details:%s" % k] = v server._info["details:%s" % k] = v
return server return server
@@ -71,7 +75,8 @@ class ShareServerManager(base.Manager):
""" """
query_string = '' query_string = ''
if search_opts: if search_opts:
opts = [(k, v) for (k, v) in search_opts.items() if v] opts = sorted(
query_string = urllib.urlencode(opts) [(k, v) for (k, v) in six.iteritems(search_opts) if v])
query_string = urlencode(opts)
query_string = '?' + query_string if query_string else '' query_string = '?' + query_string if query_string else ''
return self._list(RESOURCES_PATH + query_string, RESOURCES_NAME) return self._list(RESOURCES_PATH + query_string, RESOURCES_NAME)

View File

@@ -14,7 +14,10 @@
# under the License. # under the License.
"""Interface for shares extension.""" """Interface for shares extension."""
import urllib try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
@@ -77,10 +80,8 @@ class ShareSnapshotManager(base.ManagerWithFind):
:rtype: list of :class:`ShareSnapshot` :rtype: list of :class:`ShareSnapshot`
""" """
if search_opts: if search_opts:
query_string = urllib.urlencode([(key, value) query_string = urlencode(
for (key, value) sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
in search_opts.items()
if value])
if query_string: if query_string:
query_string = "?%s" % (query_string,) query_string = "?%s" % (query_string,)
else: else:

View File

@@ -16,7 +16,10 @@
import collections import collections
import re import re
import urllib try:
from urllib import urlencode # noqa
except ImportError:
from urllib.parse import urlencode # noqa
from manilaclient import base from manilaclient import base
from manilaclient import exceptions from manilaclient import exceptions
@@ -164,10 +167,8 @@ class ShareManager(base.ManagerWithFind):
:rtype: list of :class:`Share` :rtype: list of :class:`Share`
""" """
if search_opts: if search_opts:
query_string = urllib.urlencode([(key, value) query_string = urlencode(
for (key, value) sorted([(k, v) for (k, v) in list(search_opts.items()) if v]))
in search_opts.items()
if value])
if query_string: if query_string:
query_string = "?%s" % (query_string,) query_string = "?%s" % (query_string,)
else: else:
@@ -214,7 +215,7 @@ class ShareManager(base.ManagerWithFind):
"""Get access list to the share.""" """Get access list to the share."""
access_list = self._action("os-access_list", share)[1]["access_list"] access_list = self._action("os-access_list", share)[1]["access_list"]
if access_list: if access_list:
t = collections.namedtuple('Access', access_list[0].keys()) t = collections.namedtuple('Access', list(access_list[0]))
return [t(*value.values()) for value in access_list] return [t(*value.values()) for value in access_list]
else: else:
return [] return []

View File

@@ -82,7 +82,7 @@ def _find_share_network(cs, share_network):
def _translate_keys(collection, convert): def _translate_keys(collection, convert):
for item in collection: for item in collection:
keys = item.__dict__.keys() keys = item.__dict__
for from_key, to_key in convert: for from_key, to_key in convert:
if from_key in keys and to_key not in keys: if from_key in keys and to_key not in keys:
setattr(item, to_key, item._info[from_key]) setattr(item, to_key, item._info[from_key])
@@ -360,8 +360,7 @@ def do_metadata(cs, args):
if args.action == 'set': if args.action == 'set':
cs.shares.set_metadata(share, metadata) cs.shares.set_metadata(share, metadata)
elif args.action == 'unset': elif args.action == 'unset':
cs.shares.delete_metadata(share, sorted(metadata.keys(), cs.shares.delete_metadata(share, sorted(list(metadata), reverse=True))
reverse=True))
@utils.arg('share', metavar='<share>', @utils.arg('share', metavar='<share>',
@@ -403,10 +402,7 @@ def do_delete(cs, args):
share_ref.delete() share_ref.delete()
except Exception as e: except Exception as e:
failure_count += 1 failure_count += 1
if 'Access was denied' in e.message: print("Delete for share %s failed: %s" % (share_ref.id, e))
print('Error occurred while deleting share %s' % share_ref.id)
else:
print(e.message)
if failure_count == len(args.share): if failure_count == len(args.share):
raise exceptions.CommandError("Unable to delete any of the specified " raise exceptions.CommandError("Unable to delete any of the specified "

View File

@@ -9,13 +9,12 @@ places where actual behavior differs from the spec.
from __future__ import print_function from __future__ import print_function
def assert_has_keys(dict, required=[], optional=[]): def assert_has_keys(dictonary, required=[], optional=[]):
keys = dict.keys()
for k in required: for k in required:
try: try:
assert k in keys assert k in dictonary
except AssertionError: except AssertionError:
extra_keys = set(keys).difference(set(required + optional)) extra_keys = set(dictonary).difference(set(required + optional))
raise AssertionError("found unexpected keys: %s" % raise AssertionError("found unexpected keys: %s" %
list(extra_keys)) list(extra_keys))

View File

@@ -1,8 +1,8 @@
import cStringIO
import re import re
import sys import sys
import fixtures import fixtures
from six import moves
from testtools import matchers from testtools import matchers
from manilaclient import exceptions from manilaclient import exceptions
@@ -29,7 +29,7 @@ class ShellTest(utils.TestCase):
def shell(self, argstr): def shell(self, argstr):
orig = sys.stdout orig = sys.stdout
try: try:
sys.stdout = cStringIO.StringIO() sys.stdout = moves.StringIO()
_shell = manilaclient.shell.OpenStackManilaShell() _shell = manilaclient.shell.OpenStackManilaShell()
_shell.main(argstr.split()) _shell.main(argstr.split())
except SystemExit: except SystemExit:

View File

@@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import urlparse try:
import urlparse
except ImportError:
import urllib.parse as urlparse
from manilaclient import client as base_client from manilaclient import client as base_client
from manilaclient.v1 import client from manilaclient.v1 import client
@@ -104,7 +107,7 @@ class FakeHTTPClient(base_client.HTTPClient):
return (200, {}, quota_set) return (200, {}, quota_set)
def put_os_quota_sets_test(self, body, **kw): def put_os_quota_sets_test(self, body, **kw):
assert body.keys() == ['quota_set'] assert list(body) == ['quota_set']
fakes.assert_has_keys(body['quota_set'], fakes.assert_has_keys(body['quota_set'],
required=['tenant_id']) required=['tenant_id'])
quota_set = { quota_set = {
@@ -137,7 +140,7 @@ class FakeHTTPClient(base_client.HTTPClient):
return (200, {}, quota_class_set) return (200, {}, quota_class_set)
def put_os_quota_class_sets_test(self, body, **kw): def put_os_quota_class_sets_test(self, body, **kw):
assert body.keys() == ['quota_class_set'] assert list(body) == ['quota_class_set']
fakes.assert_has_keys(body['quota_class_set'], fakes.assert_has_keys(body['quota_class_set'],
required=['class_name']) required=['class_name'])
quota_class_set = { quota_class_set = {

View File

@@ -75,13 +75,16 @@ class FakeHTTPClient(fakes.FakeHTTPClient):
def post_shares_1234_action(self, body, **kw): def post_shares_1234_action(self, body, **kw):
_body = None _body = None
resp = 202 resp = 202
assert len(body.keys()) == 1 assert len(list(body)) == 1
action = body.keys()[0] action = list(body)[0]
if action == 'os-allow_access': if action == 'os-allow_access':
assert body[action].keys() == ['access_type', 'access_to'] expected = ['access_to', 'access_type']
actual = sorted(list(body[action]))
err_msg = "expected '%s', actual is '%s'" % (expected, actual)
assert expected == actual, err_msg
_body = {'access': {}} _body = {'access': {}}
elif action == 'os-deny_access': elif action == 'os-deny_access':
assert body[action].keys() == ['access_id'] assert list(body[action]) == ['access_id']
elif action == 'os-access_list': elif action == 'os-access_list':
assert body[action] is None assert body[action] is None
elif action == 'os-reset_status': elif action == 'os-reset_status':

View File

@@ -103,7 +103,7 @@ class SecurityServiceTest(utils.TestCase):
filters = OrderedDict([('all_tenants', 1), filters = OrderedDict([('all_tenants', 1),
('status', 'ERROR'), ('status', 'ERROR'),
('network', 'fake_network')]) ('network', 'fake_network')])
expected_postfix = '?all_tenants=1&status=ERROR&network=fake_network' expected_postfix = '?all_tenants=1&network=fake_network&status=ERROR'
with mock.patch.object(self.manager, '_list', with mock.patch.object(self.manager, '_list',
mock.Mock(return_value=None)): mock.Mock(return_value=None)):

View File

@@ -31,4 +31,28 @@ class ServicesTest(utils.TestCase):
self.manager.list() self.manager.list()
self.manager._list.assert_called_once_with( self.manager._list.assert_called_once_with(
services.RESOURCES_PATH, services.RESOURCES_PATH,
services.RESOURCES_NAME) services.RESOURCES_NAME,
)
def test_list_services_with_one_search_opt(self):
host = 'fake_host'
query_string = "?host=%s" % host
with mock.patch.object(self.manager, '_list',
mock.Mock(return_value=None)):
self.manager.list({'host': host})
self.manager._list.assert_called_once_with(
services.RESOURCES_PATH + query_string,
services.RESOURCES_NAME,
)
def test_list_services_with_two_search_opts(self):
host = 'fake_host'
binary = 'fake_binary'
query_string = "?binary=%s&host=%s" % (binary, host)
with mock.patch.object(self.manager, '_list',
mock.Mock(return_value=None)):
self.manager.list({'binary': binary, 'host': host})
self.manager._list.assert_called_once_with(
services.RESOURCES_PATH + query_string,
services.RESOURCES_NAME,
)

View File

@@ -42,6 +42,29 @@ class ShareServersTest(utils.TestCase):
share_servers.RESOURCES_PATH, share_servers.RESOURCES_PATH,
share_servers.RESOURCES_NAME) share_servers.RESOURCES_NAME)
def test_list_with_one_search_opt(self):
host = 'fake_host'
query_string = "?host=%s" % host
with mock.patch.object(self.manager, '_list',
mock.Mock(return_value=None)):
self.manager.list({'host': host})
self.manager._list.assert_called_once_with(
share_servers.RESOURCES_PATH + query_string,
share_servers.RESOURCES_NAME,
)
def test_list_with_two_search_opts(self):
host = 'fake_host'
status = 'fake_status'
query_string = "?host=%s&status=%s" % (host, status)
with mock.patch.object(self.manager, '_list',
mock.Mock(return_value=None)):
self.manager.list({'host': host, 'status': status})
self.manager._list.assert_called_once_with(
share_servers.RESOURCES_PATH + query_string,
share_servers.RESOURCES_NAME,
)
def test_get(self): def test_get(self):
server = FakeShareServer() server = FakeShareServer()
with mock.patch.object(self.manager, '_get', with mock.patch.object(self.manager, '_get',
@@ -51,8 +74,8 @@ class ShareServersTest(utils.TestCase):
self.manager._get.assert_called_once_with( self.manager._get.assert_called_once_with(
"%s/%s" % (share_servers.RESOURCES_PATH, share_server_id), "%s/%s" % (share_servers.RESOURCES_PATH, share_server_id),
share_servers.RESOURCE_NAME) share_servers.RESOURCE_NAME)
self.assertTrue("details:fake_key1" in server._info.keys()) for key in ["details:fake_key1", "details:fake_key2"]:
self.assertTrue("details:fake_key2" in server._info.keys()) self.assertTrue(key in list(server._info))
def test_details(self): def test_details(self):
with mock.patch.object(self.manager, '_get', with mock.patch.object(self.manager, '_get',

View File

@@ -101,7 +101,7 @@ class ShellTest(utils.TestCase):
def test_snapshot_list_filter_status_and_share_id(self): def test_snapshot_list_filter_status_and_share_id(self):
self.run_command('snapshot-list --status=available --share-id=1234') self.run_command('snapshot-list --status=available --share-id=1234')
self.assert_called('GET', '/snapshots/detail?' self.assert_called('GET', '/snapshots/detail?'
'status=available&share_id=1234') 'share_id=1234&status=available')
def test_rename(self): def test_rename(self):
# basic rename with positional agruments # basic rename with positional agruments

View File

@@ -1,6 +1,6 @@
[tox] [tox]
distribute = False distribute = False
envlist = py26,py27,pep8 envlist = py26,py27,py33,pep8
minversion = 1.6 minversion = 1.6
skipsdist = True skipsdist = True