def install_extension(self, source, version=None, extra_settings=None): """Install a Tempest plugin.""" if extra_settings: raise NotImplementedError( "'%s' verifiers don't support extra installation settings " "for extensions." % self.get_name()) version = version or "master" egg = re.sub("\.git$", "", os.path.basename(source.strip("/"))) full_source = "git+{0}@{1}#egg={2}".format(source, version, egg) # NOTE(ylobankov): Use 'develop mode' installation to provide an # ability to advanced users to change tests or # develop new ones in verifier repo on the fly. cmd = ["pip", "install", "--src", os.path.join(self.base_dir, "extensions"), "-e", full_source] if self.verifier.system_wide: cmd.insert(2, "--no-deps") utils.check_output(cmd, cwd=self.base_dir, env=self.environ) # Very often Tempest plugins are inside projects and requirements # for plugins are listed in the test-requirements.txt file. test_reqs_path = os.path.join(self.base_dir, "extensions", egg, "test-requirements.txt") if os.path.exists(test_reqs_path): if not self.verifier.system_wide: utils.check_output(["pip", "install", "-r", test_reqs_path], cwd=self.base_dir, env=self.environ) else: self.check_system_wide(reqs_file_path=test_reqs_path)
def checkout(self, version): """Switch a verifier repo.""" LOG.info("Switching verifier repo to the '%s' version." % version) utils.check_output(["git", "checkout", "master"], cwd=self.repo_dir) utils.check_output(["git", "remote", "update"], cwd=self.repo_dir) utils.check_output(["git", "pull"], cwd=self.repo_dir) utils.check_output(["git", "checkout", version], cwd=self.repo_dir)
def _init_testr(self): """Initialize testr.""" test_repository_dir = os.path.join(self.base_dir, ".testrepository") # NOTE(andreykurilin): Is there any possibility that .testrepository # presents in clear repo?! if not os.path.isdir(test_repository_dir): LOG.debug("Initializing testr.") try: utils.check_output(["testr", "init"], cwd=self.repo_dir, env=self.environ) except (subprocess.CalledProcessError, OSError): if os.path.exists(test_repository_dir): shutil.rmtree(test_repository_dir) raise exceptions.RallyException("Failed to initialize testr.")
def list_tests(self, pattern=""): """List all tests.""" output = utils.check_output(["testr", "list-tests", pattern], cwd=self.repo_dir, env=self.environ, debug_output=False) return [t for t in output.split("\n") if TEST_NAME_RE.match(t)]
def list_tests(self, pattern=""): """List all tests.""" if self._use_testr: cmd = ["testr", "list-tests", pattern] else: cmd = ["stestr", "list", pattern] output = utils.check_output(cmd, cwd=self.repo_dir, env=self.environ, debug_output=False) return [t for t in output.split("\n") if TEST_NAME_RE.match(t)]
def install_venv(self): """Install a virtual environment for a verifier.""" if os.path.exists(self.venv_dir): # NOTE(andreykurilin): It is necessary to remove the old env while # performing update action. LOG.info("Deleting old virtual environment.") shutil.rmtree(self.venv_dir) LOG.info("Creating virtual environment. It may take a few minutes.") LOG.debug("Initializing virtual environment in %s directory." % self.venv_dir) utils.check_output(["virtualenv", "-p", sys.executable, self.venv_dir], cwd=self.repo_dir, msg_on_err="Failed to initialize virtual env " "in %s directory." % self.venv_dir) LOG.debug("Installing verifier in virtual environment.") # NOTE(ylobankov): Use 'develop mode' installation to provide an # ability to advanced users to change tests or # develop new ones in verifier repo on the fly. utils.check_output(["pip", "install", "-e", "./"], cwd=self.repo_dir, env=self.environ)
def test_check_output(self, mock_check_output, mock_log, mock_encodeutils): self.assertEqual(mock_check_output.return_value, utils.check_output()) self.assertFalse(mock_log.error.called) mock_check_output.side_effect = subprocess.CalledProcessError(1, None) self.assertRaises(subprocess.CalledProcessError, utils.check_output) self.assertEqual(2, mock_log.error.call_count) mock_log.error.reset_mock() msg = "bla bla bla" self.assertRaises(subprocess.CalledProcessError, utils.check_output, msg_on_err=msg) self.assertEqual(3, mock_log.error.call_count) mock_log.error.assert_any_call(msg)
def list_extensions(self): """List all installed Tempest plugins.""" # TODO(andreykurilin): find a better way to list tempest plugins cmd = ("from tempest.test_discover import plugins; " "plugins_manager = plugins.TempestTestPluginManager(); " "plugins_map = plugins_manager.get_plugin_load_tests_tuple(); " "plugins_list = [" " {'name': p.name, " " 'entry_point': p.entry_point_target, " " 'location': plugins_map[p.name][1]} " " for p in plugins_manager.ext_plugins.extensions]; " "print(plugins_list)") try: output = utils.check_output(["python", "-c", cmd], cwd=self.base_dir, env=self.environ, debug_output=False).strip() except subprocess.CalledProcessError: raise exceptions.RallyException( "Cannot list installed Tempest plugins for verifier %s." % self.verifier) return yaml.safe_load(output)
def _clone(self): """Clone a repo and switch to a certain version.""" source = self.verifier.source or self._meta_get("default_repo") if not source or ( not URL_RE.match(source) and not os.path.exists(source)): raise exceptions.RallyException("Source path '%s' is not valid." % source) if logging.is_debug(): LOG.debug("Cloning verifier repo from %s into %s." % (source, self.repo_dir)) else: LOG.info("Cloning verifier repo from %s." % source) cmd = ["git", "clone", source, self.repo_dir] default_version = self._meta_get("default_version") if default_version and default_version != "master": cmd.extend(["-b", default_version]) utils.check_output(cmd) version = self.verifier.version if version: LOG.info("Switching verifier repo to the '%s' version." % version) utils.check_output(["git", "checkout", version], cwd=self.repo_dir) else: output = utils.check_output(["git", "describe", "--all"], cwd=self.repo_dir).strip() if output.startswith("heads/"): # it is a branch version = output[6:] else: head = utils.check_output(["git", "rev-parse", "HEAD"], cwd=self.repo_dir).strip() if output.endswith(head[:7]): # it is a commit ID version = head else: # it is a tag version = output self.verifier.update_properties(version=version)