def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.instance = { "instance": { "volume": {"size": "1"}, "users": [ {"name": "user1", "password": "******", "databases": [{"name": "firstdb"}]} ], "flavorRef": "https://*****:*****@(D", "databases": [ { "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" } ] } }
def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.locality = 'affinity' self.instance = { "instance": { "volume": { "size": "1" }, "users": [{ "name": "user1", "password": "******", "databases": [{ "name": "firstdb" }] }], "flavorRef": "https://*****:*****@(D", "databases": [{ "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" }], "locality": self.locality } } self.context = trove_testtools.TroveTestContext(self) self.req = Mock(remote_addr='ip:port', host='myhost')
def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.locality = 'affinity' self.instance = { "instance": { "volume": {"size": "1"}, "users": [ {"name": "user1", "password": "******", "databases": [{"name": "firstdb"}]} ], "flavorRef": "https://*****:*****@(D", "databases": [ { "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" } ], "locality": self.locality } } self.context = trove_testtools.TroveTestContext(self) self.req = Mock(remote_addr='ip:port', host='myhost')
def _instance_router(self, mapper): instance_resource = InstanceController().create_resource() mapper.connect("/{tenant_id}/instances", controller=instance_resource, action="index", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances", controller=instance_resource, action="create", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="show", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/action", controller=instance_resource, action="action", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="update", conditions={'method': ['PUT']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="delete", conditions={'method': ['DELETE']}) mapper.connect("/{tenant_id}/instances/{id}/backups", controller=instance_resource, action="backups", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/configuration", controller=instance_resource, action="configuration", conditions={'method': ['GET']})
def _instance_router(self, mapper): instance_resource = InstanceController().create_resource() mapper.connect("/{tenant_id}/instances", controller=instance_resource, action="index", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances", controller=instance_resource, action="create", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="show", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/action", controller=instance_resource, action="action", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="update", conditions={'method': ['PUT']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="edit", conditions={'method': ['PATCH']}) mapper.connect("/{tenant_id}/instances/{id}", controller=instance_resource, action="delete", conditions={'method': ['DELETE']}) mapper.connect("/{tenant_id}/instances/{id}/backups", controller=instance_resource, action="backups", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/configuration", controller=instance_resource, action="configuration", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/log", controller=instance_resource, action="guest_log_list", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/log", controller=instance_resource, action="guest_log_action", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}/modules", controller=instance_resource, action="module_list", conditions={'method': ['GET']}) mapper.connect("/{tenant_id}/instances/{id}/modules", controller=instance_resource, action="module_apply", conditions={'method': ['POST']}) mapper.connect("/{tenant_id}/instances/{id}/modules/{module_id}", controller=instance_resource, action="module_remove", conditions={'method': ['DELETE']})
def _instance_router(self, mapper): instance_resource = InstanceController().create_resource() path = "/{tenant_id}/instances" mapper.resource("instance", path, controller=instance_resource, member={ 'action': 'POST', 'backups': 'GET' })
class TestInstanceController(trove_testtools.TestCase): def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.instance = { "instance": { "volume": {"size": "1"}, "users": [ {"name": "user1", "password": "******", "databases": [{"name": "firstdb"}]} ], "flavorRef": "https://*****:*****@(D", "databases": [ { "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" } ] } } def verify_errors(self, errors, msg=None, properties=None, path=None): msg = msg or [] properties = properties or [] self.assertThat(len(errors), Is(len(msg))) i = 0 while i < len(msg): self.assertIn(errors[i].message, msg) if path: self.assertThat(path, Equals(properties[i])) else: self.assertThat(errors[i].path.pop(), Equals(properties[i])) i += 1 def test_get_schema_create(self): schema = self.controller.get_schema('create', {'instance': {}}) self.assertIsNotNone(schema) self.assertTrue('instance' in schema['properties']) def test_get_schema_action_restart(self): schema = self.controller.get_schema('action', {'restart': {}}) self.assertIsNotNone(schema) self.assertTrue('restart' in schema['properties']) def test_get_schema_action_resize_volume(self): schema = self.controller.get_schema( 'action', {'resize': {'volume': {}}}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'volume' in schema['properties']['resize']['properties']) def test_get_schema_action_resize_flavorRef(self): schema = self.controller.get_schema( 'action', {'resize': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'flavorRef' in schema['properties']['resize']['properties']) def test_get_schema_action_other(self): schema = self.controller.get_schema( 'action', {'supersized': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertThat(len(schema.keys()), Is(0)) def test_validate_create_complete(self): body = self.instance schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance body['instance']['restorePoint'] = { "backupRef": "d761edd8-0771-46ff-9743-688b9e297a3b" } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore_error(self): body = self.instance backup_id_ref = "invalid-backup-id-ref" body['instance']['restorePoint'] = { "backupRef": backup_id_ref } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("'%s' does not match '%s'" % (backup_id_ref, apischema.uuid['pattern']))) def test_validate_create_blankname(self): body = self.instance body['instance']['name'] = " " schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("' ' does not match '^.*[0-9a-zA-Z]+.*$'")) def test_validate_create_invalid_name(self): body = self.instance body['instance']['name'] = "$#$%^^" schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertEqual(1, len(errors)) self.assertIn("'$#$%^^' does not match '^.*[0-9a-zA-Z]+.*$'", errors[0].message) def test_validate_restart(self): body = {"restart": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_invalid_action(self): # TODO(juice) perhaps we should validate the schema not recognized body = {"restarted": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume(self): body = {"resize": {"volume": {"size": 4}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string(self): body = {"resize": {"volume": {"size": "4"}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string_invalid_number(self): body = {"resize": {"volume": {"size": '-44.0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[1].message, Equals("'-44.0' does not match '^[0-9]+$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_volume_invalid_characters(self): body = {"resize": {"volume": {"size": 'x'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("'x' is not of type 'integer'")) self.assertThat(errors[0].context[1].message, Equals("'x' does not match '^[0-9]+$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_instance(self): body = {"resize": {"flavorRef": "https://endpoint/v1.0/123/flavors/2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int(self): body = {"resize": {"flavorRef": 2}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_string(self): body = {"resize": {"flavorRef": 'foo'}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_empty_url(self): body = {"resize": {"flavorRef": ""}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors[0].context, ["'' is too short", "'' does not match '^.*[0-9a-zA-Z]+.*$'", "'' is not of type 'integer'"], ["flavorRef", "flavorRef", "flavorRef", "flavorRef"], errors[0].path.pop()) @skip("This URI validator allows just about anything you give it") def test_validate_resize_instance_invalid_url(self): body = {"resize": {"flavorRef": "xyz-re1f2-daze329d-f23901"}} schema = self.controller.get_schema('action', body) self.assertIsNotNone(schema) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors, ["'' is too short"], ["flavorRef"]) def _setup_modify_instance_mocks(self): instance = Mock() instance.detach_replica = Mock() instance.assign_configuration = Mock() instance.unassign_configuration = Mock() instance.update_db = Mock() return instance def test_modify_instance_with_empty_args(self): instance = self._setup_modify_instance_mocks() args = {} self.controller._modify_instance(instance, **args) self.assertEqual(0, instance.detach_replica.call_count) self.assertEqual(0, instance.unassign_configuration.call_count) self.assertEqual(0, instance.assign_configuration.call_count) self.assertEqual(0, instance.update_db.call_count) def test_modify_instance_with_nonempty_args_calls_update_db(self): instance = self._setup_modify_instance_mocks() args = {} args['any'] = 'anything' self.controller._modify_instance(instance, **args) instance.update_db.assert_called_once_with(**args) def test_modify_instance_with_False_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = False self.controller._modify_instance(instance, **args) self.assertEqual(0, instance.detach_replica.call_count) def test_modify_instance_with_True_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = True self.controller._modify_instance(instance, **args) self.assertEqual(1, instance.detach_replica.call_count) def test_modify_instance_with_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = 'some_id' self.controller._modify_instance(instance, **args) self.assertEqual(1, instance.assign_configuration.call_count) def test_modify_instance_with_None_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = None self.controller._modify_instance(instance, **args) self.assertEqual(1, instance.unassign_configuration.call_count) def test_modify_instance_with_all_args(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = True args['configuration_id'] = 'some_id' self.controller._modify_instance(instance, **args) self.assertEqual(1, instance.detach_replica.call_count) self.assertEqual(1, instance.assign_configuration.call_count) instance.update_db.assert_called_once_with(**args)
class TestInstanceController(TestCase): def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.instance = { "instance": { "volume": {"size": "1"}, "users": [ {"name": "user1", "password": "******", "databases": [{"name": "firstdb"}]} ], "flavorRef": "https://*****:*****@(D", "databases": [ { "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" } ] } } def verify_errors(self, errors, msg=None, properties=None, path=None): msg = msg or [] properties = properties or [] self.assertThat(len(errors), Is(len(msg))) i = 0 while i < len(msg): self.assertIn(errors[i].message, msg) if path: self.assertThat(path, Equals(properties[i])) else: self.assertThat(errors[i].path.pop(), Equals(properties[i])) i += 1 def test_get_schema_create(self): schema = self.controller.get_schema('create', {'instance': {}}) self.assertIsNotNone(schema) self.assertTrue('instance' in schema['properties']) def test_get_schema_action_restart(self): schema = self.controller.get_schema('action', {'restart': {}}) self.assertIsNotNone(schema) self.assertTrue('restart' in schema['properties']) def test_get_schema_action_resize_volume(self): schema = self.controller.get_schema( 'action', {'resize': {'volume': {}}}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'volume' in schema['properties']['resize']['properties']) def test_get_schema_action_resize_flavorRef(self): schema = self.controller.get_schema( 'action', {'resize': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'flavorRef' in schema['properties']['resize']['properties']) def test_get_schema_action_other(self): schema = self.controller.get_schema( 'action', {'supersized': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertThat(len(schema.keys()), Is(0)) def test_validate_create_complete(self): body = self.instance schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance body['instance']['restorePoint'] = { "backupRef": "d761edd8-0771-46ff-9743-688b9e297a3b" } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore_error(self): body = self.instance backup_id_ref = "invalid-backup-id-ref" body['instance']['restorePoint'] = { "backupRef": backup_id_ref } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("'%s' does not match '%s'" % (backup_id_ref, apischema.uuid['pattern']))) def test_validate_create_blankname(self): body = self.instance body['instance']['name'] = " " schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("' ' does not match '^.*[0-9a-zA-Z]+.*$'")) def test_validate_restart(self): body = {"restart": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_invalid_action(self): # TODO(juice) perhaps we should validate the schema not recognized body = {"restarted": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume(self): body = {"resize": {"volume": {"size": 4}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string(self): body = {"resize": {"volume": {"size": '-44.0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_invalid(self): body = {"resize": {"volume": {"size": 'x'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("'x' is not of type 'integer'")) self.assertThat(errors[0].context[1].message, Equals("'x' does not match '[0-9]+'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_instance(self): body = {"resize": {"flavorRef": "https://endpoint/v1.0/123/flavors/2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int(self): body = {"resize": {"flavorRef": 2}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_empty_url(self): body = {"resize": {"flavorRef": ""}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors[0].context, ["'' is too short", "'' does not match 'http[s]?://(?:[a-zA-Z]" "|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]" "|(?:%[0-9a-fA-F][0-9a-fA-F]))+'", "'' does not match '[0-9]+'", "'' is not of type 'integer'"], ["flavorRef", "flavorRef", "flavorRef", "flavorRef"], errors[0].path.pop()) @skip("This damn URI validator allows just about any garbage you give it") def test_validate_resize_instance_invalid_url(self): body = {"resize": {"flavorRef": "xyz-re1f2-daze329d-f23901"}} schema = self.controller.get_schema('action', body) self.assertIsNotNone(schema) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors, ["'' is too short"], ["flavorRef"])
class TestInstanceController(TestCase): def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.instance = { "instance": { "volume": { "size": "1" }, "users": [{ "name": "user1", "password": "******", "databases": [{ "name": "firstdb" }] }], "flavorRef": "https://*****:*****@(D", "databases": [{ "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" }] } } def verify_errors(self, errors, msg=None, properties=None, path=None): msg = msg or [] properties = properties or [] self.assertThat(len(errors), Is(len(msg))) i = 0 while i < len(msg): self.assertThat(errors[i].message, Equals(msg[i])) if path: self.assertThat(path, Equals(properties[i])) else: self.assertThat(errors[i].path.pop(), Equals(properties[i])) i += 1 def test_get_schema_create(self): schema = self.controller.get_schema('create', {'instance': {}}) self.assertIsNotNone(schema) self.assertTrue('instance' in schema['properties']) def test_get_schema_action_restart(self): schema = self.controller.get_schema('action', {'restart': {}}) self.assertIsNotNone(schema) self.assertTrue('restart' in schema['properties']) def test_get_schema_action_resize_volume(self): schema = self.controller.get_schema('action', {'resize': { 'volume': {} }}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'volume' in schema['properties']['resize']['properties']) def test_get_schema_action_resize_flavorRef(self): schema = self.controller.get_schema('action', {'resize': { 'flavorRef': {} }}) self.assertIsNotNone(schema) self.assertTrue('resize' in schema['properties']) self.assertTrue( 'flavorRef' in schema['properties']['resize']['properties']) def test_get_schema_action_other(self): schema = self.controller.get_schema('action', {'supersized': { 'flavorRef': {} }}) self.assertIsNotNone(schema) self.assertThat(len(schema.keys()), Is(0)) def test_validate_create_complete(self): body = self.instance schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance body['instance']['restorePoint'] = { "backupRef": "d761edd8-0771-46ff-9743-688b9e297a3b" } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance backup_id_ref = "invalid-backup-id-ref" body['instance']['restorePoint'] = {"backupRef": backup_id_ref} schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat( errors[0].message, Equals("'%s' does not match '%s'" % (backup_id_ref, apischema.uuid['pattern']))) def test_validate_create_blankname(self): body = self.instance body['instance']['name'] = " " schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("' ' does not match '^.*[0-9a-zA-Z]+.*$'")) def test_validate_restart(self): body = {"restart": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_invalid_action(self): # TODO(juice) perhaps we should validate the schema not recognized body = {"restarted": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume(self): body = {"resize": {"volume": {"size": 4}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string(self): body = {"resize": {"volume": {"size": '-44.0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_invalid(self): body = {"resize": {"volume": {"size": 'x'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("'x' is not of type 'integer'")) self.assertThat(errors[0].context[1].message, Equals("'x' does not match '[0-9]+'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_instance(self): body = {"resize": {"flavorRef": "https://endpoint/v1.0/123/flavors/2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int(self): body = {"resize": {"flavorRef": 2}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int_xml(self): body = {"resize": {"flavorRef": "2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_empty_url(self): body = {"resize": {"flavorRef": ""}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors[0].context, [ "'' is too short", "'' does not match 'http[s]?://(?:[a-zA-Z]" "|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]" "|(?:%[0-9a-fA-F][0-9a-fA-F]))+'", "'' does not match '[0-9]+'", "'' is not of type 'integer'" ], ["flavorRef", "flavorRef", "flavorRef", "flavorRef"], errors[0].path.pop()) @skip("This damn URI validator allows just about any garbage you give it") def test_validate_resize_instance_invalid_url(self): body = {"resize": {"flavorRef": "xyz-re1f2-daze329d-f23901"}} schema = self.controller.get_schema('action', body) self.assertIsNotNone(schema) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors, ["'' is too short"], ["flavorRef"])
class TestInstanceController(trove_testtools.TestCase): def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.locality = 'affinity' self.instance = { "instance": { "volume": { "size": "1" }, "users": [{ "name": "user1", "password": "******", "databases": [{ "name": "firstdb" }] }], "flavorRef": "https://*****:*****@(D", "databases": [{ "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" }], "locality": self.locality } } self.context = trove_testtools.TroveTestContext(self) self.req = Mock(remote_addr='ip:port', host='myhost') def verify_errors(self, errors, msg=None, properties=None, path=None): msg = msg or [] properties = properties or [] self.assertThat(len(errors), Is(len(msg))) i = 0 while i < len(msg): self.assertIn(errors[i].message, msg) if path: self.assertThat(path, Equals(properties[i])) else: self.assertThat(errors[i].path.pop(), Equals(properties[i])) i += 1 def test_get_schema_create(self): schema = self.controller.get_schema('create', {'instance': {}}) self.assertIsNotNone(schema) self.assertIn('instance', schema['properties']) def test_get_schema_action_restart(self): schema = self.controller.get_schema('action', {'restart': {}}) self.assertIsNotNone(schema) self.assertIn('restart', schema['properties']) def test_get_schema_action_resize_volume(self): schema = self.controller.get_schema('action', {'resize': { 'volume': {} }}) self.assertIsNotNone(schema) self.assertIn('resize', schema['properties']) self.assertIn('volume', schema['properties']['resize']['properties']) def test_get_schema_action_resize_flavorRef(self): schema = self.controller.get_schema('action', {'resize': { 'flavorRef': {} }}) self.assertIsNotNone(schema) self.assertIn('resize', schema['properties']) self.assertIn('flavorRef', schema['properties']['resize']['properties']) def test_get_schema_action_other(self): schema = self.controller.get_schema('action', {'supersized': { 'flavorRef': {} }}) self.assertIsNotNone(schema) self.assertThat(len(schema.keys()), Is(0)) def test_validate_create_complete(self): body = self.instance schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance body['instance']['restorePoint'] = { "backupRef": "d761edd8-0771-46ff-9743-688b9e297a3b" } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore_error(self): body = self.instance backup_id_ref = "invalid-backup-id-ref" body['instance']['restorePoint'] = {"backupRef": backup_id_ref} schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat( errors[0].message, Equals("'%s' does not match '%s'" % (backup_id_ref, apischema.uuid['pattern']))) def test_validate_create_blankname(self): body = self.instance body['instance']['name'] = " " schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("' ' does not match '^.*[0-9a-zA-Z]+.*$'")) def test_validate_create_invalid_name(self): body = self.instance body['instance']['name'] = "$#$%^^" schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertEqual(1, len(errors)) self.assertIn("'$#$%^^' does not match '^.*[0-9a-zA-Z]+.*$'", errors[0].message) def test_validate_create_invalid_locality(self): body = self.instance body['instance']['locality'] = "$%^" schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) error_messages = [error.message for error in errors] error_paths = [error.path.pop() for error in errors] self.assertEqual(1, len(errors)) self.assertIn("'$%^' does not match '^.*[0-9a-zA-Z]+.*$'", error_messages) self.assertIn("locality", error_paths) def test_validate_create_valid_nics(self): body = copy.copy(self.instance) body['instance']['nics'] = [{ 'network_id': str(uuid.uuid4()), 'subnet_id': str(uuid.uuid4()), 'ip_address': '192.168.1.11' }] schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_restart(self): body = {"restart": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_invalid_action(self): # TODO(juice) perhaps we should validate the schema not recognized body = {"restarted": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume(self): body = {"resize": {"volume": {"size": 4}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string(self): body = {"resize": {"volume": {"size": "4"}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string_start_with_zero(self): body = {"resize": {"volume": {"size": "0040"}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string_invalid_number(self): body = {"resize": {"volume": {"size": '-44.0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[1].message, Equals("'-44.0' does not match '^0*[1-9]+[0-9]*$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_volume_invalid_characters(self): body = {"resize": {"volume": {"size": 'x'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("'x' is not of type 'integer'")) self.assertThat(errors[0].context[1].message, Equals("'x' does not match '^0*[1-9]+[0-9]*$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_volume_zero_number(self): body = {"resize": {"volume": {"size": 0}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("0 is less than the minimum of 1")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_volume_string_zero_number(self): body = {"resize": {"volume": {"size": '0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[1].message, Equals("'0' does not match '^0*[1-9]+[0-9]*$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_instance(self): body = {"resize": {"flavorRef": "https://endpoint/v1.0/123/flavors/2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int(self): body = {"resize": {"flavorRef": 2}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_string(self): body = {"resize": {"flavorRef": 'foo'}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_empty_url(self): body = {"resize": {"flavorRef": ""}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors[0].context, [ "'' is too short", "'' does not match '^.*[0-9a-zA-Z]+.*$'", "'' is not of type 'integer'" ], ["flavorRef", "flavorRef", "flavorRef", "flavorRef"], errors[0].path.pop()) @skip("This URI validator allows just about anything you give it") def test_validate_resize_instance_invalid_url(self): body = {"resize": {"flavorRef": "xyz-re1f2-daze329d-f23901"}} schema = self.controller.get_schema('action', body) self.assertIsNotNone(schema) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors, ["'' is too short"], ["flavorRef"]) def _setup_modify_instance_mocks(self): instance = Mock() instance.detach_replica = Mock() instance.attach_configuration = Mock() instance.detach_configuration = Mock() instance.update_db = Mock() instance.update_access = Mock() return instance def test_modify_instance_with_empty_args(self): instance = self._setup_modify_instance_mocks() args = {} self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(0, instance.detach_replica.call_count) self.assertEqual(0, instance.detach_configuration.call_count) self.assertEqual(0, instance.attach_configuration.call_count) self.assertEqual(0, instance.update_db.call_count) def test_modify_instance_with_False_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = False self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(0, instance.detach_replica.call_count) def test_modify_instance_with_True_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = True self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.detach_replica.call_count) def test_modify_instance_with_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = 'some_id' self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.attach_configuration.call_count) def test_modify_instance_with_None_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = None self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.detach_configuration.call_count) def test_update_api_invalid_field(self): body = {'instance': {'invalid': 'invalid'}} schema = self.controller.get_schema('update', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) @mock.patch('trove.instance.models.Instance.load') def test_update_name(self, load_mock): body = {'instance': {'name': 'new_name'}} ins_mock = MagicMock() load_mock.return_value = ins_mock self.controller.update(MagicMock(), 'fake_id', body, 'fake_tenant_id') ins_mock.update_db.assert_called_once_with(name='new_name') def test_update_multiple_operations(self): body = { 'instance': { 'name': 'new_name', 'replica_of': None, 'configuration': 'fake_config_id' } } self.assertRaises(exception.BadRequest, self.controller.update, MagicMock(), 'fake_id', body, 'fake_tenant_id') @mock.patch('trove.instance.models.Instance.load') def test_update_name_and_access(self, load_mock): body = { 'instance': { 'name': 'new_name', 'access': { 'is_public': True, 'allowed_cidrs': [] } } } ins_mock = MagicMock() load_mock.return_value = ins_mock self.controller.update(MagicMock(), 'fake_id', body, 'fake_tenant_id') ins_mock.update_db.assert_called_once_with(name='new_name') ins_mock.update_access.assert_called_once_with( body['instance']['access'])
class TestInstanceController(trove_testtools.TestCase): def setUp(self): super(TestInstanceController, self).setUp() self.controller = InstanceController() self.locality = 'affinity' self.instance = { "instance": { "volume": {"size": "1"}, "users": [ {"name": "user1", "password": "******", "databases": [{"name": "firstdb"}]} ], "flavorRef": "https://*****:*****@(D", "databases": [ { "name": "firstdb", "collate": "latin2_general_ci", "character_set": "latin2" }, { "name": "db2" } ], "locality": self.locality } } self.context = trove_testtools.TroveTestContext(self) self.req = Mock(remote_addr='ip:port', host='myhost') def verify_errors(self, errors, msg=None, properties=None, path=None): msg = msg or [] properties = properties or [] self.assertThat(len(errors), Is(len(msg))) i = 0 while i < len(msg): self.assertIn(errors[i].message, msg) if path: self.assertThat(path, Equals(properties[i])) else: self.assertThat(errors[i].path.pop(), Equals(properties[i])) i += 1 def test_get_schema_create(self): schema = self.controller.get_schema('create', {'instance': {}}) self.assertIsNotNone(schema) self.assertIn('instance', schema['properties']) def test_get_schema_action_restart(self): schema = self.controller.get_schema('action', {'restart': {}}) self.assertIsNotNone(schema) self.assertIn('restart', schema['properties']) def test_get_schema_action_resize_volume(self): schema = self.controller.get_schema( 'action', {'resize': {'volume': {}}}) self.assertIsNotNone(schema) self.assertIn('resize', schema['properties']) self.assertIn( 'volume', schema['properties']['resize']['properties']) def test_get_schema_action_resize_flavorRef(self): schema = self.controller.get_schema( 'action', {'resize': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertIn('resize', schema['properties']) self.assertIn( 'flavorRef', schema['properties']['resize']['properties']) def test_get_schema_action_other(self): schema = self.controller.get_schema( 'action', {'supersized': {'flavorRef': {}}}) self.assertIsNotNone(schema) self.assertThat(len(schema.keys()), Is(0)) def test_validate_create_complete(self): body = self.instance schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore(self): body = self.instance body['instance']['restorePoint'] = { "backupRef": "d761edd8-0771-46ff-9743-688b9e297a3b" } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_create_complete_with_restore_error(self): body = self.instance backup_id_ref = "invalid-backup-id-ref" body['instance']['restorePoint'] = { "backupRef": backup_id_ref } schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("'%s' does not match '%s'" % (backup_id_ref, apischema.uuid['pattern']))) def test_validate_create_blankname(self): body = self.instance body['instance']['name'] = " " schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(len(errors), Is(1)) self.assertThat(errors[0].message, Equals("' ' does not match '^.*[0-9a-zA-Z]+.*$'")) def test_validate_create_invalid_name(self): body = self.instance body['instance']['name'] = "$#$%^^" schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertEqual(1, len(errors)) self.assertIn("'$#$%^^' does not match '^.*[0-9a-zA-Z]+.*$'", errors[0].message) def test_validate_create_invalid_locality(self): body = self.instance body['instance']['locality'] = "$%^" schema = self.controller.get_schema('create', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) error_messages = [error.message for error in errors] error_paths = [error.path.pop() for error in errors] self.assertEqual(1, len(errors)) self.assertIn("'$%^' does not match '^.*[0-9a-zA-Z]+.*$'", error_messages) self.assertIn("locality", error_paths) def test_validate_restart(self): body = {"restart": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_invalid_action(self): # TODO(juice) perhaps we should validate the schema not recognized body = {"restarted": {}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume(self): body = {"resize": {"volume": {"size": 4}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string(self): body = {"resize": {"volume": {"size": "4"}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_volume_string_invalid_number(self): body = {"resize": {"volume": {"size": '-44.0'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[1].message, Equals("'-44.0' does not match '^[0-9]+$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_volume_invalid_characters(self): body = {"resize": {"volume": {"size": 'x'}}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.assertThat(errors[0].context[0].message, Equals("'x' is not of type 'integer'")) self.assertThat(errors[0].context[1].message, Equals("'x' does not match '^[0-9]+$'")) self.assertThat(errors[0].path.pop(), Equals('size')) def test_validate_resize_instance(self): body = {"resize": {"flavorRef": "https://endpoint/v1.0/123/flavors/2"}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_int(self): body = {"resize": {"flavorRef": 2}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_string(self): body = {"resize": {"flavorRef": 'foo'}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertTrue(validator.is_valid(body)) def test_validate_resize_instance_empty_url(self): body = {"resize": {"flavorRef": ""}} schema = self.controller.get_schema('action', body) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors[0].context, ["'' is too short", "'' does not match '^.*[0-9a-zA-Z]+.*$'", "'' is not of type 'integer'"], ["flavorRef", "flavorRef", "flavorRef", "flavorRef"], errors[0].path.pop()) @skip("This URI validator allows just about anything you give it") def test_validate_resize_instance_invalid_url(self): body = {"resize": {"flavorRef": "xyz-re1f2-daze329d-f23901"}} schema = self.controller.get_schema('action', body) self.assertIsNotNone(schema) validator = jsonschema.Draft4Validator(schema) self.assertFalse(validator.is_valid(body)) errors = sorted(validator.iter_errors(body), key=lambda e: e.path) self.verify_errors(errors, ["'' is too short"], ["flavorRef"]) def _setup_modify_instance_mocks(self): instance = Mock() instance.detach_replica = Mock() instance.attach_configuration = Mock() instance.detach_configuration = Mock() instance.update_db = Mock() return instance def test_modify_instance_with_empty_args(self): instance = self._setup_modify_instance_mocks() args = {} self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(0, instance.detach_replica.call_count) self.assertEqual(0, instance.detach_configuration.call_count) self.assertEqual(0, instance.attach_configuration.call_count) self.assertEqual(0, instance.update_db.call_count) def test_modify_instance_with_nonempty_args_calls_update_db(self): instance = self._setup_modify_instance_mocks() args = {} args['any'] = 'anything' self.controller._modify_instance(self.context, self.req, instance, **args) instance.update_db.assert_called_once_with(**args) def test_modify_instance_with_False_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = False self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(0, instance.detach_replica.call_count) def test_modify_instance_with_True_detach_replica_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = True self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.detach_replica.call_count) def test_modify_instance_with_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = 'some_id' self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.attach_configuration.call_count) def test_modify_instance_with_None_configuration_id_arg(self): instance = self._setup_modify_instance_mocks() args = {} args['configuration_id'] = None self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.detach_configuration.call_count) def test_modify_instance_with_all_args(self): instance = self._setup_modify_instance_mocks() args = {} args['detach_replica'] = True args['configuration_id'] = 'some_id' self.controller._modify_instance(self.context, self.req, instance, **args) self.assertEqual(1, instance.detach_replica.call_count) self.assertEqual(1, instance.attach_configuration.call_count) instance.update_db.assert_called_once_with(**args) def test_create_databases_none(self): req = {'instance': {'databases': []}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(0, len(users)) self.assertEqual(0, len(databases)) def test_create_databases_single(self): req = {'instance': {'databases': [{'name': 'one_db'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(0, len(users)) self.assertEqual(1, len(databases)) def test_create_databases_unique(self): req = {'instance': {'databases': [{'name': 'one_db'}, {'name': 'diff_db'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(0, len(users)) self.assertEqual(2, len(databases)) def test_create_databases_duplicate(self): req = {'instance': {'users': [], 'databases': [{'name': 'same_db'}, {'name': 'same_db'}]}} self.assertRaises(exception.DatabaseInitialDatabaseDuplicateError, self.controller._parse_users_and_databases, 'mysql', req) def test_create_databases_intermingled(self): req = {'instance': {'users': [], 'databases': [{'name': 'a_db'}, {'name': 'b_db'}, {'name': 'a_db'}]}} self.assertRaises(exception.DatabaseInitialDatabaseDuplicateError, self.controller._parse_users_and_databases, 'mysql', req) def test_populate_users_single(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(1, len(users)) self.assertEqual(0, len(databases)) def test_populate_users_unique_host(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'host': '127.0.0.1'}, {'name': 'bob', 'password': '******', 'host': '128.0.0.1'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(2, len(users)) self.assertEqual(0, len(databases)) def test_populate_users_unique_name(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'host': '127.0.0.1'}, {'name': 'tom', 'password': '******', 'host': '127.0.0.1'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(2, len(users)) self.assertEqual(0, len(databases)) def test_create_users_duplicate(self): req = {'instance': {'users': [ {'name': 'bob', 'password': '******', 'host': '127.0.0.1'}, {'name': 'bob', 'password': '******', 'host': '127.0.0.1'}]}} self.assertRaises(exception.DatabaseInitialUserDuplicateError, self.controller._parse_users_and_databases, 'mysql', req) def test_create_users_intermingled(self): req = {'instance': {'users': [ {'name': 'bob', 'password': '******', 'host': '127.0.0.1'}, {'name': 'tom', 'password': '******', 'host': '128.0.0.1'}, {'name': 'bob', 'password': '******', 'host': '127.0.0.1'}]}} self.assertRaises(exception.DatabaseInitialUserDuplicateError, self.controller._parse_users_and_databases, 'mysql', req) def test_create_users_both_db_list_empty(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******'}], 'databases': []}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(1, len(users)) self.assertEqual(0, len(databases)) def test_create_users_db_list_empty(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'databases': [{'name': 'my_db'}]}], 'databases': []}} self.assertRaises(exception.DatabaseForUserNotInDatabaseListError, self.controller._parse_users_and_databases, 'mysql', req) def test_create_users_user_db_list_empty(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******'}], 'databases': [{'name': 'my_db'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(1, len(users)) self.assertEqual(1, len(databases)) def test_create_users_db_in_list(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'databases': [{'name': 'my_db'}]}], 'databases': [{'name': 'my_db'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(1, len(users)) self.assertEqual(1, len(databases)) def test_create_users_db_multi_in_list(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'databases': [{'name': 'a_db'}]}, {'name': 'tom', 'password': '******', 'databases': [{'name': 'c_db'}]}, {'name': 'sue', 'password': '******', 'databases': [{'name': 'c_db'}]}], 'databases': [{'name': 'a_db'}, {'name': 'b_db'}, {'name': 'c_db'}, {'name': 'd_db'}]}} users, databases = self.controller._parse_users_and_databases( 'mysql', req) self.assertEqual(3, len(users)) self.assertEqual(4, len(databases)) def test_create_users_db_not_in_list(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'databases': [{'name': 'fake_db'}]}], 'databases': [{'name': 'a_db'}, {'name': 'b_db'}, {'name': 'c_db'}, {'name': 'd_db'}]}} self.assertRaises( exception.DatabaseForUserNotInDatabaseListError, self.controller._parse_users_and_databases, 'mysql', req) def test_create_users_db_multi_not_in_list(self): req = {'instance': {'users': [{'name': 'bob', 'password': '******', 'databases': [{'name': 'a_db'}]}, {'name': 'tom', 'password': '******', 'databases': [{'name': 'fake_db'}]}, {'name': 'sue', 'password': '******', 'databases': [{'name': 'd_db'}]}], 'databases': [{'name': 'a_db'}, {'name': 'b_db'}, {'name': 'c_db'}, {'name': 'd_db'}]}} self.assertRaises( exception.DatabaseForUserNotInDatabaseListError, self.controller._parse_users_and_databases, 'mysql', req)