From 782baf7a555fb1e6822248dc0be611605a51b8fa Mon Sep 17 00:00:00 2001 From: Andrey Kurilin Date: Tue, 28 Aug 2018 18:30:31 +0300 Subject: [PATCH] Add functional tests for env check * add new tests for `env check` command which interacts with existing@openstack platfrom * merge ``RallyWithSpecifiedDeployment`` class to the tests.functional.utils.Rally . Change-Id: I57ea3cbe8b8b3a1398ea0a2d27d26ae2510b59ec --- tests/functional/test_certification_task.py | 2 +- tests/functional/test_cli_env.py | 123 ++++++++++++++++++++ tests/functional/test_task_samples.py | 2 +- tests/functional/utils.py | 55 ++++----- 4 files changed, 153 insertions(+), 29 deletions(-) create mode 100644 tests/functional/test_cli_env.py diff --git a/tests/functional/test_certification_task.py b/tests/functional/test_certification_task.py index b46ea85d..0f83bdf6 100644 --- a/tests/functional/test_certification_task.py +++ b/tests/functional/test_certification_task.py @@ -26,7 +26,7 @@ class TestPreCreatedTasks(unittest.TestCase): def test_task_samples_is_valid(self): - rally = utils.RallyWithSpecifiedDeployment() + rally = utils.Rally() full_path = os.path.join( os.path.dirname(rally_openstack.__file__), os.pardir, "tasks", "openstack") diff --git a/tests/functional/test_cli_env.py b/tests/functional/test_cli_env.py new file mode 100644 index 00000000..083aa11a --- /dev/null +++ b/tests/functional/test_cli_env.py @@ -0,0 +1,123 @@ +# Copyright 2013: Mirantis Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import copy +import unittest + +from tests.functional import utils + + +TEST_ENV = { + "OS_USERNAME": "admin", + "OS_PASSWORD": "admin", + "OS_TENANT_NAME": "admin", + "OS_AUTH_URL": "http://fake/", +} + +RALLY_OPTS = { + # speed up failures + "DEFAULT": {"openstack_client_http_timeout": 5} +} + + +class EnvTestCase(unittest.TestCase): + def test_check_success(self): + rally = utils.Rally() + rally("env check") + + def test_check_wrong_url(self): + rally = utils.Rally(config_opts=RALLY_OPTS) + fake_spec = copy.deepcopy(rally.env_spec) + fake_spec["existing@openstack"]["auth_url"] = "http://example.com:5000" + spec = utils.JsonTempFile(fake_spec) + rally("env create --name t_create_env --spec %s" % spec.filename) + + try: + rally("env check") + except utils.RallyCliError as e: + output = e.output.split("\n") + line_template = "| :-( | openstack | %s |" + err1 = "Unable to establish connection to http://example.com:5000" + err2 = "Request to http://example.com:5000 timed out" + if (line_template % err1 not in output + and line_template % err2 not in output): + self.fail("The output of `env check` doesn't contain expected" + " error. Output:\n" % e.output) + else: + self.fail("Check env command should fail!") + + def test_check_wrong_username(self): + rally = utils.Rally(config_opts=RALLY_OPTS) + fake_spec = copy.deepcopy(rally.env_spec) + fake_spec["existing@openstack"]["admin"]["username"] = "MASTER777" + spec = utils.JsonTempFile(fake_spec) + rally("env create --name t_create_env --spec %s" % spec.filename) + + try: + rally("env check") + except utils.RallyCliError as e: + line = ("| :-( | openstack | Failed to authenticate to " + "%s for user '%s' in project '%s': The request you have " + "made requires authentication. |" % + (fake_spec["existing@openstack"]["auth_url"], + fake_spec["existing@openstack"]["admin"]["username"], + fake_spec["existing@openstack"]["admin"]["project_name"])) + self.assertIn(line, e.output.split("\n")) + else: + self.fail("Check env command should fail!") + + def test_check_wrong_password(self): + rally = utils.Rally(config_opts=RALLY_OPTS) + fake_spec = copy.deepcopy(rally.env_spec) + fake_spec["existing@openstack"]["admin"]["password"] = "MASTER777" + spec = utils.JsonTempFile(fake_spec) + rally("env create --name t_create_env --spec %s" % spec.filename) + + try: + rally("env check") + except utils.RallyCliError as e: + line = ("| :-( | openstack | Failed to authenticate to " + "%s for user '%s' in project '%s': The request you have " + "made requires authentication. |" % + (fake_spec["existing@openstack"]["auth_url"], + fake_spec["existing@openstack"]["admin"]["username"], + fake_spec["existing@openstack"]["admin"]["project_name"])) + self.assertIn(line, e.output.split("\n")) + else: + self.fail("Check env command should fail!") + + def test_create_from_sysenv(self): + rally = utils.Rally() + rally.env.update(TEST_ENV) + rally("env create --name t_create_env --from-sysenv") + config = rally("env show --only-spec", getjson=True) + self.assertIn("existing@openstack", config) + self.assertEqual(TEST_ENV["OS_USERNAME"], + config["existing@openstack"]["admin"]["username"]) + self.assertEqual(TEST_ENV["OS_PASSWORD"], + config["existing@openstack"]["admin"]["password"]) + if "project_name" in config["existing@openstack"]["admin"]: + # keystone v3 + self.assertEqual( + TEST_ENV["OS_TENANT_NAME"], + config["existing@openstack"]["admin"]["project_name"]) + else: + # keystone v2 + self.assertEqual( + TEST_ENV["OS_TENANT_NAME"], + config["existing@openstack"]["admin"]["tenant_name"]) + self.assertEqual( + TEST_ENV["OS_AUTH_URL"], + config["existing@openstack"]["auth_url"]) diff --git a/tests/functional/test_task_samples.py b/tests/functional/test_task_samples.py index 785986cb..d6c64429 100644 --- a/tests/functional/test_task_samples.py +++ b/tests/functional/test_task_samples.py @@ -56,7 +56,7 @@ class TestTaskSamples(unittest.TestCase): @plugins.ensure_plugins_are_loaded def test_task_samples_are_valid(self): from rally_openstack.contexts.keystone import users - rally = utils.RallyWithSpecifiedDeployment(force_new_db=True) + 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") diff --git a/tests/functional/utils.py b/tests/functional/utils.py index 246825d5..cfeec677 100644 --- a/tests/functional/utils.py +++ b/tests/functional/utils.py @@ -70,9 +70,17 @@ class Rally(object): output = rally("deployment list") """ - _DEPLOYMENT_CREATE_ARGS = "" - def __init__(self, force_new_db=False, plugin_path=None): + ENV_FILE = "/tmp/rally_functests_main_env.json" + + def __init__(self, force_new_db=False, plugin_path=None, config_opts=None): + if not os.path.exists(self.ENV_FILE): + subprocess.call(["rally", "--log-file", "/dev/null", + "env", "show", "--only-spec"], + stdout=open(self.ENV_FILE, "w")) + with open(self.ENV_FILE) as f: + self.env_spec = json.loads(f.read()) + print(self.env_spec) # NOTE(sskripnick): we should change home dir to avoid races # and do not touch any user files in ~/.rally @@ -80,6 +88,7 @@ class Rally(object): self.env = copy.deepcopy(os.environ) self.env["HOME"] = self.tmp_dir self.config_filename = None + self.config_opts = copy.deepcopy(config_opts) if config_opts else {} self.method_name = None self.class_name = None @@ -96,27 +105,33 @@ class Rally(object): self.class_name = test_object.__class__.__name__ if force_new_db or ("RCI_KEEP_DB" not in os.environ): - config_filename = os.path.join(self.tmp_dir, "conf") + self.config_opts.setdefault("database", {}) + conn = "sqlite:///%s/db" % self.tmp_dir + self.config_opts["database"]["connection"] = conn + + if self.config_opts: + self.config_filename = os.path.join(self.tmp_dir, "conf") config = configparser.RawConfigParser() - config.add_section("database") - config.set("database", "connection", - "sqlite:///%s/db" % self.tmp_dir) - with open(config_filename, "w") as conf: + for section, opts in self.config_opts.items(): + if section.lower() != "default": + config.add_section(section) + for opt_name, opt_value in opts.items(): + config.set(section, opt_name, opt_value) + + with open(self.config_filename, "w") as conf: config.write(conf) - self.args = ["rally", "--config-file", config_filename] - subprocess.call(["rally", "--config-file", config_filename, - "db", "recreate"], env=self.env) - self.config_filename = config_filename + self.args = ["rally", "--config-file", self.config_filename] else: self.args = ["rally"] - subprocess.call(["rally", "db", "recreate"], env=self.env) + + subprocess.call(self.args + ["db", "recreate"], env=self.env) if plugin_path: self.args.extend(["--plugin-paths", os.path.abspath(plugin_path)]) self.reports_root = os.environ.get("REPORTS_ROOT", "rally-cli-output-files") self._created_files = [] - self("deployment create --name MAIN%s" % self._DEPLOYMENT_CREATE_ARGS, + self("env create --name MAIN --spec %s" % self.ENV_FILE, write_report=False) def __del__(self): @@ -215,20 +230,6 @@ class Rally(object): rep.write("%s\n" % output) -class RallyWithSpecifiedDeployment(Rally): - - DEPLOYMENT_FILE = "/tmp/rally_functests_main_deployment.json" - - def __init__(self, force_new_db=False): - self._DEPLOYMENT_CREATE_ARGS = " --file %s" % self.DEPLOYMENT_FILE - if not os.path.exists(self.DEPLOYMENT_FILE): - subprocess.call(["rally", "--log-file", "/dev/null", - "deployment", "config"], - stdout=open(self.DEPLOYMENT_FILE, "w")) - super(RallyWithSpecifiedDeployment, self).__init__( - force_new_db=force_new_db) - - def get_global(global_key, env): home_dir = env.get("HOME") with open("%s/.rally/globals" % home_dir) as f: