Skip to content

Commit

Permalink
add return all missed required arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
islamgulov committed Jun 13, 2012
1 parent db7699b commit 91d2554
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 22 deletions.
22 changes: 14 additions & 8 deletions libcloud_rest/api/validators.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
# -*- coding:utf-8 -*-
from libcloud_rest.errors import MissingHeaderError
from libcloud_rest.api.parser import ARGS_TO_XHEADERS_DICT
from libcloud_rest.exception import ValidationError
from libcloud_rest.exception import ValidationError, MissingArguments
from libcloud_rest.api.parser import get_method_requirements

__all__ = [
'validate_header_arguments',
]


def validate_header_arguments(required_arguments, arguments):
def validate_driver_arguments(Driver, arguments):
"""
Validate that in all required arguments are existing.
@param required_arguments:
@param arguments:
@raise: L{MissingHeaderError}
"""
for arg_altertives in required_arguments:
#required args validate
try:
required_args = get_method_requirements(Driver.__init__)
except NotImplementedError:
required_args = get_method_requirements(Driver.__new__)
missing_args = []
for arg_altertives in required_args:
if not any([arg in arguments for arg in arg_altertives]):
header_names = [ARGS_TO_XHEADERS_DICT[arg]
for arg in arg_altertives]
raise MissingHeaderError(header=' or '.join(header_names))
missing_args.append(arg_altertives)
if missing_args:
raise MissingArguments(missing_args)
return True


class BaseValidator(object):
Expand Down
6 changes: 3 additions & 3 deletions libcloud_rest/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ class InternalError(LibcloudRestError):
http_status_code = 500


class MissingHeaderError(LibcloudRestError):
class MissingHeadersError(LibcloudRestError):
code = 1003
name = 'MissingHeader'
message = 'Your request was missing a required header: %(header)s.'
name = 'MissingsHeader'
message = 'Your request was missing a required headers: %(headers)s.'
http_status_code = 400


Expand Down
9 changes: 9 additions & 0 deletions libcloud_rest/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@

class ValidationError(Exception):
pass


class MissingArguments(Exception):

def __init__(self, arguments):
self.arguments = arguments

def __str__(self):
return "Missing arguments: %s" % str(self.arguments)
20 changes: 12 additions & 8 deletions libcloud_rest/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import inspect

from libcloud.utils.misc import get_driver
from libcloud_rest.errors import ProviderNotSupportedError
from libcloud_rest.api.parser import get_method_requirements
from libcloud_rest.api.validators import validate_header_arguments
from libcloud_rest.errors import ProviderNotSupportedError, MissingHeadersError
from libcloud_rest.exception import MissingArguments
from libcloud_rest.api.validators import validate_driver_arguments
from libcloud_rest.api.parser import ARGS_TO_XHEADERS_DICT

__all__ = [
'get_providers_names',
Expand Down Expand Up @@ -55,11 +56,14 @@ def get_driver_instance(Driver, **kwargs):
@param kwargs:
@return:
"""
try:
required_args = get_method_requirements(Driver.__init__)
except NotImplementedError:
required_args = get_method_requirements(Driver.__new__)
#FIXME:validate for extra args
validate_header_arguments(required_args, kwargs)
try:
validate_driver_arguments(Driver, kwargs)
except MissingArguments, error:
str_repr = ', '.join((
' or '.join(ARGS_TO_XHEADERS_DICT[arg] for arg in args)
for args in error.arguments
))
raise MissingHeadersError(headers=str_repr)
driver = Driver(**kwargs)
return driver
11 changes: 9 additions & 2 deletions tests/compute/test_cloudstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@

class CloudstackTests(unittest2.TestCase):
def setUp(self):
self.url_tmpl = rest_versions[libcloud.__version__] +\
'/compute/cloudstack/%s?test=1'
self.client = Client(LibcloudRestApp(), BaseResponse)
self.fixtures = ComputeFixtures('cloudstack')

def test_list_nodes(self):
url = rest_versions[libcloud.__version__] +\
'/compute/cloudstack/nodes?test=1'
url = self.url_tmpl % 'nodes'
headers = {'x-auth-user': 'apikey', 'x-api-key': 'secret',
'x-provider-path': '/test/path',
'x-provider-host': 'api.dummy.com'}
Expand All @@ -33,6 +34,12 @@ def test_list_nodes(self):
self.assertEqual(resp.status_code, 200)
self.assertEqual(resp_data, test_data)

def test_bad_headers(self):
url = self.url_tmpl % 'nodes'
headers = {'x-auth-user': 'apikey'}
resp = self.client.get(url, headers=headers)
self.assertEqual(resp.status_code, 400)


if __name__ == '__main__':
sys.exit(unittest2.main())
6 changes: 6 additions & 0 deletions tests/compute/test_gogrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def setUp(self):
self.url_tmpl = rest_versions[libcloud.__version__] +\
'/compute/gogrid/%s?test=1'

def test_bad_headers(self):
url = self.url_tmpl % 'nodes'
headers = {'abs': 1, 'def': 2}
resp = self.client.get(url, headers=headers)
self.assertEqual(resp.status_code, 400)

def test_list_nodes(self):
url = self.url_tmpl % 'nodes'
resp = self.client.get(url, headers=self.headers)
Expand Down
33 changes: 32 additions & 1 deletion tests/test_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import unittest2

from libcloud_rest.api import validators
from libcloud_rest.exception import ValidationError
from libcloud_rest.exception import ValidationError, MissingArguments


class TestParser(unittest2.TestCase):
Expand Down Expand Up @@ -45,3 +45,34 @@ def test_required(self):
self.assertTrue(dict_validator(valid_dict))
self.assertTrue(dict_validator(valid_dict2))
self.assertRaises(ValidationError, dict_validator, invalid_dict)


class TestGetDriverArguments(unittest2.TestCase):

def test_requires(self):
class FakeDriver(object):
def __init__(self):
"@requires: arg1, arg2"
pass
self.assertTrue(
validators.validate_driver_arguments(FakeDriver, ['arg1', 'arg2']))
self.assertRaises(MissingArguments,
validators.validate_driver_arguments,
FakeDriver, ['arg1']
)

def test_init_new_requires_docs(self):
class FakeDriver(object):
def __init__(self):
"@requires: arg1, arg2"
pass

def __new__(cls, *args, **kwargs):
"@requires: arg2, arg3"
pass
self.assertTrue(
validators.validate_driver_arguments(FakeDriver, ['arg1', 'arg2']))
self.assertRaises(MissingArguments,
validators.validate_driver_arguments,
FakeDriver, ['arg2', 'arg3']
)

0 comments on commit 91d2554

Please sign in to comment.