Esempio n. 1
0
    def docker_fixture():
        """The actual fixture code generated by get_docker_fixture

        on setup, this fixture ensures that a docker container is running
        and starts one if necessary.

        Fixture yields parameters of the container with a `custom` field passed
        into the `get_docker_container`.

        on teardown, this fixture stops the docker container it started
        """

        skip_if_no_network()
        args = [
            'docker',
            'run',
            '-d',
            '--rm',
        ]
        params = {}
        if name:
            args += ['--name', name]
            params['name'] = name

        if portmaps:
            for from_to in portmaps.items():
                args += ['-p', '%d:%d' % from_to]
                params['port'] = from_to[0]
        args += [image]
        stdout, _ = Runner().run(args)
        params['container_id'] = container_id = stdout.strip()
        params['custom'] = custom_params
        yield params
        Runner().run(['docker', 'stop', container_id])
Esempio n. 2
0
def check_run_and_get_output(cmd):
    runner = Runner()
    try:
        # suppress log output happen it was set to high values
        with patch.dict('os.environ', {'NICEMAN_LOGLEVEL': 'WARN'}):
            output = runner.run(["niceman", "--help"])
    except CommandError as e:
        raise AssertionError("'niceman --help' failed to start normally. "
                             "Exited with %d and output %s" % (e.code, (e.stdout, e.stderr)))
    return output
Esempio n. 3
0
def test_create_and_start(tmpdir):
    runner = Runner()
    tmpdir = str(tmpdir)
    cfg_file = op.join(tmpdir, "custom.cfg")
    inventory_file = op.join(tmpdir, "inventory.yml")
    with open(cfg_file, "w") as cfg_fh:
        cfg_fh.write("[general]\ninventory_file = {}\n".format(inventory_file))

    def run_niceman(args):
        runner(["niceman", "--config", cfg_file] + args, expect_stderr=True)

    run_niceman(["create", "--resource-type=shell", "myshell"])

    with open(inventory_file) as ifh:
        dumped = ifh.read()
    assert "myshell" in dumped
    assert "id" in dumped

    # Running with a different config fails ...
    empty_cfg_file = op.join(tmpdir, "empty.cfg")
    with open(empty_cfg_file, "w"):
        pass

    with swallow_logs(new_level=logging.ERROR) as cml:
        with pytest.raises(CommandError):
            runner(["niceman", "--config", empty_cfg_file, "start", "myshell"])
        if os.environ.get("NICEMAN_LOGTARGET", "stderr") == "stderr":
            assert "ResourceNotFoundError" in cml.out
    # ... but using the same config works.
    run_niceman(["start", "myshell"])
Esempio n. 4
0
 def revision(self):
     # svn info doesn't give the current revision
     # (see http://svnbook.red-bean.com/en/1.7/svn.tour.history.html)
     # so we need to run svn log
     if not hasattr(self, '_revision'):
         runner = Runner()
         log = runner(['svn', 'log', '^/', '-l', '1'], cwd=self.path)[0]
         lines = log.strip().split('\n')
         if len(lines) == 1:
             self._revision = None
         else:
             revision = lines[1].split()[0]
             if revision.startswith('r') and revision[1:].isdigit():
                 self._revision = int(revision[1:])
             else:
                 self._revision = revision[1:]
     return self._revision
Esempio n. 5
0
def test_git_repo_detached(git_repo):
    runner = Runner()
    # If we are in a detached state, we still don't identify the
    # repository itself.
    runner(["git", "checkout", "master^{}", "--"],
           cwd=git_repo,
           expect_stderr=True)

    hexsha_master, _ = runner(["git", "rev-parse", "master"], cwd=git_repo)
    hexsha_master = hexsha_master.strip()

    tracer = VCSTracer()
    dists = list(tracer.identify_distributions([git_repo]))

    pkg = dists[0][0].packages[0]
    # We do not include repository path itself.
    assert pkg.files == []
    assert pkg.hexsha == hexsha_master
    assert not pkg.branch
    assert not pkg.remotes
Esempio n. 6
0
    def chown(self, path, uid=-1, gid=-1, recursive=False, remote=True):
        """Set the user and gid of a path
        """
        uid = int(uid)  # Command line parameters getting passed as type str
        gid = int(gid)

        if uid == -1 and gid > -1:
            command = ['chgrp']
        else:
            command = ['chown']
        if recursive: command += ["-R"]
        if uid > -1 and gid > -1: command += ["{}.{}".format(uid, gid)]
        elif uid > -1: command += [uid]
        elif gid > -1: command += [gid]
        else:
            raise CommandError(cmd='chown',
                               msg="Invalid command \
            parameters.")
        command += [path]
        if remote:
            self.execute_command(command)
        else:
            # Run on the local file system
            Runner().run(command)
Esempio n. 7
0
def venv_test_dir():
    dirs = AppDirs('niceman')
    test_dir = os.path.join(dirs.user_cache_dir, 'venv_test')
    if os.path.exists(test_dir):
        return test_dir

    runner = Runner()
    runner.run(["mkdir", "-p", test_dir])

    pymod_dir = os.path.join(test_dir, "minimal_pymodule")
    create_pymodule(pymod_dir)

    with chpwd(test_dir):
        runner.run(["virtualenv", "--python", PY_VERSION, "venv0"])
        runner.run(["virtualenv", "--python", PY_VERSION, "venv1"])
        runner.run(["./venv0/bin/pip", "install", "pyyaml"])
        runner.run(["./venv0/bin/pip", "install", "-e", pymod_dir])
        runner.run(["./venv1/bin/pip", "install", "attrs"])
    return test_dir
Esempio n. 8
0
 def start(self):
     self._runner = Runner()
Esempio n. 9
0
class ShellSession(POSIXSession):
    """Local shell session"""

    def __init__(self):
        super(ShellSession, self).__init__()
        self._runner = None

    def start(self):
        self._runner = Runner()

    def stop(self):
        self._runner = None

    #
    # Commands fulfilling a "Session" interface to interact with the environment
    #
    def _execute_command(self, command, env=None, cwd=None):
        """
        Execute the given command in the environment.

        Parameters
        ----------
        command : list
            Shell command string or list of command tokens to send to the
            environment to execute.
        env : dict
            Additional (or replacement) environment variables which are applied
            only to the current call

        Returns
        -------
        out, err
        """
        # XXX should it be a generic behavior to auto-start?
        if self._runner is None:
            self.start()
        run_kw = {}
        if env:
            # if anything custom, then we need to get original full environment
            # and update it with custom settings which we either "accumulated"
            # via set_envvar, or it was passed into this call.
            run_kw['env'] = get_updated_env(os.environ, env)

        return self._runner.run(
            command,
            # For now we do not ERROR out whenever command fails or provides
            # stderr -- analysis will be done outside
            expect_fail=True,
            expect_stderr=True,
            cwd=cwd,
            **run_kw
        )  # , shell=True)

    def isdir(self, path):
        return os.path.isdir(path)

    def mkdir(self, path, parents=False):
        if not os.path.exists(path):
            if parents:
                os.makedirs(path)
            else:
                os.mkdir(path)
Esempio n. 10
0
def git_repo_fixture(kind="default", scope="function"):
    """Create a Git repository fixture.

    Parameters
    ----------
    kind : {"empty", "default", "pair"}, optional
        Kind git repository.

        - empty: a repository with no commits.

        - default: a repository with three commits, each adding one of
          its three files: "foo", "bar", and "subdir/baz".

        - pair: a (local, remote) pair of Git repos.  The repos have
          the same structure as the "default" repo, but "local" has a
          remote "origin" with a URL that points to "remote".

    scope : {"function", "class", "module", "session"}, optional
        A `pytest.fixture` scope argument.

    Returns
    -------
    A fixture function.
    """
    runner = Runner()

    def setup_user():
        # Set the user in the local Git configuration rather than
        # through environmental variables so that test functions using
        # this fixture can make commits under the same user.
        runner(["git", "config", "user.name", "A U Thor"])
        runner(["git", "config", "user.email", "*****@*****.**"])

    def add_and_commit(fname):
        directory = os.path.dirname(fname)
        if directory and not os.path.exists(directory):
            os.makedirs(directory)
        with open(fname, "w") as fh:
            fh.write(fname + "content")
        runner.run(["git", "add", fname])
        runner.run(["git", "commit", "-m", "add " + fname])

    @pytest.fixture(scope=scope)
    def fixture():
        # We can't use pytest's tempdir because that is limited to
        # scope=function.
        tmpdir = tempfile.mkdtemp(prefix="niceman-tests-")
        repodir = os.path.realpath(os.path.join(tmpdir, "repo0"))
        os.mkdir(repodir)

        retval = repodir

        with chpwd(repodir):
            runner.run(["git", "init"])
            setup_user()

            if kind != "empty":
                add_and_commit("foo")
                add_and_commit("bar")
                runner.run(["git", "tag", "tag0"])
                add_and_commit("subdir/baz")

            if kind == "pair":
                localdir = os.path.realpath(os.path.join(tmpdir, "repo1"))
                runner.run(["git", "clone", repodir, localdir],
                           expect_stderr=True)
                with chpwd(localdir):
                    setup_user()
                retval = localdir, repodir
        yield retval
        shutil.rmtree(tmpdir)

    return fixture
Esempio n. 11
0
 def fixture():
     skip_if_no_svn()
     repo_name = 'svnrepo'
     tmpdir = os.path.realpath(tempfile.mkdtemp(prefix='niceman-tests-'))
     root_dir = os.path.join(tmpdir, repo_name)
     subdir = os.path.join(tmpdir, 'subdir')
     os.mkdir(subdir)
     runner = Runner()
     runner.run(['svnadmin', 'create', root_dir])
     runner.run(['svn', 'checkout', 'file://' + root_dir], cwd=subdir)
     checked_out_dir = os.path.join(subdir, repo_name)
     if kind != 'empty':
         runner.run(['touch', 'foo'], cwd=checked_out_dir)
         runner.run(['svn', 'add', 'foo'], cwd=checked_out_dir)
         runner.run(['svn', 'commit', '-m', 'bar'], cwd=checked_out_dir)
     yield (root_dir, checked_out_dir)
     shutil.rmtree(tmpdir)
Esempio n. 12
0
 def open(self):
     self._runner = Runner()
Esempio n. 13
0
class ShellSession(POSIXSession):
    """Local shell session"""
    def __init__(self):
        super(ShellSession, self).__init__()
        self._runner = None

    @borrowdoc(Session)
    def open(self):
        self._runner = Runner()

    @borrowdoc(Session)
    def close(self):
        self._runner = None

    @borrowdoc(Session)
    def _execute_command(self, command, env=None, cwd=None):
        # XXX should it be a generic behavior to auto-start?
        if self._runner is None:
            self.open()
        run_kw = {}
        if env:
            # if anything custom, then we need to get original full environment
            # and update it with custom settings which we either "accumulated"
            # via set_envvar, or it was passed into this call.
            run_kw['env'] = get_updated_env(os.environ, env)

        return self._runner.run(
            command,
            # For now we do not ERROR out whenever command fails or provides
            # stderr -- analysis will be done outside
            expect_fail=True,
            expect_stderr=True,
            cwd=cwd,
            **run_kw)  # , shell=True)

    @borrowdoc(Session)
    def isdir(self, path):
        return os.path.isdir(path)

    @borrowdoc(Session)
    def mkdir(self, path, parents=False):
        if not os.path.exists(path):
            if parents:
                os.makedirs(path)
            else:
                try:
                    os.mkdir(path)
                except OSError:
                    raise CommandError(
                        msg="Failed to make directory {}".format(path))

    @borrowdoc(Session)
    def get(self, src_path, dest_path=None, uid=-1, gid=-1):
        dest_path = self._prepare_dest_path(src_path, dest_path)
        shutil.copy(src_path, dest_path)
        if uid > -1 or gid > -1:
            self.chown(dest_path, uid, gid, recursive=True)

    @borrowdoc(Session)
    def put(self, src_path, dest_path, uid=-1, gid=-1):
        # put is the same as get for the shell resource
        self.get(src_path, dest_path, uid, gid)
Esempio n. 14
0
    """For internal use
    """
    def __str__(self):
        return "UNKNOWN"

    def __cmp__(self, other):
        if other is self:
            return 0
        raise TypeError("UNKNOWN version is not comparable")


#
# Custom handlers
#
from niceman.cmd import Runner
_runner = Runner()


def _get_annex_version():
    """Return version of available git-annex"""
    return _runner.run('git annex version --raw'.split())[0]


def _get_git_version():
    """Return version of available git"""
    return _runner.run('git version'.split())[0].split()[-1]


def _get_apt_cache_version():
    """Return version of available git"""
    return _runner.run('apt-cache -v'.split())[0].split()[1]
Esempio n. 15
0
def test_detached_git(repo=None):
    import os
    # XXX Replace with our session?
    from niceman.cmd import Runner
    env = os.environ.copy()
    env['LC_ALL'] = 'C'
    runner = Runner(env=env, cwd=repo)
    assert runner('git config user.name')[0], "git env should be set"
    assert runner('git config user.email')[0], "git env should be set"
    runner('git init')

    # should be good enough not to crash
    distributions, files = identify_distributions([repo])
    assert len(distributions) == 1
    dist = distributions[0]
    assert dist.name == 'git'
    packages = dist.packages
    assert len(packages) == 1
    pkg = packages[0]
    # we do not include repository path itself
    assert pkg.files == []
    assert pkg.path == repo

    # Let's now make it more sensible
    fname = opj(repo, "file")
    with open(fname, 'w') as f:
        f.write("data")
    runner("git add file")
    runner("git commit -m added file")
    distributions, files = identify_distributions([fname])
    assert len(distributions) == 1
    pkg = distributions[0].packages[0]
    assert pkg.files == [fname]
    hexsha = pkg.hexsha
    assert hexsha
    assert pkg.branch == 'master'

    # And if point to a directory under, should not identify the VCS
    # (since in principle git e.g. is not tracing directories)
    subdir = opj(repo, 'subdir')
    os.mkdir(subdir)
    distributions_, files_ = identify_distributions([subdir])
    assert distributions_ == []
    assert files_ == [subdir]

    # but if we point to a file under
    subfile = opj(subdir, 'file')
    with open(subfile, 'w') as f:
        pass
    runner("git add subdir/file")
    distributions__, files__ = identify_distributions([subfile])
    assert len(distributions__) == 1
    pkg = distributions__[0].packages[0]
    assert pkg.files == [subfile]

    # and if we cause a detachment
    runner("git rm file")
    runner("git commit -m removed file")
    runner("git checkout HEAD^", expect_stderr=True)
    distributions, files = identify_distributions([repo])
    pkg = distributions[0].packages[0]
    # we do not include repository path itself
    assert pkg.files == []
    assert pkg.hexsha == hexsha
    assert not pkg.branch
    assert not pkg.remotes
Esempio n. 16
0
def test_git_repo_remotes(git_repo_pair):
    repo_local, repo_remote = git_repo_pair
    runner = Runner()
    tracer = VCSTracer()

    # Set remote.pushdefault to a value we know doesn't exist.
    # Otherwise, the test machine may have remote.pushdefault globally
    # configured to point to "origin".
    runner.run(["git", "config", "remote.pushdefault", "notexisting"],
               cwd=repo_local)
    # Add another remote that doesn't contain the current commit (in
    # fact doesn't actually exist), so that we test the "listed as
    # remote but doesn't contain" case.
    runner.run(["git", "remote", "add", "fakeremote", "fakepath"],
               cwd=repo_local)

    paths = [os.path.join(repo_local, "foo")]

    dists_nopush = list(tracer.identify_distributions(paths))
    assert_distributions(dists_nopush,
                         expected_length=1,
                         expected_subset={
                             "name":
                             "git",
                             "packages": [{
                                 "files": paths,
                                 "path": repo_local,
                                 "branch": "master",
                                 "tracked_remote": "origin",
                                 "remotes": {
                                     "origin": {
                                         "url": repo_remote,
                                         "contains": True
                                     },
                                     "fakeremote": {
                                         "url": "fakepath"
                                     }
                                 }
                             }]
                         })
    pkg_nopush = dists_nopush[0][0].packages[0]
    assert set(pkg_nopush.remotes.keys()) == {"origin", "fakeremote"}

    # fakeremote, which doesn't contain the current commit, doesn't
    # have contains=True.
    assert "contains" in pkg_nopush.remotes["origin"]
    assert "contains" not in pkg_nopush.remotes["fakeremote"]
    # pushurl is not included in the output above because it is not
    # set.
    assert "pushurl" not in list(pkg_nopush.remotes.values())

    # If we set the pushurl and retrace, it is included.
    runner.run(["git", "config", "remote.origin.pushurl", repo_remote],
               cwd=repo_local)
    dists_push = list(tracer.identify_distributions(paths))
    pkg_push = dists_push[0][0].packages[0]
    assert pkg_push.remotes["origin"]["pushurl"] == repo_remote

    # If we are at a commit that none of the remotes are known to
    # contain, there are no listed remotes.
    with chpwd(repo_local):
        runner(["git", "commit", "--allow-empty", "-m", "empty commit"])

    dists_nocontain = list(tracer.identify_distributions(paths))
    assert not dists_nocontain[0][0].packages[0].remotes.values()

    # The remote repository, however, doesn't have a remote, so there
    # are not listed remotes.
    paths = [os.path.join(repo_remote, "foo")]
    dists_remote = list(tracer.identify_distributions(paths))
    assert not dists_remote[0][0].packages[0].remotes.values()