class NodeEntryTests(unittest2.TestCase): def setUp(self): self.entry = Entry('node', 'L{Node}', 'node which is required') def test_validate(self): valid_json = '{"node_id": "33333", "unknown_arg": 123}' self.entry._get_json_and_validate(valid_json) malformed_json = '{"id"}' self.assertRaises(MalformedJSONError, self.entry._get_json_and_validate, malformed_json) invalid_json = '{"node_id": 123}' self.assertRaises(ValidationError, self.entry._get_json_and_validate, invalid_json) def test_get_arguments(self): argument = self.entry.get_arguments()[0] self.assertEqual(argument['name'], 'node_id') self.assertEqual(argument['type'], 'str') def test_to_json(self): node = Node('111', 'test', NodeState.RUNNING, ['123.123.123.123'], None, Node) json_data = json.loads(self.entry.to_json(node)) self.assertEqual(node.name, json_data['name']) self.assertEqual(node.id, json_data['id']) self.assertEqual(node.state, json_data['state']) self.assertEqual(node.public_ips, json_data['public_ips']) self.assertRaises(ValueError, self.entry.to_json, ['pass']) def test_from_json(self): json_data = '{"node_id": "2600"}' node = self.entry.from_json(json_data, None) self.assertEqual(node.id, '2600')
def __init__(self, driver_obj, method_name): if inspect.isclass(driver_obj): self.driver_cls = driver_obj else: self.driver_cls = driver_obj.__class__ self.driver_obj = driver_obj self.method_name = method_name self.method = getattr(self.driver_obj, method_name, None) if not inspect.ismethod(self.method): raise NoSuchOperationError() method_doc = get_method_docstring(self.driver_cls, method_name) if not method_doc: raise MethodParsingException('Empty docstring') argspec_arg = parse_args(self.method) docstring_parse_result = parse_docstring(method_doc, self.driver_cls) self.description = docstring_parse_result['description'] docstring_args = docstring_parse_result['arguments'] #check vargs self.vargs_entries = [] for name, arg_info in argspec_arg.iteritems(): if name in docstring_args: docstring_arg = docstring_args[name] entry_kwargs = { 'name': name, 'description': docstring_arg['description'], 'type_name': docstring_arg['type_name'], 'required': (docstring_arg['required'] or arg_info['required']), } if not entry_kwargs['required'] and 'default' in arg_info: entry_kwargs['default'] = arg_info['default'] self.vargs_entries.append(Entry(**entry_kwargs)) else: raise MethodParsingException( '%s %s not described in docstring' % (method_name, name)) #update kwargs kwargs = set(docstring_args).difference(argspec_arg) self.kwargs_entries = [ Entry(arg_name, **docstring_args[arg_name]) for arg_name in kwargs ] method_return = docstring_parse_result['return'] self.result_entry = Entry('', method_return['type_name'], method_return['description'], True)
class RecordTypeTest(unittest2.TestCase): def setUp(self): self.entry = Entry('type', 'L{RecordType}', 'pass', True) def test_from_json(self): valid_json = '{"record_type": 1}' self.assertEqual(self.entry.from_json(valid_json, None), RecordType.AAAA) invalid_json = '{"record_type": "ABC"}' self.assertRaises(ValidationError, self.entry.from_json, invalid_json, None)
class OneOfEntryTests(unittest2.TestCase): def setUp(self): self.entry = Entry('node', 'L{NodeAuthSSHKey} or L{NodeAuthPassword}', 'Initial authentication information for the node') def test_get_arguments(self): args = self.entry.get_arguments() self.assertEqual(2, len(args)) get_arg = lambda name: [arg for arg in args if arg['name'] == name][0] node_pubkey_arg = get_arg('node_pubkey') self.assertEqual(node_pubkey_arg['type'], 'str') node_password_arg = get_arg('node_password') self.assertEqual(node_password_arg['type'], 'str') def test_from_json(self): key_json = '{"node_pubkey": "123", "unknown_arg": 123}' node_auth_ssh_key = self.entry.from_json(key_json, None) self.assertEqual("123", node_auth_ssh_key.pubkey) password_json = '{"node_password": "******", "unknown_arg": 123}' node_auth_password = self.entry.from_json(password_json, None) self.assertEqual("321", node_auth_password.password) key_password_json = '{"node_pubkey": "123",' \ ' "node_password": "******", "unknown_args": 123}' self.assertRaises(TooManyArgumentsError, self.entry.from_json, key_password_json, None) empty_json = "{}" self.assertRaises(MissingArguments, self.entry.from_json, empty_json, None) invalid_json = '{"node_pubkey": 123}' self.assertRaises(ValidationError, self.entry.from_json, invalid_json, None) def test_to_json(self): node_ssh_key = NodeAuthSSHKey('pk') self.assertEqual('{"pubkey": "pk"}', self.entry.to_json(node_ssh_key)) node_password = NodeAuthPassword('pwd') self.assertEqual('{"password": "******"}', self.entry.to_json(node_password))
class StringEntryTests(unittest2.TestCase): def setUp(self): self.entry = Entry('zone_id', 'C{str}', 'ID of the zone which is required') def test_validate(self): valid_json = '{"zone_id": "123"}' self.entry._get_json_and_validate(valid_json) malformed_json = "{ '1'}" self.assertRaises(MalformedJSONError, self.entry._get_json_and_validate, malformed_json) invalid_json = '{"zone_id": 123}' self.assertRaises(ValidationError, self.entry._get_json_and_validate, invalid_json) def test_get_arguments(self): argument = self.entry.get_arguments()[0] self.assertEqual(argument['name'], 'zone_id') self.assertEqual(argument['description'], 'ID of the zone which is required') self.assertEqual(argument['type'], 'str') def test_to_json(self): valid = '123' self.entry.to_json(valid) invalid = 123 self.assertRaises(ValueError, self.entry.to_json, invalid) def test_from_json(self): valid = '{"zone_id": "123"}' self.entry.from_json(valid) invalid = '{"zone_id": 333}' self.assertRaises(ValidationError, self.entry.from_json, invalid) def test_default(self): entry = Entry('zone_id', 'C{str}', 'ID of the zone which is required', default='12345') valid_json = '{"zone_id": "33333", "unknown_arg": 123}' self.assertEqual('33333', entry.from_json(valid_json)) self.assertTrue(entry._get_json_and_validate(valid_json)) node_json = '{"node_id": "33333", "unknown_arg": 123}' self.assertEqual('12345', entry.from_json(node_json)) self.assertRaises(MissingArguments, entry._get_json_and_validate, node_json) valid = '123' entry.to_json(valid) invalid = 123 self.assertRaises(ValueError, entry.to_json, invalid)
def test_default(self): entry = Entry('zone_id', 'C{str}', 'ID of the zone which is required', default='12345') valid_json = '{"zone_id": "33333", "unknown_arg": 123}' self.assertEqual('33333', entry.from_json(valid_json)) self.assertTrue(entry._get_json_and_validate(valid_json)) node_json = '{"node_id": "33333", "unknown_arg": 123}' self.assertEqual('12345', entry.from_json(node_json)) self.assertRaises(MissingArguments, entry._get_json_and_validate, node_json) valid = '123' entry.to_json(valid) invalid = 123 self.assertRaises(ValueError, entry.to_json, invalid)
def __init__(self, driver_obj, method_name): if inspect.isclass(driver_obj): self.driver_cls = driver_obj else: self.driver_cls = driver_obj.__class__ self.driver_obj = driver_obj self.method_name = method_name self.method = getattr(self.driver_obj, method_name, None) if not inspect.ismethod(self.method): raise NoSuchOperationError() method_doc = get_method_docstring(self.driver_cls, method_name) if not method_doc: raise MethodParsingException('Empty docstring') argspec_arg = parse_args(self.method) docstring_parse_result = parse_docstring(method_doc, self.driver_cls) self.description = docstring_parse_result['description'] docstring_args = docstring_parse_result['arguments'] #check vargs self.vargs_entries = [] for name, arg_info in argspec_arg.iteritems(): if name in docstring_args: docstring_arg = docstring_args[name] entry_kwargs = { 'name': name, 'description': docstring_arg['description'], 'type_name': docstring_arg['type_name'], 'required': (docstring_arg['required'] or arg_info['required']), } if not entry_kwargs['required'] and 'default' in arg_info: entry_kwargs['default'] = arg_info['default'] self.vargs_entries.append(Entry(**entry_kwargs)) else: raise MethodParsingException( '%s %s not described in docstring' % (method_name, name)) #update kwargs kwargs = set(docstring_args).difference(argspec_arg) self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name]) for arg_name in kwargs] method_return = docstring_parse_result['return'] self.result_entry = Entry('', method_return['type_name'], method_return['description'], True)
class DefaultOneOfEntryTests(unittest2.TestCase): def setUp(self): self.entry = Entry('attr', 'C{str} or C{dict}', 'Test description', default='default_value') def test_get_arguments(self): args = self.entry.get_arguments() self.assertEqual(2, len(args)) test_args = [{ 'type': 'str', 'name': 'attr', 'description': 'Test description', 'required': True }, { 'type': 'dict', 'name': 'attr', 'description': 'Test description', 'required': True }] self.assertEqual(test_args, args) def test_from_json(self): str_json = '{"attr": "123", "unknown_arg": 123}' self.assertEqual("123", self.entry.from_json(str_json, None)) dict_json = '{"attr": "{}", "unknown_arg": 123}' self.assertEqual("{}", self.entry.from_json(dict_json, None)) invalid_json = '{"attr": 555}' self.assertRaises(ValidationError, self.entry.from_json, invalid_json, None) without_attr_json = '{"unknown_arg": 123}' self.assertEqual('default_value', self.entry.from_json(without_attr_json, None)) malformed_json = '{' self.assertRaises(MalformedJSONError, self.entry.from_json, malformed_json, None) def test_to_json(self): str_data = 'abc' self.assertEqual('{"attr": "abc"}', self.entry.to_json(str_data)) dict_data = {'1': 2} self.assertEqual('{"attr": {"1": 2}}', self.entry.to_json(dict_data)) int_data = 5 self.assertRaises(ValueError, self.entry.to_json, int_data)
class DefaultOneOfEntryTests(unittest2.TestCase): def setUp(self): self.entry = Entry('attr', 'C{str} or C{dict}', 'Test description', default='default_value') def test_get_arguments(self): args = self.entry.get_arguments() self.assertEqual(2, len(args)) test_args = [{'type': 'str', 'name': 'attr', 'description': 'Test description', 'required': True}, {'type': 'dict', 'name': 'attr', 'description': 'Test description', 'required': True}] self.assertEqual(test_args, args) def test_from_json(self): str_json = '{"attr": "123", "unknown_arg": 123}' self.assertEqual("123", self.entry.from_json(str_json, None)) dict_json = '{"attr": "{}", "unknown_arg": 123}' self.assertEqual("{}", self.entry.from_json(dict_json, None)) invalid_json = '{"attr": 555}' self.assertRaises(ValidationError, self.entry.from_json, invalid_json, None) without_attr_json = '{"unknown_arg": 123}' self.assertEqual('default_value', self.entry.from_json(without_attr_json, None)) malformed_json = '{' self.assertRaises(MalformedJSONError, self.entry.from_json, malformed_json, None) def test_to_json(self): str_data = 'abc' self.assertEqual('{"attr": "abc"}', self.entry.to_json(str_data)) dict_data = {'1': 2} self.assertEqual('{"attr": {"1": 2}}', self.entry.to_json(dict_data)) int_data = 5 self.assertRaises(ValueError, self.entry.to_json, int_data)
def setUp(self): self.entry = Entry('type', 'L{RecordType}', 'pass', True)
def setUp(self): self.entry = Entry('node', 'L{Node}', 'node which is required')
def setUp(self): self.entry = Entry('attr', 'C{str} or C{dict}', 'Test description', default='default_value')
def setUp(self): self.entry = Entry('node', 'L{NodeAuthSSHKey} or L{NodeAuthPassword}', 'Initial authentication information for the node')
def setUp(self): self.entry = Entry('zone_id', 'C{str}', 'ID of the zone which is required')
class DriverMethod(object): _type_name_pattern = r'.\{([_0-9a-zA-Z]+)\}' def __init__(self, driver_obj, method_name): if inspect.isclass(driver_obj): self.driver_cls = driver_obj else: self.driver_cls = driver_obj.__class__ self.driver_obj = driver_obj self.method_name = method_name self.method = getattr(self.driver_obj, method_name, None) if not inspect.ismethod(self.method): raise NoSuchOperationError() method_doc = get_method_docstring(self.driver_cls, method_name) if not method_doc: raise MethodParsingException('Empty docstring') argspec_arg = parse_args(self.method) docstring_parse_result = parse_docstring(method_doc, self.driver_cls) self.description = docstring_parse_result['description'] docstring_args = docstring_parse_result['arguments'] #check vargs self.vargs_entries = [] for name, arg_info in argspec_arg.iteritems(): if name in docstring_args: docstring_arg = docstring_args[name] entry_kwargs = { 'name': name, 'description': docstring_arg['description'], 'type_name': docstring_arg['type_name'], 'required': (docstring_arg['required'] or arg_info['required']), } if not entry_kwargs['required'] and 'default' in arg_info: entry_kwargs['default'] = arg_info['default'] self.vargs_entries.append(Entry(**entry_kwargs)) else: raise MethodParsingException( '%s %s not described in docstring' % (method_name, name)) #update kwargs kwargs = set(docstring_args).difference(argspec_arg) self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name]) for arg_name in kwargs] method_return = docstring_parse_result['return'] self.result_entry = Entry('', method_return['type_name'], method_return['description'], True) @classmethod def _remove_type_name_brackets(cls, type_name): return re.sub(cls._type_name_pattern, r'\1', type_name) def get_description(self): result_arguments = [] for entry in self.vargs_entries: result_arguments.extend(entry.get_arguments()) for entry in self.kwargs_entries: result_arguments.extend(entry.get_arguments()) result = {'name': self.method_name, 'description': self.description, 'arguments': result_arguments, 'return': { 'type': self._remove_type_name_brackets( self.result_entry.type_name), 'description': self.result_entry.description} } return result def invoke_result_to_json(self, value): return self.result_entry.to_json(value) def invoke(self, data): vargs = [e.from_json(data, self.driver_obj) for e in self.vargs_entries] kwargs = {} for kw_entry in self.kwargs_entries: try: kwargs[kw_entry.name] = kw_entry.from_json(data, self.driver_obj) except MissingArguments: if kw_entry.required: raise if self.method_name == '__init__': return self.driver_cls(*vargs, **kwargs) return self.method(*vargs, **kwargs)