예제 #1
0
def test_command_completion(shell: str) -> None:
    env = os.environ.copy()
    env["_MOLECULE_COMPLETE"] = f"{shell}_source"

    if "bash" in shell:
        bash_version = util.run_command(["bash", "--version"]).stdout.split()[3][0:3]

    result = util.run_command(["molecule"], env=env)

    if "bash" in shell and (float(bash_version) < 4.4):
        assert result.returncode == 1
        assert "Found config file" not in result.stdout
    else:
        assert result.returncode == 0
        assert "Found config file" not in result.stdout
예제 #2
0
    def execute(self):
        if not self.enabled:
            msg = 'Skipping, dependency is disabled.'
            LOG.warn(msg)
            return

        if self._sh_command is None:
            self.bake()

        try:
            util.run_command(self._sh_command, debug=self._config.debug)
            msg = 'Dependency completed successfully.'
            LOG.success(msg)
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #3
0
def test_molecule_init_scenario():
    """Verify that init role works."""
    cmd = ['molecule', 'init', 'scenario', 'default', '--driver-name', 'virtup']
    runner = CliRunner()
    with runner.isolated_filesystem():
        result = run_command(cmd)
        assert result.returncode == 0
예제 #4
0
def list_with_format_plain(x):
    cmd = ["molecule", "list", "--format", "plain"]
    result = util.run_command(cmd)
    out = util.strip_ansi_color(result.stdout)

    for l in x.splitlines():
        assert l in out
예제 #5
0
    def execute(self):
        """
        Execute the actions necessary to perform a `molecule lint` and \
        returns None.

        :return: None
        """
        self.print_info()

        # v3 migration code:
        cmd = self._config.lint
        if not cmd:
            LOG.info("Lint is disabled.")
            return

        if cmd == "yamllint":
            msg = (
                "Deprecated linter config found, migrate to v3 schema. "
                "See https://github.com/ansible-community/molecule/issues/2293"
            )
            util.sysexit_with_message(msg)

        result = util.run_command(cmd, env=self.env, echo=True)
        if result.returncode != 0:
            util.sysexit_with_message(
                "Lint failed with error code %s" % result.returncode
            )
예제 #6
0
def test_command_completion(shell: str) -> None:
    env = os.environ.copy()
    env["_MOLECULE_COMPLETE"] = f"{shell}_source"

    result = util.run_command(["molecule"], env=env)
    assert result.returncode == 0
    assert "Found config file" not in result.stdout
예제 #7
0
    def execute(self):
        """
        Execute ``ansible-playbook`` and returns a string.

        :return: str
        """
        if self._ansible_command is None:
            self.bake()

        if not self._playbook:
            LOG.warning("Skipping, %s action has no playbook.",
                        self._config.action)
            return

        with warnings.catch_warnings(record=True) as warns:
            warnings.filterwarnings("default", category=MoleculeRuntimeWarning)
            self._config.driver.sanity_checks()
            result = util.run_command(self._ansible_command,
                                      debug=self._config.debug)

        if result.returncode != 0:
            util.sysexit_with_message(
                f"Ansible return code was {result.returncode}, command was: {result.args}",
                result.returncode,
                warns=warns,
            )

        return result.stdout
예제 #8
0
    def _testinfra(self,
                   tests,
                   debug=False,
                   ansible_env={},
                   out=LOG.info,
                   err=LOG.error,
                   **kwargs):
        """
        Executes testinfra against specified tests and returns a :func:`sh`
        response object.

        :param tests: A list of testinfra tests.
        :param debug: An optional bool to toggle debug output.
        :param pattern: A string containing the pattern of files to lint.
        :param ansible_env: An optional environment to pass to underlying
         :func:`sh` call.
        :param out: An optional function to process STDOUT for underlying
         :func:`sh` call.
        :param err: An optional function to process STDERR for underlying
         :func:`sh` call.
        :return: :func:`sh` response object.
        """
        kwargs['debug'] = debug
        kwargs['_env'] = ansible_env
        kwargs['_out'] = out
        kwargs['_err'] = err

        msg = 'Executing testinfra tests found in {}/.'.format(
            self._testinfra_dir)
        util.print_info(msg)

        cmd = sh.testinfra.bake(tests, **kwargs)
        return util.run_command(cmd, debug=self._debug)
예제 #9
0
    def _rubocop(self,
                 serverspec_dir,
                 debug=False,
                 pattern='/**/*.rb',
                 out=util.callback_info,
                 err=util.callback_error):
        """
        Executes rubocop against specified directory/pattern and returns a
        :func:`sh` response object.

        :param serverspec_dir: A string containing the directory with files
        to lint.
        :param debug: An optional bool to toggle debug output.
        :param pattern: A string containing the pattern of files to lint.
        :param out: An optional function to process STDOUT for underlying
         :func:`sh` call.
        :param err: An optional function to process STDERR for underlying
         :func:`sh` call.
        :return: :func:`sh` response object.
        """
        kwargs = {'_out': out, '_err': err, 'debug': debug}

        msg = 'Executing rubocop on *.rb files found in {}/...'.format(
            serverspec_dir)
        util.print_info(msg)
        match = serverspec_dir + pattern

        try:
            cmd = sh.rubocop.bake(match, **kwargs)
        except sh.CommandNotFound:
            msg = 'Verifier missing, gem install rubocop.'
            util.print_error(msg)
            util.sysexit()
        return util.run_command(cmd, debug=self._debug)
예제 #10
0
    def execute(self):
        if not self.enabled:
            msg = "Skipping, verifier is disabled."
            LOG.warning(msg)
            return

        if not len(self._tests) > 0:
            msg = "Skipping, no tests found."
            LOG.warning(msg)
            return

        if self._testinfra_command is None:
            self.bake()

        msg = "Executing Testinfra tests found in {}/...".format(
            self.directory)
        LOG.info(msg)

        result = util.run_command(self._testinfra_command,
                                  debug=self._config.debug)
        if result.returncode == 0:
            msg = "Verifier completed successfully."
            LOG.info(msg)
        else:
            util.sysexit(result.returncode)
예제 #11
0
    def _rake(self,
              rakefile,
              debug=False,
              out=util.callback_info,
              err=util.callback_error):
        """
        Executes rake against specified rakefile and returns a :func:`sh`
        response object.

        :param rakefile: A string containing path to the rakefile.
        :param debug: An optional bool to toggle debug output.
        :param out: An optional function to process STDOUT for underlying
         :func:`sh` call.
        :param err: An optional function to process STDERR for underlying
         :func:`sh` call.
        :return: :func:`sh` response object.
        """
        kwargs = {
            '_out': out,
            '_err': err,
            'trace': debug,
            'rakefile': rakefile
        }

        msg = 'Executing serverspec tests found in {}/...'.format(
            self._serverspec_dir)
        util.print_info(msg)

        try:
            cmd = sh.rake.bake(**kwargs)
        except sh.CommandNotFound:
            msg = 'Verifier missing, gem install rake.'
            util.print_error(msg)
            util.sysexit()
        return util.run_command(cmd, debug=self._debug)
예제 #12
0
def ansible_version(version: str = "") -> Version:
    """Return current Version object for Ansible.

    If version is not mentioned, it returns current version as detected.
    When version argument is mentioned, it return converts the version string
    to Version object in order to make it usable in comparisons.
    """
    if not version:
        proc = run_command(["ansible", "--version"], quiet=True)
        if proc.returncode != 0:
            LOG.fatal(
                "Unable to find a working copy of ansible executable. Read https://molecule.readthedocs.io/en/latest/installation.html\n%s",
                proc,
            )
            sysexit(RC_SETUP_ERROR)

        # First line of the `ansible --version` output is:
        #
        #  1. `ansible <version>` on ansible < 2.10 and on ansible-base.
        #  2. `ansible [core <version>]` on ansible-core.
        #
        # The code below grabs the last component in that line and strips trailing ] if
        # present.
        version = proc.stdout.splitlines()[0].split()[-1].rstrip("]")

    return Version(version)
예제 #13
0
    def execute(self):
        if not self.enabled:
            LOG.warn('Skipping, dependency is disabled.')
            return

        if not self._has_requirements_file():
            LOG.warn('Skipping, missing the requirements file.')
            return

        if self._gilt_command is None:
            self.bake()

        try:
            util.run_command(self._gilt_command, debug=self._config.debug)
            LOG.success('Dependency completed successfully.')
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #14
0
def run_command(cmd, env=os.environ, log=True):
    if log:
        cmd = _rebake_command(cmd, env)

    # Never let sh truncate exceptions in testing
    cmd = cmd.bake(_truncate_exc=False)

    return util.run_command(cmd)
예제 #15
0
def list(x):
    cmd = ["molecule", "list"]
    result = run_command(cmd)
    assert result.returncode == 0
    out = util.strip_ansi_color(result.stdout)

    for l in x.splitlines():
        assert l in out
예제 #16
0
    def execute(self):
        if not self.enabled:
            LOG.warn('Skipping, lint is disabled.')
            return

        if self._yamllint_command is None:
            self.bake()

        msg = 'Executing Yamllint on files found in {}/...'.format(
            self._config.project_directory)
        LOG.info(msg)

        try:
            util.run_command(self._yamllint_command, debug=self._config.debug)
            LOG.success('Lint completed successfully.')
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #17
0
    def execute(self):
        if not self.enabled:
            LOG.warn('Skipping, lint is disabled.')
            return

        if self._ansible_lint_command is None:
            self.bake()

        msg = 'Executing Ansible Lint on {}...'.format(
            self._config.provisioner.playbooks.converge)
        LOG.info(msg)

        try:
            util.run_command(
                self._ansible_lint_command, debug=self._config.debug)
            LOG.success('Lint completed successfully.')
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #18
0
    def execute(self):
        """
        Executes `flake8` and returns None.

        :return: None
        """
        if self._flake8_command is None:
            self.bake()

        msg = 'Executing Flake8 on files found in {}/...'.format(
            self.directory)
        LOG.info(msg)

        try:
            util.run_command(self._flake8_command,
                             debug=self._config.args.get('debug'))
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #19
0
def test(driver_name, scenario_name="default", parallel=False):
    cmd = ["molecule", "test", "--scenario-name", scenario_name]
    if driver_name != "delegated":
        if scenario_name is None:
            cmd.append("--all")
        if parallel:
            cmd.append("--parallel")

    assert run_command(cmd).returncode == 0
예제 #20
0
def login(login_args, scenario_name="default"):
    cmd = ["molecule", "destroy", "--scenario-name", scenario_name]
    assert run_command(cmd).returncode == 0

    cmd = ["molecule", "create", "--scenario-name", scenario_name]
    assert run_command(cmd).returncode == 0

    for instance, regexp in login_args:
        if len(login_args) > 1:
            child_cmd = "molecule login --host {} --scenario-name {}".format(
                instance, scenario_name
            )
        else:
            child_cmd = "molecule login --scenario-name {}".format(scenario_name)
        child = pexpect.spawn(child_cmd)
        child.expect(regexp)
        # If the test returns and doesn't hang it succeeded.
        child.sendline("exit")
예제 #21
0
    def execute(self):
        """
        Executes `ansible-lint` and returns None.

        :return: None
        """
        if not self.enabled:
            LOG.warn('Skipping, lint is disabled.')
            return

        if self._ansible_lint_command is None:
            self.bake()

        try:
            util.run_command(self._ansible_lint_command,
                             debug=self._config.args.get('debug'))
            LOG.success('Lint completed successfully.')
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #22
0
def test_valid(temp_dir, _molecule_file, _role_directory, _command_args,
               _instance):
    _instance._process_templates("molecule", _command_args, _role_directory)

    data = util.safe_load_file(_molecule_file)

    assert {} == schema_v3.validate(data)

    cmd = ["yamllint", "-s", _molecule_file]
    result = util.run_command(cmd)
    assert result.returncode == 0
예제 #23
0
def test_command_init_scenario(temp_dir):
    role_directory = os.path.join(temp_dir.strpath, "test-init")
    cmd = ["molecule", "init", "role", "test-init"]
    assert run_command(cmd).returncode == 0

    with change_dir_to(role_directory):
        molecule_directory = pytest.helpers.molecule_directory()
        scenario_directory = os.path.join(molecule_directory, "test-scenario")
        cmd = [
            "molecule",
            "init",
            "scenario",
            "test-scenario",
            "--role-name",
            "test-init",
            "--driver-name",
            "openstack",
        ]
        assert run_command(cmd).returncode == 0

        assert os.path.isdir(scenario_directory)
예제 #24
0
def test_command_init_scenario(temp_dir):
    role_directory = os.path.join(temp_dir.strpath, "test-init")
    options = {}
    cmd = sh.molecule.bake("init", "role", "test-init", **options)
    assert run_command(cmd).returncode == 0
    metadata_lint_update(role_directory)

    with change_dir_to(role_directory):
        molecule_directory = pytest.helpers.molecule_directory()
        scenario_directory = os.path.join(molecule_directory, "test-scenario")
        options = {
            "role_name": "test-init",
            "driver-name": "ec2",
        }
        cmd = sh.molecule.bake("init", "scenario", "test-scenario", **options)
        assert run_command(cmd).returncode == 0

        assert os.path.isdir(scenario_directory)

        cmd = sh.molecule.bake("test", "-s", "test-scenario")
        assert run_command(cmd).returncode == 0
예제 #25
0
파일: flake8.py 프로젝트: shahtab/molecule
    def execute(self):
        if not self.enabled:
            LOG.warn('Skipping, verifier_lint is disabled.')
            return

        if not len(self._tests) > 0:
            LOG.warn('Skipping, no tests found.')
            return

        if self._flake8_command is None:
            self.bake()

        msg = 'Executing Flake8 on files found in {}/...'.format(
            self._config.verifier.directory)
        LOG.info(msg)

        try:
            util.run_command(self._flake8_command, debug=self._config.debug)
            LOG.success('Lint completed successfully.')
        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
예제 #26
0
def with_scenario(request, scenario_to_test, driver_name, scenario_name):
    scenario_directory = os.path.join(os.path.dirname(util.abs_path(__file__)),
                                      "scenarios", scenario_to_test)

    with change_dir_to(scenario_directory):
        yield
        if scenario_name:
            msg = "CLEANUP: Destroying instances for all scenario(s)"
            LOG.info(msg)
            cmd = [
                "molecule", "destroy", "--driver-name", driver_name, "--all"
            ]
            assert run_command(cmd).returncode == 0
예제 #27
0
def test_vagrant_root(temp_dir, scenario):

    env = os.environ
    if not os.path.exists("/dev/kvm"):
        env.update({"VIRT_DRIVER": "'qemu'"})

    scenario_directory = os.path.join(os.path.dirname(util.abs_path(__file__)),
                                      os.path.pardir, "scenarios")

    with change_dir_to(scenario_directory):
        cmd = ["molecule", "test", "--scenario-name", scenario]
        result = run_command(cmd)
        assert result.returncode == 0
예제 #28
0
    def execute(self):
        """
        Executes ansible-lint against the configured playbook and returns
        None.

        :return: None
        """
        env = os.environ.copy()
        env.update({
            'ANSIBLE_CONFIG':
            self._molecule.config.config['ansible']['config_file']
        })
        if 'ansible_lint' not in self._molecule.disabled:
            msg = 'Executing ansible-lint...'
            util.print_info(msg)
            args = [self._playbook]
            [args.extend(["--exclude", path]) for path in self._ignore_paths]
            cmd = sh.ansible_lint.bake(*args,
                                       _env=env,
                                       _out=util.callback_info,
                                       _err=util.callback_error)
            util.run_command(cmd, debug=self._debug)
예제 #29
0
    def execute(self):
        if not self.enabled:
            LOG.warn('Skipping, verifier is disabled.')
            return

        if not len(self._tests) > 0:
            LOG.warn('Skipping, no tests found.')
            return

        if self._testinfra_command is None:
            self.bake()

        msg = 'Executing Testinfra tests found in {}/...'.format(
            self.directory)
        LOG.info(msg)

        try:
            util.run_command(self._testinfra_command,
                             debug=self._config.args.get('debug'))
            LOG.success('Verifier completed successfully.')

        except sh.ErrorReturnCode as e:
            util.sysexit(e.exit_code)
def test_command_init_scenario(temp_dir):
    """Verify that we can initialize a new scenario with this driver."""
    with change_dir_to(temp_dir):
        scenario_directory = os.path.join(molecule_directory(), "default")
        cmd = [
            "molecule",
            "init",
            "scenario",
            "default",
            "--driver-name",
            "containers",
        ]
        result = run_command(cmd)
        assert result.returncode == 0

        assert os.path.isdir(scenario_directory)

        # we do not run the full "test" sequence because lint will fail, check
        # is shorter but comprehensive enough to test the most important
        # functionality: destroy, dependency, create, prepare, converge
        cmd = ["molecule", "check", "-s", "default"]
        result = run_command(cmd)
        assert result.returncode == 0