From 03eee76877f4c956fcee77c62344c385d7a41ac2 Mon Sep 17 00:00:00 2001 From: Serhii Vasheka Date: Wed, 18 Mar 2015 15:25:27 +0200 Subject: [PATCH] Add keystone benchmark scenarios for roles Add keystone assign_and_remove_role scenario. API covered roles.add_user_role, roles.remove_user_role Add keystone create_and_delete_role scenario. API covered roles.create, roles.delete Add keystone create_and_list_user_roles scenario. API covered roles.create, roles.list Change-Id: Ib351c76774a63302e112ee45e6dcb93c85e3c3cc --- rally-jobs/rally.yaml | 38 +++++++++++++ .../openstack/scenarios/keystone/basic.py | 27 ++++++++++ .../openstack/scenarios/keystone/utils.py | 31 +++++++++++ .../keystone/create-and-delete-role.json | 11 ++++ .../keystone/create-and-delete-role.yaml | 7 +++ tests/unit/fakes.py | 3 ++ .../scenarios/keystone/test_basic.py | 54 +++++++++++++++++++ .../scenarios/keystone/test_utils.py | 52 ++++++++++++++++++ 8 files changed, 223 insertions(+) create mode 100644 samples/tasks/scenarios/keystone/create-and-delete-role.json create mode 100644 samples/tasks/scenarios/keystone/create-and-delete-role.yaml diff --git a/rally-jobs/rally.yaml b/rally-jobs/rally.yaml index cf63dde0..1fe5f9d3 100644 --- a/rally-jobs/rally.yaml +++ b/rally-jobs/rally.yaml @@ -46,6 +46,44 @@ failure_rate: max: 0 + KeystoneBasic.add_and_remove_user_role: + - + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + + KeystoneBasic.create_and_delete_role: + - + runner: + type: "constant" + times: 10 + concurrency: 5 + sla: + failure_rate: + max: 0 + + KeystoneBasic.create_add_and_list_user_roles: + - + runner: + type: "constant" + times: 10 + concurrency: 5 + context: + users: + tenants: 1 + users_per_tenant: 1 + sla: + failure_rate: + max: 0 + KeystoneBasic.create_and_list_users: - args: diff --git a/rally/plugins/openstack/scenarios/keystone/basic.py b/rally/plugins/openstack/scenarios/keystone/basic.py index 8d0c1c10..1e0f6039 100644 --- a/rally/plugins/openstack/scenarios/keystone/basic.py +++ b/rally/plugins/openstack/scenarios/keystone/basic.py @@ -99,6 +99,33 @@ class KeystoneBasic(kutils.KeystoneScenario): self._tenant_create(name_length=name_length, **kwargs) self._list_tenants() + @validation.required_openstack(admin=True, users=True) + @base.scenario(context={"admin_cleanup": ["keystone"]}) + def add_and_remove_user_role(self): + """Create a user role add to a user and disassociate.""" + tenant_id = self.context["tenant"]["id"] + user_id = self.context["user"]["id"] + role = self._role_create() + self._role_add(user_id, role, tenant_id) + self._role_remove(user_id, role, tenant_id) + + @validation.required_openstack(admin=True) + @base.scenario(context={"admin_cleanup": ["keystone"]}) + def create_and_delete_role(self): + """Create a user role and delete it.""" + role = self._role_create() + self._resource_delete(role) + + @validation.required_openstack(admin=True, users=True) + @base.scenario(context={"admin_cleanup": ["keystone"]}) + def create_add_and_list_user_roles(self): + """Create user role, add it and list user roles for given user.""" + tenant_id = self.context["tenant"]["id"] + user_id = self.context["user"]["id"] + role = self._role_create() + self._role_add(user_id, role, tenant_id) + self._list_roles_for_user(user_id, tenant_id) + @validation.required_openstack(admin=True) @base.scenario(context={"admin_cleanup": ["keystone"]}) def get_entities(self): diff --git a/rally/plugins/openstack/scenarios/keystone/utils.py b/rally/plugins/openstack/scenarios/keystone/utils.py index 7a9061f5..2953c519 100644 --- a/rally/plugins/openstack/scenarios/keystone/utils.py +++ b/rally/plugins/openstack/scenarios/keystone/utils.py @@ -120,6 +120,37 @@ class KeystoneScenario(base.Scenario): """List services.""" return self.admin_clients("keystone").services.list() + @base.atomic_action_timer("keystone.list_roles") + def _list_roles_for_user(self, user, tenant): + """List user roles. + + :param user: user for whom roles will be listed + :param tenant: tenant on which user have roles + """ + return self.admin_clients("keystone").roles.roles_for_user( + user, tenant) + + @base.atomic_action_timer("keystone.add_role") + def _role_add(self, user, role, tenant): + """Add role to a given user on a tenant. + + :param user: user to be assigned the role to + :param role: user role to assign with + :param tenant: tenant on which assignation will take place + """ + self.admin_clients("keystone").roles.add_user_role(user, role, tenant) + + @base.atomic_action_timer("keystone.remove_role") + def _role_remove(self, user, role, tenant): + """Dissociate user with role. + + :param user: user to be stripped with role + :param role: role to be dissociated with user + :param tenant: tenant on which assignation took place + """ + self.admin_clients("keystone").roles.remove_user_role(user, + role, tenant) + @base.atomic_action_timer("keystone.get_tenant") def _get_tenant(self, tenant_id): """Get given tenant. diff --git a/samples/tasks/scenarios/keystone/create-and-delete-role.json b/samples/tasks/scenarios/keystone/create-and-delete-role.json new file mode 100644 index 00000000..25f95e6d --- /dev/null +++ b/samples/tasks/scenarios/keystone/create-and-delete-role.json @@ -0,0 +1,11 @@ +{ + "KeystoneBasic.create_and_delete_role": [ + { + "runner": { + "type": "constant", + "times": 100, + "concurrency": 10 + } + } + ] +} \ No newline at end of file diff --git a/samples/tasks/scenarios/keystone/create-and-delete-role.yaml b/samples/tasks/scenarios/keystone/create-and-delete-role.yaml new file mode 100644 index 00000000..2e7d8083 --- /dev/null +++ b/samples/tasks/scenarios/keystone/create-and-delete-role.yaml @@ -0,0 +1,7 @@ +--- + KeystoneBasic.create_and_delete_role: + - + runner: + type: "constant" + times: 100 + concurrency: 10 diff --git a/tests/unit/fakes.py b/tests/unit/fakes.py index 59048b3e..0d77f6f1 100644 --- a/tests/unit/fakes.py +++ b/tests/unit/fakes.py @@ -732,6 +732,9 @@ class FakeRolesManager(FakeManager): role.name = "admin" return [role, ] + def add_user_role(self, user, role, tenant): + pass + class FakeAlarmManager(FakeManager): diff --git a/tests/unit/plugins/openstack/scenarios/keystone/test_basic.py b/tests/unit/plugins/openstack/scenarios/keystone/test_basic.py index cbebc2c1..1d314a26 100644 --- a/tests/unit/plugins/openstack/scenarios/keystone/test_basic.py +++ b/tests/unit/plugins/openstack/scenarios/keystone/test_basic.py @@ -24,6 +24,13 @@ BASIC = BASE + "basic.KeystoneBasic." class KeystoneBasicTestCase(test.TestCase): + @staticmethod + def _get_context(): + return { + "user": {"id": "fake"}, + "tenant": {"id": "fake"} + } + @mock.patch(BASIC + "_generate_random_name") def test_create_user(self, mock_gen_name): scenario = basic.KeystoneBasic() @@ -98,6 +105,53 @@ class KeystoneBasicTestCase(test.TestCase): enabled=True) scenario._list_tenants.assert_called_with() + def test_assign_and_remove_user_role(self): + context = self._get_context() + scenario = basic.KeystoneBasic(context) + fake_tenant = context["tenant"]["id"] + fake_user = context["user"]["id"] + fake_role = mock.MagicMock() + scenario._tenant_create = mock.MagicMock(return_value=fake_tenant) + scenario._user_create = mock.MagicMock(return_value=fake_user) + scenario._role_create = mock.MagicMock(return_value=fake_role) + scenario._role_add = mock.MagicMock() + scenario._role_remove = mock.MagicMock() + scenario.add_and_remove_user_role() + scenario._role_create.assert_called_once_with() + scenario._role_add.assert_called_once_with(fake_user, + fake_role, + fake_tenant) + scenario._role_remove.assert_called_once_with(fake_user, + fake_role, + fake_tenant) + + def test_create_and_delete_role(self): + scenario = basic.KeystoneBasic() + fake_role = mock.MagicMock() + scenario._role_create = mock.MagicMock(return_value=fake_role) + scenario._resource_delete = mock.MagicMock() + scenario.create_and_delete_role() + scenario._role_create.assert_called_once_with() + scenario._resource_delete.assert_called_once_with(fake_role) + + def test_create_and_list_user_roles(self): + context = self._get_context() + scenario = basic.KeystoneBasic(context) + fake_tenant = context["tenant"]["id"] + fake_user = context["user"]["id"] + fake_role = mock.MagicMock() + scenario._tenant_create = mock.MagicMock(return_value=fake_tenant) + scenario._user_create = mock.MagicMock(return_value=fake_user) + scenario._role_create = mock.MagicMock(return_value=fake_role) + scenario._role_add = mock.MagicMock() + scenario._list_roles_for_user = mock.MagicMock() + scenario.create_add_and_list_user_roles() + scenario._role_create.assert_called_once_with() + scenario._role_add.assert_called_once_with(fake_user, + fake_role, fake_tenant) + scenario._list_roles_for_user.assert_called_once_with(fake_user, + fake_tenant) + @mock.patch(BASIC + "_generate_random_name") def test_get_entities(self, mock_gen_name): scenario = basic.KeystoneBasic() diff --git a/tests/unit/plugins/openstack/scenarios/keystone/test_utils.py b/tests/unit/plugins/openstack/scenarios/keystone/test_utils.py index c6ff5b5e..c4ef26b5 100644 --- a/tests/unit/plugins/openstack/scenarios/keystone/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/keystone/test_utils.py @@ -88,6 +88,40 @@ class KeystoneScenarioTestCase(test.TestCase): self._test_atomic_action_timer(scenario.atomic_actions(), "keystone.create_role") + def test_list_roles_for_user(self): + user = mock.MagicMock() + tenant = mock.MagicMock() + fake_keystone = fakes.FakeKeystoneClient() + fake_keystone.roles.roles_for_user = mock.MagicMock() + fake_clients = fakes.FakeClients() + fake_clients._keystone = fake_keystone + scenario = utils.KeystoneScenario(admin_clients=fake_clients) + + scenario._list_roles_for_user(user, tenant) + + fake_keystone.roles.roles_for_user.assert_called_once_with(user, + tenant) + self._test_atomic_action_timer(scenario.atomic_actions(), + "keystone.list_roles") + + def test_role_add(self): + user = mock.MagicMock() + role = mock.MagicMock() + tenant = mock.MagicMock() + fake_keystone = fakes.FakeKeystoneClient() + fake_keystone.roles.add_user_role = mock.MagicMock() + fake_clients = fakes.FakeClients() + fake_clients._keystone = fake_keystone + scenario = utils.KeystoneScenario(admin_clients=fake_clients) + + scenario._role_add(user=user.id, role=role.id, tenant=tenant.id) + + fake_keystone.roles.add_user_role.assert_called_once_with(user.id, + role.id, + tenant.id) + self._test_atomic_action_timer(scenario.atomic_actions(), + "keystone.add_role") + def test_user_delete(self): resource = fakes.FakeResource() resource.delete = mock.MagicMock() @@ -98,6 +132,24 @@ class KeystoneScenarioTestCase(test.TestCase): r = "keystone.delete_%s" % resource.__class__.__name__.lower() self._test_atomic_action_timer(scenario.atomic_actions(), r) + def test_role_remove(self): + user = mock.MagicMock() + role = mock.MagicMock() + tenant = mock.MagicMock() + fake_keystone = fakes.FakeKeystoneClient() + fake_keystone.roles.remove_user_role = mock.MagicMock() + fake_clients = fakes.FakeClients() + fake_clients._keystone = fake_keystone + scenario = utils.KeystoneScenario(admin_clients=fake_clients) + + scenario._role_remove(user=user, role=role, tenant=tenant) + + fake_keystone.roles.remove_user_role.assert_called_once_with(user, + role, + tenant) + self._test_atomic_action_timer(scenario.atomic_actions(), + "keystone.remove_role") + @mock.patch(UTILS + "KeystoneScenario._generate_random_name") def test_tenant_create(self, mock_gen_name): name = "abc"