def setup(self): """Creates custom image(s) with preinstalled applications. When admin is present creates one public image that is usable from all the tenants and users. Otherwise create one image per user and tenant. """ if "admin" in self.context: # NOTE(pboldin): Create by first user and make it public by # the admin user = self.context["users"][0] tenant = self.context["tenants"][user["tenant_id"]] nics = None if "networks" in tenant: nics = [{"net-id": tenant["networks"][0]["id"]}] custom_image = self.create_one_image(user, nics=nics) for tenant in self.context["tenants"].values(): tenant["custom_image"] = custom_image else: def publish(queue): users = self.context.get("users", []) for user, tenant_id in utils.iterate_per_tenants(users): queue.append((user, tenant_id)) def consume(cache, args): user, tenant_id = args tenant = self.context["tenants"][tenant_id] tenant["custom_image"] = self.create_one_image(user) broker.run(publish, consume, self.config["workers"])
def _delete_objects(self, context, threads): """Delete objects created by Swift context and update Rally context. :param context: dict, Rally context environment :param threads: int, number of threads to use for broker pattern """ def publish(queue): for tenant_id in context["tenants"]: containers = context["tenants"][tenant_id]["containers"] for container in containers: for object_name in container["objects"][:]: args = object_name, container queue.append(args) def consume(cache, args): object_name, container = args user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario( {"user": user, "task": context.get("task", {})}) cache[user["id"]]._delete_object(container["container"], object_name) container["objects"].remove(object_name) broker.run(publish, consume, threads)
def _create_containers(self, context, containers_per_tenant, threads): """Create containers and store results in Rally context. :param context: dict, Rally context environment :param containers_per_tenant: int, number of containers to create per tenant :param threads: int, number of threads to use for broker pattern :returns: list of tuples containing (account, container) """ containers = [] def publish(queue): for user, tenant_id in (rutils.iterate_per_tenants( context.get("users", []))): context["tenants"][tenant_id]["containers"] = [] for i in range(containers_per_tenant): args = (user, context["tenants"][tenant_id]["containers"]) queue.append(args) def consume(cache, args): user, tenant_containers = args if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario({"user": user}) container_name = cache[user["id"]]._create_container() tenant_containers.append({"user": user, "container": container_name, "objects": []}) containers.append((user["tenant_id"], container_name)) broker.run(publish, consume, threads) return containers
def _create_tenants(self): threads = self.config["resource_management_workers"] tenants = collections.deque() def publish(queue): for i in range(self.config["tenants"]): args = (self.config["project_domain"], self.task["uuid"], i) queue.append(args) def consume(cache, args): domain, task_id, i = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = keystone.wrap(clients.keystone()) tenant = cache["client"].create_project( self.generate_random_name(), domain) tenant_dict = {"id": tenant.id, "name": tenant.name, "users": []} tenants.append(tenant_dict) # NOTE(msdubov): consume() will fill the tenants list in the closure. broker.run(publish, consume, threads) tenants_dict = {} for t in tenants: tenants_dict[t["id"]] = t return tenants_dict
def setup(self): """Add all roles to users.""" threads = self.workers roles_dict = {} def publish(queue): for context_role in self.config: role = self._get_role_object(context_role) roles_dict[role.id] = role.name LOG.debug("Adding role %(role_name)s having ID %(role_id)s " "to all users using %(threads)s threads" % {"role_name": role.name, "role_id": role.id, "threads": threads}) for user in self.context["users"]: if "roles" not in user: user["roles"] = self._get_user_role_ids( user["id"], user["tenant_id"]) user["assigned_roles"] = [] if role.id not in user["roles"]: args = (role.id, user["id"], user["tenant_id"]) queue.append(args) user["assigned_roles"].append(role.id) broker.run(publish, self._get_consumer("add_role"), threads) self.context["roles"] = roles_dict
def setup(self): """Creates custom image(s) with preinstalled applications. When admin is present creates one public image that is usable from all the tenants and users. Otherwise create one image per user and tenant. """ if "admin" in self.context: # NOTE(pboldin): Create by first user and make it public by # the admin user = self.context["users"][0] tenant = self.context["tenants"][user["tenant_id"]] nics = None if "networks" in tenant: nics = [{"net-id": tenant["networks"][0]["id"]}] custom_image = self.create_one_image(user, nics=nics) self.make_image_public(custom_image) for tenant in self.context["tenants"].values(): tenant["custom_image"] = custom_image else: def publish(queue): users = self.context.get("users", []) for user, tenant_id in utils.iterate_per_tenants(users): queue.append((user, tenant_id)) def consume(cache, args): user, tenant_id = args tenant = self.context["tenants"][tenant_id] tenant["custom_image"] = self.create_one_image(user) broker.run(publish, consume, self.config["workers"])
def _create_containers(self, containers_per_tenant, threads): """Create containers and store results in Rally context. :param containers_per_tenant: int, number of containers to create per tenant :param threads: int, number of threads to use for broker pattern :returns: list of tuples containing (account, container) """ containers = [] def publish(queue): for user, tenant_id in self._iterate_per_tenants(): self.context["tenants"][tenant_id]["containers"] = [] for i in range(containers_per_tenant): args = (user, self.context["tenants"][tenant_id]["containers"]) queue.append(args) def consume(cache, args): user, tenant_containers = args if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario( {"user": user, "task": self.context.get("task", {})}) container_name = cache[user["id"]]._create_container() tenant_containers.append({"user": user, "container": container_name, "objects": []}) containers.append((user["tenant_id"], container_name)) broker.run(publish, consume, threads) return containers
def _create_tenants(self): threads = self.config["resource_management_workers"] tenants = collections.deque() def publish(queue): for i in range(self.config["tenants"]): args = (self.config["project_domain"], self.task["uuid"], i) queue.append(args) def consume(cache, args): domain, task_id, i = args if "client" not in cache: clients = osclients.Clients(self.endpoint) cache["client"] = keystone.wrap(clients.keystone()) tenant = cache["client"].create_project( self.PATTERN_TENANT % { "task_id": task_id, "iter": i }, domain) tenant_dict = {"id": tenant.id, "name": tenant.name} tenants.append(tenant_dict) # NOTE(msdubov): consume() will fill the tenants list in the closure. broker.run(publish, consume, threads) tenants_dict = {} for t in tenants: tenants_dict[t["id"]] = t return tenants_dict
def _create_tenants(self): threads = self.config["resource_management_workers"] tenants = collections.deque() def publish(queue): for i in range(self.config["tenants"]): args = (self.config["project_domain"], self.task["uuid"], i) queue.append(args) def consume(cache, args): domain, task_id, i = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = identity.Identity( clients, name_generator=self.generate_random_name) tenant = cache["client"].create_project(domain_name=domain) tenant_dict = {"id": tenant.id, "name": tenant.name, "users": []} tenants.append(tenant_dict) # NOTE(msdubov): consume() will fill the tenants list in the closure. broker.run(publish, consume, threads) tenants_dict = {} for t in tenants: tenants_dict[t["id"]] = t return tenants_dict
def _delete_objects(self, context, threads): """Delete objects created by Swift context and update Rally context. :param context: dict, Rally context environment :param threads: int, number of threads to use for broker pattern """ def publish(queue): for tenant_id in context["tenants"]: containers = context["tenants"][tenant_id]["containers"] for container in containers: for object_name in container["objects"][:]: args = object_name, container queue.append(args) def consume(cache, args): object_name, container = args user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario({ "user": user, "task": context.get("task", {}) }) cache[user["id"]]._delete_object(container["container"], object_name) container["objects"].remove(object_name) broker.run(publish, consume, threads)
def _delete_tenants(self): threads = self.config["resource_management_workers"] def publish(queue): for tenant_id in self.context["tenants"]: queue.append(tenant_id) broker.run(publish, self._get_consumer_for_deletion("delete_project"), threads) self.context["tenants"] = {}
def _delete_users(self): threads = self.config["resource_management_workers"] def publish(queue): for user in self.context["users"]: queue.append(user["id"]) broker.run(publish, self._get_consumer_for_deletion("delete_user"), threads) self.context["users"] = []
def _create_users(self): # NOTE(msdubov): This should be called after _create_tenants(). threads = self.config["resource_management_workers"] users_per_tenant = self.config["users_per_tenant"] default_role = cfg.CONF.openstack.keystone_default_role users = collections.deque() def publish(queue): for tenant_id in self.context["tenants"]: for user_id in range(users_per_tenant): username = self.generate_random_name() password = (str(uuid.uuid4()) if self.config.get("user_password") is None else self.config["user_password"]) args = (username, password, self.config["project_domain"], self.config["user_domain"], tenant_id) queue.append(args) def consume(cache, args): username, password, project_dom, user_dom, tenant_id = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = identity.Identity( clients, name_generator=self.generate_random_name) client = cache["client"] user = client.create_user(username, password=password, project_id=tenant_id, domain_name=user_dom, default_role=default_role) user_credential = credential.OpenStackCredential( auth_url=self.credential["auth_url"], username=user.name, password=password, tenant_name=self.context["tenants"][tenant_id]["name"], permission=consts.EndpointPermission.USER, project_domain_name=project_dom, user_domain_name=user_dom, endpoint_type=self.credential["endpoint_type"], https_insecure=self.credential["https_insecure"], https_cacert=self.credential["https_cacert"], region_name=self.credential["region_name"], profiler_hmac_key=self.credential["profiler_hmac_key"], profiler_conn_str=self.credential["profiler_conn_str"], api_info=self.credential["api_info"]) users.append({ "id": user.id, "credential": user_credential, "tenant_id": tenant_id }) # NOTE(msdubov): consume() will fill the users list in the closure. broker.run(publish, consume, threads) return list(users)
def _delete_envs(self): threads = self.config["resource_management_workers"] def publish(queue): queue.extend(self.context["fuel"]["environments"]) def consume(cache, env_id): self.fscenario._delete_environment(env_id) broker.run(publish, consume, threads) self.context["fuel"] = {}
def cleanup(self): """Remove all roles from users.""" threads = self.workers def publish(queue): for role_id in self.context["roles"]: LOG.debug("Removing role %s from all users" % (role_id)) for user in self.context["users"]: args = (role_id, user["id"], user["tenant_id"]) queue.append(args) broker.run(publish, self._get_consumer("remove_role"), threads)
def cleanup(self): """Remove all roles from users.""" threads = self.workers def publish(queue): for role_id in self.context["roles"]: LOG.debug("Removing role %s from all users", role_id) for user in self.context["users"]: args = (role_id, user["id"], user["tenant_id"]) queue.append(args) broker.run(publish, self._get_consumer("revoke_role"), threads)
def _create_users(self): # NOTE(msdubov): This should be called after _create_tenants(). threads = self.config["resource_management_workers"] users_per_tenant = self.config["users_per_tenant"] default_role = cfg.CONF.users_context.keystone_default_role users = collections.deque() def publish(queue): for tenant_id in self.context["tenants"]: for user_id in range(users_per_tenant): username = self.generate_random_name() password = str(uuid.uuid4()) args = (username, password, self.config["project_domain"], self.config["user_domain"], tenant_id) queue.append(args) def consume(cache, args): username, password, project_dom, user_dom, tenant_id = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = identity.Identity( clients, name_generator=self.generate_random_name) client = cache["client"] user = client.create_user(username, password=password, email="*****@*****.**" % username, project_id=tenant_id, domain_name=user_dom, default_role=default_role) user_credential = objects.Credential( self.credential.auth_url, user.name, password, self.context["tenants"][tenant_id]["name"], consts.EndpointPermission.USER, self.credential.region_name, project_domain_name=project_dom, user_domain_name=user_dom, endpoint_type=self.credential.endpoint_type, https_insecure=self.credential.insecure, https_cacert=self.credential.cacert) users.append({ "id": user.id, "credential": user_credential, "tenant_id": tenant_id }) # NOTE(msdubov): consume() will fill the users list in the closure. broker.run(publish, consume, threads) return list(users)
def test_run(self): def publish(queue): queue.append(1) queue.append(2) queue.append(3) consumed = set() def consume(cache, item): consumed.add(item) consumer_count = 2 broker.run(publish, consume, consumer_count) self.assertEqual(set([1, 2, 3]), consumed)
def _create_users(self): # NOTE(msdubov): This should be called after _create_tenants(). threads = self.config["resource_management_workers"] users_per_tenant = self.config["users_per_tenant"] default_role = cfg.CONF.openstack.keystone_default_role users = collections.deque() def publish(queue): for tenant_id in self.context["tenants"]: for user_id in range(users_per_tenant): username = self.generate_random_name() password = str(uuid.uuid4()) args = (username, password, self.config["project_domain"], self.config["user_domain"], tenant_id) queue.append(args) def consume(cache, args): username, password, project_dom, user_dom, tenant_id = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = identity.Identity( clients, name_generator=self.generate_random_name) client = cache["client"] user = client.create_user(username, password=password, project_id=tenant_id, domain_name=user_dom, default_role=default_role) user_credential = credential.OpenStackCredential( auth_url=self.credential["auth_url"], username=user.name, password=password, tenant_name=self.context["tenants"][tenant_id]["name"], permission=consts.EndpointPermission.USER, project_domain_name=project_dom, user_domain_name=user_dom, endpoint_type=self.credential["endpoint_type"], https_insecure=self.credential["https_insecure"], https_cacert=self.credential["https_cacert"], region_name=self.credential["region_name"], profiler_hmac_key=self.credential["profiler_hmac_key"], profiler_conn_str=self.credential["profiler_conn_str"]) users.append({"id": user.id, "credential": user_credential, "tenant_id": tenant_id}) # NOTE(msdubov): consume() will fill the users list in the closure. broker.run(publish, consume, threads) return list(users)
def _create_users(self): # NOTE(msdubov): This should be called after _create_tenants(). threads = self.config["resource_management_workers"] users_per_tenant = self.config["users_per_tenant"] users = collections.deque() def publish(queue): for tenant_id in self.context["tenants"]: for user_id in range(users_per_tenant): username = self.PATTERN_USER % { "tenant_id": tenant_id, "uid": user_id } password = str(uuid.uuid4()) args = (username, password, self.config["project_domain"], self.config["user_domain"], tenant_id) queue.append(args) def consume(cache, args): username, password, project_dom, user_dom, tenant_id = args if "client" not in cache: clients = osclients.Clients(self.endpoint) cache["client"] = keystone.wrap(clients.keystone()) client = cache["client"] user = client.create_user(username, password, "*****@*****.**" % username, tenant_id, user_dom) user_endpoint = objects.Endpoint( client.auth_url, user.name, password, self.context["tenants"][tenant_id]["name"], consts.EndpointPermission.USER, client.region_name, project_domain_name=project_dom, user_domain_name=user_dom, endpoint_type=self.endpoint.endpoint_type, https_insecure=self.endpoint.insecure, https_cacert=self.endpoint.cacert) users.append({ "id": user.id, "endpoint": user_endpoint, "tenant_id": tenant_id }) # NOTE(msdubov): consume() will fill the users list in the closure. broker.run(publish, consume, threads) return list(users)
def _delete_users(self): threads = self.config["resource_management_workers"] def publish(queue): for user in self.context["users"]: queue.append(user["id"]) def consume(cache, user_id): if "client" not in cache: clients = osclients.Clients(self.endpoint) cache["client"] = keystone.wrap(clients.keystone()) cache["client"].delete_user(user_id) broker.run(publish, consume, threads) self.context["users"] = []
def _delete_tenants(self): threads = self.config["resource_management_workers"] self._remove_associated_networks() def publish(queue): for tenant_id in self.context["tenants"]: queue.append(tenant_id) def consume(cache, tenant_id): if "client" not in cache: clients = osclients.Clients(self.endpoint) cache["client"] = keystone.wrap(clients.keystone()) cache["client"].delete_project(tenant_id) broker.run(publish, consume, threads) self.context["tenants"] = {}
def _create_objects(self, context, objects_per_container, object_size, threads): """Create objects and store results in Rally context. :param context: dict, Rally context environment :param objects_per_container: int, number of objects to create per container :param object_size: int, size of created swift objects in byte :param threads: int, number of threads to use for broker pattern :returns: list of tuples containing (account, container, object) """ objects = [] with tempfile.TemporaryFile() as dummy_file: # set dummy file to specified object size dummy_file.truncate(object_size) def publish(queue): for tenant_id in context["tenants"]: containers = context["tenants"][tenant_id]["containers"] for container in containers: for i in range(objects_per_container): queue.append(container) def consume(cache, container): user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario({ "user": user, "task": context.get("task", {}) }) dummy_file.seek(0) object_name = cache[user["id"]]._upload_object( container["container"], dummy_file)[1] container["objects"].append(object_name) objects.append( (user["tenant_id"], container["container"], object_name)) broker.run(publish, consume, threads) return objects
def _create_users(self): # NOTE(msdubov): This should be called after _create_tenants(). threads = self.config["resource_management_workers"] users_per_tenant = self.config["users_per_tenant"] default_role = cfg.CONF.users_context.keystone_default_role users = collections.deque() def publish(queue): for tenant_id in self.context["tenants"]: for user_id in range(users_per_tenant): username = self.generate_random_name() password = str(uuid.uuid4()) args = (username, password, self.config["project_domain"], self.config["user_domain"], tenant_id) queue.append(args) def consume(cache, args): username, password, project_dom, user_dom, tenant_id = args if "client" not in cache: clients = osclients.Clients(self.credential) cache["client"] = keystone.wrap(clients.keystone()) client = cache["client"] user = client.create_user( username, password, "*****@*****.**" % username, tenant_id, user_dom, default_role=default_role) user_credential = objects.Credential( client.auth_url, user.name, password, self.context["tenants"][tenant_id]["name"], consts.EndpointPermission.USER, client.region_name, project_domain_name=project_dom, user_domain_name=user_dom, endpoint_type=self.credential.endpoint_type, https_insecure=self.credential.insecure, https_cacert=self.credential.cacert) users.append({"id": user.id, "credential": user_credential, "tenant_id": tenant_id}) # NOTE(msdubov): consume() will fill the users list in the closure. broker.run(publish, consume, threads) return list(users)
def _create_objects(self, context, objects_per_container, object_size, threads): """Create objects and store results in Rally context. :param context: dict, Rally context environment :param objects_per_container: int, number of objects to create per container :param object_size: int, size of created swift objects in byte :param threads: int, number of threads to use for broker pattern :returns: list of tuples containing (account, container, object) """ objects = [] with tempfile.TemporaryFile() as dummy_file: # set dummy file to specified object size dummy_file.truncate(object_size) def publish(queue): for tenant_id in context["tenants"]: containers = context["tenants"][tenant_id]["containers"] for container in containers: for i in range(objects_per_container): queue.append(container) def consume(cache, container): user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario( {"user": user}) dummy_file.seek(0) object_name = cache[user["id"]]._upload_object( container["container"], dummy_file)[1] container["objects"].append(object_name) objects.append((user["tenant_id"], container["container"], object_name)) broker.run(publish, consume, threads) return objects
def _create_envs(self): threads = self.config["resource_management_workers"] envs = collections.deque() def publish(queue): kwargs = {"release_id": self.config["release_id"], "network_provider": self.config["network_provider"], "deployment_mode": self.config["deployment_mode"], "net_segment_type": self.config["net_segment_type"]} for i in range(self.config["environments"]): queue.append(kwargs) def consume(cache, kwargs): env_id = self.fscenario._create_environment(**kwargs) envs.append(env_id) broker.run(publish, consume, threads) return list(envs)
def _delete_containers(self, context, threads): """Delete containers created by Swift context and update Rally context. :param context: dict, Rally context environment :param threads: int, number of threads to use for broker pattern """ def publish(queue): for tenant_id in context["tenants"]: containers = context["tenants"][tenant_id]["containers"] for container in containers[:]: args = container, containers queue.append(args) def consume(cache, args): container, tenant_containers = args user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario({"user": user}) cache[user["id"]]._delete_container(container["container"]) tenant_containers.remove(container) broker.run(publish, consume, threads)
def _delete_containers(self, threads): """Delete containers created by Swift context and update Rally context. :param threads: int, number of threads to use for broker pattern """ def publish(queue): for tenant_id in self.context["tenants"]: containers = self.context["tenants"][tenant_id]["containers"] for container in containers[:]: args = container, containers queue.append(args) def consume(cache, args): container, tenant_containers = args user = container["user"] if user["id"] not in cache: cache[user["id"]] = swift_utils.SwiftScenario( {"user": user, "task": self.context.get("task", {})}) cache[user["id"]]._delete_container(container["container"]) tenant_containers.remove(container) broker.run(publish, consume, threads)
def cleanup(self): """Delete created custom image(s).""" if "admin" in self.context: user = self.context["users"][0] tenant = self.context["tenants"][user["tenant_id"]] if "custom_image" in tenant: self.delete_one_image(user, tenant["custom_image"]) tenant.pop("custom_image") else: def publish(queue): users = self.context.get("users", []) for user, tenant_id in utils.iterate_per_tenants(users): queue.append((user, tenant_id)) def consume(cache, args): user, tenant_id = args tenant = self.context["tenants"][tenant_id] if "custom_image" in tenant: self.delete_one_image(user, tenant["custom_image"]) tenant.pop("custom_image") broker.run(publish, consume, self.config["workers"])
def exterminate(self): """Delete all resources for passed users, admin and resource_mgr.""" broker.run(self._gen_publisher(), self._gen_consumer(), consumers_count=self.manager_cls._threads)
def test_task_samples_are_valid(self): from rally_openstack.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") admin_cred = deployment.get_credentials_for("openstack")["admin"] ctx = { "env": { "platforms": { "openstack": { "admin": admin_cred.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(six.text_type(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_task_samples_are_valid(self): 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") admin_cred = deployment.get_credentials_for("openstack")["admin"] ctx = { "env": { "platforms": { "openstack": { "admin": admin_cred.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) # NOTE(andreykurilin): mock building credential to share one cache of # clients(it will allow to avoid hundreds of redundant # authentications) between validations of different samples deployment = rapi.deployment._get("MAIN") original_get_credentials_for = deployment.get_credentials_for creds_cache = {} def get_credentials_for(platform): if platform not in creds_cache: creds_cache[platform] = original_get_credentials_for( platform) return creds_cache[platform] deployment.get_credentials_for = get_credentials_for deployment_patcher = mock.patch("rally.api.objects.Deployment.get") m_deployment = deployment_patcher.start() m_deployment.return_value = deployment self.addCleanup(deployment_patcher.stop) # 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_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(six.text_type(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_task_samples_are_valid(self): rally = utils.Rally(force_new_db=True) # In TestTaskSamples, Rally API will be called directly (not via # subprocess), so we need to change database options to temp database. db.db_options.set_defaults(db.CONF, connection="sqlite:///%s/db" % rally.tmp_dir) # let's use pre-created users to make TestTaskSamples quicker rapi = api.API(config_file=rally.config_filename) deployment = rapi.deployment._get("MAIN") admin_cred = deployment.get_credentials_for("openstack")["admin"] ctx = { "admin": { "credential": admin_cred }, "task": { "uuid": self.__class__.__name__ } } user_ctx = users.UserGenerator(ctx) user_ctx.setup() self.addCleanup(user_ctx.cleanup) config = deployment["config"] os_creds = config["creds"]["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 config["creds"]["openstack"]["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(config)) rally("deployment create --name MAIN --filename %s" % deployment_cfg, write_report=False) # NOTE(andreykurilin): mock building credential to share one cache of # clients(it will allow to avoid hundreds of redundant # authentications) between validations of different samples deployment = rapi.deployment._get("MAIN") original_get_credentials_for = deployment.get_credentials_for creds_cache = {} def get_credentials_for(namespace): if namespace not in creds_cache: creds_cache[namespace] = original_get_credentials_for( namespace) return creds_cache[namespace] deployment.get_credentials_for = get_credentials_for deployment_patcher = mock.patch("rally.api.objects.Deployment.get") m_deployment = deployment_patcher.start() m_deployment.return_value = deployment self.addCleanup(deployment_patcher.stop) # 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_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(six.text_type(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() ]))