def test___init__for_new_users(self): self.context["config"]["users"] = { "tenants": 1, "users_per_tenant": 1, "resource_management_workers": 1 } user_generator = users.UserGenerator(self.context) self.assertEqual([], user_generator.existing_users) self.assertEqual(self.admin_cred["project_domain_name"], user_generator.config["project_domain"]) self.assertEqual(self.admin_cred["user_domain_name"], user_generator.config["user_domain"]) # the case #2 - existing users are presented in deployment but # the user forces to create new ones self.platforms["openstack"]["users"] = [mock.Mock()] user_generator = users.UserGenerator(self.context) self.assertEqual([], user_generator.existing_users) self.assertEqual(self.admin_cred["project_domain_name"], user_generator.config["project_domain"]) self.assertEqual(self.admin_cred["user_domain_name"], user_generator.config["user_domain"])
def test__delete_users(self, mock_identity): user_generator = users.UserGenerator(self.context) user1 = mock.MagicMock() user2 = mock.MagicMock() user_generator.context["users"] = [user1, user2] user_generator._delete_users() self.assertEqual(0, len(user_generator.context["users"]))
def test__create_tenants(self, mock_identity): self.context["config"]["users"]["tenants"] = 1 user_generator = users.UserGenerator(self.context) tenants = user_generator._create_tenants(1) self.assertEqual(1, len(tenants)) id, tenant = tenants.popitem() self.assertIn("name", tenant)
def test__remove_default_security_group_no_sg(self): self.context.update(tenants={"tenant-1": {}, "tenant-2": {}}) self.osclients.Clients.return_value = mock.Mock() neutron = self.osclients.Clients.return_value.neutron.return_value neutron.list_extensions.return_value = {"extensions": []} neutron.list_security_groups.return_value = { "security_groups": [{ "id": "id-1", "name": "default", "tenant_id": "tenant-1" }, { "id": "id-2", "name": "default", "tenant_id": "tenant-2" }, { "id": "id-3", "name": "default", "tenant_id": "tenant-3" }] } users.UserGenerator(self.context)._remove_default_security_group() self.assertFalse(neutron.list_security_groups.called) self.assertFalse(neutron.delete_security_group.called)
def test__remove_default_security_group(self): self.context.update(tenants={"tenant-1": {}, "tenant-2": {}}) self.osclients.Clients.return_value = mock.Mock() neutron = self.osclients.Clients.return_value.neutron.return_value neutron.list_extensions.return_value = { "extensions": [{ "alias": "security-group" }] } neutron.list_security_groups.return_value = { "security_groups": [{ "id": "id-1", "name": "default", "tenant_id": "tenant-1" }, { "id": "id-2", "name": "default", "tenant_id": "tenant-2" }, { "id": "id-3", "name": "default", "tenant_id": "tenant-3" }] } users.UserGenerator(self.context)._remove_default_security_group() neutron.list_security_groups.assert_called_once_with(name="default") self.assertEqual( [mock.call("id-1"), mock.call("id-2")], neutron.delete_security_group.call_args_list)
def test_users_contains_default_endpoint_type(self, mock_identity): credential = oscredential.OpenStackCredential("foo_url", "foo", "foo_pass") config = { "config": { "users": { "tenants": 1, "users_per_tenant": 2, "resource_management_workers": 1 } }, "env": { "platforms": { "openstack": { "admin": credential, "users": [] } } }, "task": { "uuid": "task_id", "deployment_uuid": "deployment_id" } } user_generator = users.UserGenerator(config) users_ = user_generator._create_users(2) for user in users_: self.assertEqual("public", user["credential"].endpoint_type)
def test__remove_default_security_group(self, mock_network): net_wrapper = mock.Mock(SERVICE_IMPL=consts.Service.NEUTRON) net_wrapper.supports_extension.return_value = (True, None) mock_network.wrap.return_value = net_wrapper user_generator = users.UserGenerator(self.context) admin_clients = mock.Mock() admin_clients.services.return_value = { "compute": consts.Service.NOVA, "neutron": consts.Service.NEUTRON } user1 = mock.Mock() user1.neutron.return_value.list_security_groups.return_value = { "security_groups": [{ "id": "id-1", "name": "default" }, { "id": "id-2", "name": "not-default" }] } user2 = mock.Mock() user2.neutron.return_value.list_security_groups.return_value = { "security_groups": [{ "id": "id-3", "name": "default" }, { "id": "id-4", "name": "not-default" }] } user_clients = [user1, user2] self.osclients.Clients.side_effect = [admin_clients] + user_clients user_generator._iterate_per_tenants = mock.MagicMock( return_value=[(mock.MagicMock(), "t1"), (mock.MagicMock(), "t2")]) user_generator._remove_default_security_group() mock_network.wrap.assert_called_once_with(admin_clients, user_generator) user_generator._iterate_per_tenants.assert_called_once_with() expected = [mock.call(user_generator.credential)] + [ mock.call(u["credential"]) for u, t in user_generator._iterate_per_tenants.return_value ] self.osclients.Clients.assert_has_calls(expected, any_order=True) user_net = user1.neutron.return_value user_net.list_security_groups.assert_called_once_with(tenant_id="t1") user_net = user2.neutron.return_value user_net.list_security_groups.assert_called_once_with(tenant_id="t2") admin_neutron = admin_clients.neutron.return_value self.assertEqual( [mock.call("id-1"), mock.call("id-3")], admin_neutron.delete_security_group.call_args_list)
def test__delete_users_failure(self, mock_identity): identity_service = mock_identity.Identity.return_value identity_service.delete_user.side_effect = Exception() user_generator = users.UserGenerator(self.context) user1 = mock.MagicMock() user2 = mock.MagicMock() user_generator.context["users"] = [user1, user2] user_generator._delete_users() self.assertEqual(0, len(user_generator.context["users"]))
def test___init__for_existing_users(self): foo_user = mock.Mock() self.platforms["openstack"]["users"] = [foo_user] user_generator = users.UserGenerator(self.context) self.assertEqual([foo_user], user_generator.existing_users) self.assertEqual({"user_choice_method": "random"}, user_generator.config) # the case #2: the config with `user_choice_method` option self.context["config"]["users"] = {"user_choice_method": "foo"} user_generator = users.UserGenerator(self.context) self.assertEqual([foo_user], user_generator.existing_users) self.assertEqual({"user_choice_method": "foo"}, user_generator.config)
def test_users_and_tenants_in_context(self, mock_identity): identity_service = mock_identity.Identity.return_value credential = oscredential.OpenStackCredential("foo_url", "foo", "foo_pass", https_insecure=True, https_cacert="cacert") tmp_context = dict(self.context) tmp_context["config"]["users"] = { "tenants": 1, "users_per_tenant": 2, "resource_management_workers": 1 } tmp_context["env"]["platforms"]["openstack"]["admin"] = credential credential_dict = credential.to_dict() user_list = [ mock.MagicMock(id="id_%d" % i) for i in range(self.users_num) ] identity_service.create_user.side_effect = user_list with users.UserGenerator(tmp_context) as ctx: ctx.generate_random_name = mock.Mock() ctx.setup() create_tenant_calls = [] for i, t in enumerate(ctx.context["tenants"]): create_tenant_calls.append( mock.call(ctx.generate_random_name.return_value, ctx.config["project_domain"])) for user in ctx.context["users"]: self.assertEqual(set(["id", "credential", "tenant_id"]), set(user.keys())) user_credential_dict = user["credential"].to_dict() excluded_keys = [ "auth_url", "username", "password", "tenant_name", "region_name", "project_domain_name", "user_domain_name", "permission" ] for key in (set(credential_dict.keys()) - set(excluded_keys)): self.assertEqual(credential_dict[key], user_credential_dict[key], "The key '%s' differs." % key) tenants_ids = [] for t in ctx.context["tenants"].keys(): tenants_ids.append(t) for (user, tenant_id, orig_user) in zip(ctx.context["users"], tenants_ids, user_list): self.assertEqual(orig_user.id, user["id"]) self.assertEqual(tenant_id, user["tenant_id"])
def test_setup_and_cleanup_with_error_during_create_user( self, mock_identity, mock_log_warning): identity_service = mock_identity.Identity.return_value identity_service.create_user.side_effect = Exception() with users.UserGenerator(self.context) as ctx: self.assertRaises(exceptions.ContextSetupFailure, ctx.setup) mock_log_warning.assert_called_with( "Failed to consume a task from the queue: ") # Ensure that tenants get deleted anyway self.assertEqual(0, len(ctx.context["tenants"]))
def test_setup_and_cleanup(self, mock_identity): with users.UserGenerator(self.context) as ctx: ctx.setup() self.assertEqual(self.users_num, len(ctx.context["users"])) self.assertEqual(self.tenants_num, len(ctx.context["tenants"])) self.assertEqual("random", ctx.context["user_choice_method"]) # Cleanup (called by content manager) self.assertEqual(0, len(ctx.context["users"])) self.assertEqual(0, len(ctx.context["tenants"]))
def test__delete_tenants(self, mock_identity): user_generator = users.UserGenerator(self.context) user_generator.context["tenants"] = { "t1": { "id": "t1", "name": "t1" }, "t2": { "id": "t2", "name": "t2" } } user_generator._delete_tenants() self.assertEqual(0, len(user_generator.context["tenants"]))
def create_projects_and_users(admin_creds, projects_count, users_per_project): """Create new projects and users via 'users@openstack' context. :param admin_creds: admin credentials to use for creating new entities :param projects_count: The number of keystone projects to create. :param users_per_project: The number of keystone users to create per one keystone project. """ # it should be imported after calling rally.api.API that setups oslo_config from rally_openstack.task.contexts.keystone import users as users_ctx ctx = { "env": { "platforms": { "openstack": { "admin": admin_creds.to_dict(), "users": [] } } }, "task": { "uuid": str(uuid.uuid4()) }, "config": { "users@openstack": { "tenants": projects_count, "users_per_tenant": users_per_project } } } users_ctx.UserGenerator(ctx).setup() users = [] for user in ctx["users"]: users.append({ "username": user["credential"]["username"], "password": user["credential"]["password"], "project_name": user["credential"]["tenant_name"] }) for optional in ("domain_name", "user_domain_name", "project_domain_name"): if user["credential"][optional]: users[-1][optional] = user["credential"][optional] return users
def test__delete_tenants_failure(self, mock_identity): identity_service = mock_identity.Identity.return_value identity_service.delete_project.side_effect = Exception() user_generator = users.UserGenerator(self.context) user_generator.context["tenants"] = { "t1": { "id": "t1", "name": "t1" }, "t2": { "id": "t2", "name": "t2" } } user_generator._delete_tenants() self.assertEqual(0, len(user_generator.context["tenants"]))
def test__create_users(self, mock_identity): self.context["config"]["users"]["users_per_tenant"] = 2 user_generator = users.UserGenerator(self.context) user_generator.context["tenants"] = { "t1": { "id": "t1", "name": "t1" }, "t2": { "id": "t2", "name": "t2" } } users_ = user_generator._create_users(4) self.assertEqual(4, len(users_)) for user in users_: self.assertIn("id", user) self.assertIn("credential", user)
def test__remove_default_security_group_neutron_no_sg(self, mock_wrap): net_wrapper = mock.Mock(SERVICE_IMPL=consts.Service.NEUTRON) net_wrapper.supports_extension.return_value = (False, None) mock_wrap.return_value = net_wrapper user_generator = users.UserGenerator(self.context) admin_clients = mock.Mock() admin_clients.services.return_value = { "compute": consts.Service.NOVA, "neutron": consts.Service.NEUTRON } user_clients = [mock.Mock(), mock.Mock()] self.osclients.Clients.side_effect = [admin_clients] + user_clients user_generator._remove_default_security_group() mock_wrap.assert_called_once_with(admin_clients, user_generator) net_wrapper.supports_extension.assert_called_once_with( "security-group")
def test_setup(self): user_generator = users.UserGenerator(self.context) user_generator.use_existing_users = mock.Mock() user_generator.create_users = mock.Mock() # no existing users -> new users should be created user_generator.existing_users = [] user_generator.setup() user_generator.create_users.assert_called_once_with() self.assertFalse(user_generator.use_existing_users.called) user_generator.create_users.reset_mock() user_generator.use_existing_users.reset_mock() # existing_users is not empty -> existing users should be created user_generator.existing_users = [mock.Mock()] user_generator.setup() user_generator.use_existing_users.assert_called_once_with() self.assertFalse(user_generator.create_users.called)
def test_cleanup(self): user_generator = users.UserGenerator(self.context) user_generator._remove_default_security_group = mock.Mock() user_generator._delete_users = mock.Mock() user_generator._delete_tenants = mock.Mock() # In case if existing users nothing should be done user_generator.existing_users = [mock.Mock] user_generator.cleanup() self.assertFalse(user_generator._remove_default_security_group.called) self.assertFalse(user_generator._delete_users.called) self.assertFalse(user_generator._delete_tenants.called) # In case when new users were created, the proper cleanup should be # performed user_generator.existing_users = [] user_generator.cleanup() user_generator._remove_default_security_group.assert_called_once_with() user_generator._delete_users.assert_called_once_with() user_generator._delete_tenants.assert_called_once_with()
def test__remove_default_security_group_not_needed(self, mock_wrap): services = {"compute": consts.Service.NOVA} self.osclients.Clients().services.return_value = services user_generator = users.UserGenerator(self.context) user_generator._remove_default_security_group() self.assertFalse(mock_wrap.called)
def test_task_samples_are_valid(self): from rally_openstack.task.contexts.keystone import users rally = utils.Rally(force_new_db=True) # let's use pre-created users to make TestTaskSamples quicker rapi = api.API(config_file=rally.config_filename) deployment = rapi.deployment._get("MAIN") openstack_platform = deployment.env_obj.data["platforms"]["openstack"] admin_creds = credential.OpenStackCredential( permission=consts.EndpointPermission.ADMIN, **openstack_platform["platform_data"]["admin"]) ctx = { "env": { "platforms": { "openstack": { "admin": admin_creds.to_dict(), "users": [] } } }, "task": { "uuid": self.__class__.__name__, "deployment_uuid": deployment["uuid"] } } user_ctx = users.UserGenerator(ctx) user_ctx.setup() self.addCleanup(user_ctx.cleanup) os_creds = deployment["config"]["openstack"] user = copy.copy(os_creds["admin"]) user["username"] = ctx["users"][0]["credential"].username user["password"] = ctx["users"][0]["credential"].password if "project_name" in os_creds["admin"]: # it is Keystone user["project_name"] = ctx["users"][0]["credential"].tenant_name else: user["tenant_name"] = ctx["users"][0]["credential"].tenant_name os_creds["users"] = [user] rally("deployment destroy MAIN", write_report=False) deployment_cfg = os.path.join(rally.tmp_dir, "new_deployment.json") with open(deployment_cfg, "w") as f: f.write(json.dumps({"openstack": os_creds})) rally("deployment create --name MAIN --filename %s" % deployment_cfg, write_report=False) # store all failures and print them at once failed_samples = {} def publisher(queue): """List all samples and render task configs""" samples_path = os.path.join( os.path.dirname(rally_openstack_module.__file__), os.pardir, "samples", "tasks") for dirname, dirnames, filenames in os.walk(samples_path): # NOTE(rvasilets): Skip by suggest of boris-42 because in # future we don't what to maintain this dir if dirname.find("tempest-do-not-run-against-production") != -1: continue for filename in filenames: full_path = os.path.join(dirname, filename) # NOTE(hughsaunders): Skip non config files # (bug https://bugs.launchpad.net/rally/+bug/1314369) if os.path.splitext(filename)[1] != ".json": continue with open(full_path) as task_file: input_task = task_file.read() rendered_task = rapi.task.render_template( task_template=input_task) queue.append((full_path, rendered_task)) def consumer(_cache, sample): """Validate one sample""" full_path, rendered_task = sample task_config = yaml.safe_load(rendered_task) try: rapi.task.validate(deployment="MAIN", config=task_config) except Exception as e: if not self._skip(str(e)): failed_samples[full_path] = traceback.format_exc() broker.run(publisher, consumer, self.NUMBER_OF_THREADS) if failed_samples: self.fail("Validation failed on the one or several samples. " "See details below:\n%s" % "".join([ "\n======\n%s\n\n%s\n" % (k, v) for k, v in failed_samples.items() ]))
def test_use_existing_users(self, mock_clients, mock_open_stack_credential): user1 = { "tenant_name": "proj", "username": "******", "password": "******", "auth_url": "https://example.com" } user2 = { "tenant_name": "proj", "username": "******", "password": "******", "auth_url": "https://example.com" } user3 = { "tenant_name": "proj", "username": "******", "password": "******", "auth_url": "https://example.com" } user_list = [user1, user2, user3] class AuthRef(object): USER_ID_COUNT = 0 PROJECT_ID_COUNT = 0 @property def user_id(self): self.USER_ID_COUNT += 1 return "u%s" % self.USER_ID_COUNT @property def project_id(self): self.PROJECT_ID_COUNT += 1 return "p%s" % (self.PROJECT_ID_COUNT % 2) auth_ref = AuthRef() mock_clients.return_value.keystone.auth_ref = auth_ref self.platforms["openstack"]["users"] = user_list user_generator = users.UserGenerator(self.context) user_generator.setup() self.assertIn("users", self.context) self.assertIn("tenants", self.context) self.assertIn("user_choice_method", self.context) self.assertEqual("random", self.context["user_choice_method"]) creds = mock_open_stack_credential.return_value self.assertEqual([{ "id": "u1", "credential": creds, "tenant_id": "p1" }, { "id": "u2", "credential": creds, "tenant_id": "p0" }, { "id": "u3", "credential": creds, "tenant_id": "p1" }], self.context["users"]) self.assertEqual( { "p0": { "id": "p0", "name": creds.tenant_name }, "p1": { "id": "p1", "name": creds.tenant_name } }, self.context["tenants"])