Improve User context

*) Default value for concurrency should be at least 30.
*) Change templates for names of users and context
*) Store tenant_id in user (it's very usefull in many cases):
role context:
https://review.openstack.org/#/c/87984/4/rally/benchmark/context/role.py
quotas benchmarks:
https://review.openstack.org/#/c/87283/7/rally/benchmark/scenarios/quotas/quotas.py
(where we should setup quotas for passed user)

Change-Id: I00a97cb6ba20f6ee1636e56dc9ad35216ed30144
This commit is contained in:
Boris Pavlovic 2014-04-21 04:47:59 +04:00
parent 6acc580ee1
commit 73781a8325
4 changed files with 74 additions and 27 deletions

View File

@ -404,6 +404,6 @@
# How many concurrent threads use for serving users context # How many concurrent threads use for serving users context
# (integer value) # (integer value)
#concurrent=1 #concurrent=30

View File

@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import uuid
from oslo.config import cfg from oslo.config import cfg
from rally.benchmark.context import base from rally.benchmark.context import base
from rally.benchmark import utils from rally.benchmark import utils
@ -29,10 +27,10 @@ from rally import utils as rutils
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
context_opts = [ context_opts = [
cfg.IntOpt('concurrent', cfg.IntOpt("concurrent",
default=1, default=30,
help='How many concurrent threads use for' help="How many concurrent threads use for serving users "
' serving users context'), "context")
] ]
CONF = cfg.CONF CONF = cfg.CONF
@ -67,8 +65,8 @@ class UserGenerator(base.Context):
}, },
"additionalProperties": False "additionalProperties": False
} }
PATTERN_TENANT = "temp_%(run_id)s_tenant_%(iter)i" PATTERN_TENANT = "ctx_rally_%(task_id)s_tenant_%(iter)i"
PATTERN_USER = "%(tenant_id)s_user_%(uid)d" PATTERN_USER = "ctx_rally_%(tenant_id)s_user_%(uid)d"
def __init__(self, context): def __init__(self, context):
super(UserGenerator, self).__init__(context) super(UserGenerator, self).__init__(context)
@ -94,12 +92,12 @@ class UserGenerator(base.Context):
:returns: tuple (dict tenant, list users) :returns: tuple (dict tenant, list users)
""" """
admin_endpoint, users_num, run_id, i = args admin_endpoint, users_num, task_id, i = args
users = [] users = []
client = osclients.Clients(admin_endpoint).keystone() client = osclients.Clients(admin_endpoint).keystone()
tenant = client.tenants.create( tenant = client.tenants.create(
cls.PATTERN_TENANT % {"run_id": run_id, "iter": i}) cls.PATTERN_TENANT % {"task_id": task_id, "iter": i})
LOG.debug("Creating %d users for tenant %s" % (users_num, tenant.id)) LOG.debug("Creating %d users for tenant %s" % (users_num, tenant.id))
@ -112,7 +110,9 @@ class UserGenerator(base.Context):
"password", tenant.name, "password", tenant.name,
consts.EndpointPermission.USER, consts.EndpointPermission.USER,
client.region_name) client.region_name)
users.append({"id": user.id, "endpoint": user_endpoint}) users.append({"id": user.id,
"endpoint": user_endpoint,
"tenant_id": tenant.id})
return ({"id": tenant.id, "name": tenant.name}, users) return ({"id": tenant.id, "name": tenant.name}, users)
@ -155,9 +155,8 @@ class UserGenerator(base.Context):
"""Create tenants and users, using pool of threads.""" """Create tenants and users, using pool of threads."""
users_num = self.config["users_per_tenant"] users_num = self.config["users_per_tenant"]
run_id = str(uuid.uuid4())
args = [(self.endpoint, users_num, run_id, i) args = [(self.endpoint, users_num, self.task["uuid"], i)
for i in range(self.config["tenants"])] for i in range(self.config["tenants"])]
LOG.debug("Creating %d users using %s threads" % ( LOG.debug("Creating %d users using %s threads" % (

View File

@ -89,19 +89,17 @@ class UserGeneratorTestCase(test.TestCase):
fc = fakes.FakeClients() fc = fakes.FakeClients()
mock_osclients.Clients.return_value = fc mock_osclients.Clients.return_value = fc
with users.UserGenerator(self.context) as generator: with users.UserGenerator(self.context) as ctx:
# Setup (must be called obviously)
self.assertEqual(len(fc.keystone().users.list()), 0) self.assertEqual(len(fc.keystone().users.list()), 0)
self.assertEqual(len(fc.keystone().tenants.list()), 0) self.assertEqual(len(fc.keystone().tenants.list()), 0)
generator.setup() ctx.setup()
self.assertEqual(len(generator.context["users"]), self.assertEqual(len(ctx.context["users"]),
self.users_num) self.users_num)
self.assertEqual(len(fc.keystone().users.list()), self.assertEqual(len(fc.keystone().users.list()),
self.users_num) self.users_num)
self.assertEqual(len(generator.context["tenants"]), self.assertEqual(len(ctx.context["tenants"]),
self.tenants_num) self.tenants_num)
self.assertEqual(len(fc.keystone().tenants.list()), self.assertEqual(len(fc.keystone().tenants.list()),
self.tenants_num) self.tenants_num)
@ -109,3 +107,50 @@ class UserGeneratorTestCase(test.TestCase):
# Cleanup (called by content manager) # Cleanup (called by content manager)
self.assertEqual(len(fc.keystone().users.list()), 0) self.assertEqual(len(fc.keystone().users.list()), 0)
self.assertEqual(len(fc.keystone().tenants.list()), 0) self.assertEqual(len(fc.keystone().tenants.list()), 0)
@mock.patch("rally.benchmark.context.users.osclients")
def test_users_and_tenants_in_context(self, mock_osclients):
fc = fakes.FakeClients()
mock_osclients.Clients.return_value = fc
task = {"uuid": "abcdef"}
config = {
"config": {
"users": {
"tenants": 2,
"users_per_tenant": 2,
"concurrent": 1
}
},
"admin": {"endpoint": mock.MagicMock()},
"task": task
}
with users.UserGenerator(config) as ctx:
ctx.setup()
tenants = []
for i, t in enumerate(fc.keystone().tenants.list()):
pattern = users.UserGenerator.PATTERN_TENANT
tenants.append({
"id": t.id,
"name": pattern % {"task_id": task["uuid"], "iter": i}
})
self.assertEqual(ctx.context["tenants"], tenants)
for user in ctx.context["users"]:
self.assertEqual(set(["id", "endpoint", "tenant_id"]),
set(user.keys()))
tenants_ids = []
for t in tenants:
tenants_ids.extend([t["id"], t["id"]])
users_ids = [user.id for user in fc.keystone().users.list()]
for (user, tenant_id, user_id) in zip(ctx.context["users"],
tenants_ids, users_ids):
self.assertEqual(user["id"], user_id)
self.assertEqual(user["tenant_id"], tenant_id)

View File

@ -90,7 +90,10 @@ class FakeFloatingIP(FakeResource):
class FakeTenant(FakeResource): class FakeTenant(FakeResource):
pass
def __init__(self, manager, name):
super(FakeTenant, self).__init__(manager)
self.name = name
class FakeUser(FakeResource): class FakeUser(FakeResource):
@ -166,6 +169,7 @@ class FakeManager(object):
def __init__(self): def __init__(self):
super(FakeManager, self).__init__() super(FakeManager, self).__init__()
self.cache = {} self.cache = {}
self.resources_order = []
def get(self, resource_uuid): def get(self, resource_uuid):
return self.cache.get(resource_uuid, None) return self.cache.get(resource_uuid, None)
@ -174,17 +178,16 @@ class FakeManager(object):
cached = self.get(resource_uuid) cached = self.get(resource_uuid)
if cached is not None: if cached is not None:
cached.status = "DELETED" cached.status = "DELETED"
del self.cache[cached.uuid] del self.cache[resource_uuid]
self.resources_order.remove(resource_uuid)
def _cache(self, resource): def _cache(self, resource):
self.resources_order.append(resource.uuid)
self.cache[resource.uuid] = resource self.cache[resource.uuid] = resource
return resource return resource
def list(self, **kwargs): def list(self, **kwargs):
resources = [] return [self.cache[key] for key in self.resources_order]
for uuid in self.cache.keys():
resources.append(self.cache[uuid])
return resources
def find(self, **kwargs): def find(self, **kwargs):
for resource in self.cache.values(): for resource in self.cache.values():
@ -271,7 +274,7 @@ class FakeFloatingIPsManager(FakeManager):
class FakeTenantsManager(FakeManager): class FakeTenantsManager(FakeManager):
def create(self, name): def create(self, name):
return self._cache(FakeTenant(self)) return self._cache(FakeTenant(self, name))
class FakeNetworkManager(FakeManager): class FakeNetworkManager(FakeManager):