Exemple #1
0
    def _info(self, branch=None, revision=None, cwd=''):
        commit = self.find(branch=branch, revision=revision)
        if not commit:
            return mocks.ProcessCompletion(returncode=1, stderr='svn: E160006: No such revision {}\n'.format(revision))

        return mocks.ProcessCompletion(
            returncode=0,
            stdout=
            'Path: .\n'
            'Working Copy Root Path: {path}\n'
            'URL: {remote}/{branch}{directory}\n'
            'Relative URL: ^/{branch}{directory}\n'
            'Repository Root: {remote}\n'
            'Revision: {revision}\n'
            'NodeKind: directory\n'
            'Schedule: normal\n'
            'Last Changed Author: {author}\n'
            'Last Changed Rev: {revision}\n'
            'Last Changed Date: {date}'.format(
                directory=cwd[len(self.path):],
                path=self.path,
                remote=self.remote,
                branch=self.branch,
                revision=commit.revision,
                author=commit.author.email,
                date=datetime.utcfromtimestamp(commit.timestamp).strftime('%Y-%m-%d %H:%M:%S {} (%a, %d %b %Y)'.format(self.utc_offset)),
            ),
        )
    def test_documentation(self):
        with OutputCapture():
            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                result = run(['ls'], capture_output=True, encoding='utf-8')
                assert result.returncode == 0
                assert result.stdout == 'file1.txt\nfile2.txt\n'

            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                assert subprocess.check_output(['ls'
                                                ]) == b'file1.txt\nfile2.txt\n'
                assert subprocess.check_call(['ls']) == 0

            with mocks.Subprocess(
                    mocks.Subprocess.CommandRoute(
                        'command-a',
                        'argument',
                        completion=mocks.ProcessCompletion(returncode=0)),
                    mocks.Subprocess.CommandRoute(
                        'command-b',
                        completion=mocks.ProcessCompletion(returncode=-1)),
            ):
                result = run(['command-a', 'argument'])
                assert result.returncode == 0

                result = run(['command-b'])
                assert result.returncode == -1
 def test_cwd_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0),
                 cwd='/example'),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command'], cwd='/example').returncode, 0)
 def test_argument_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 '--help',
                 completion=mocks.ProcessCompletion(returncode=0)),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command', '--help']).returncode, 0)
Exemple #5
0
 def _log_for(self, branch=None, revision=None):
     commit = self.find(branch=branch, revision=revision)
     if not commit:
         return mocks.ProcessCompletion(returncode=1)
     return mocks.ProcessCompletion(
         returncode=0,
         stdout=
         '------------------------------------------------------------------------\n'
         '{line} | {lines} lines\n\n'
         '{log}\n'.format(line=self.log_line(commit),
                          lines=len(commit.message.splitlines()),
                          log=commit.message),
     )
 def test_input_priority(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0),
                 input='stdin'),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
     ):
         self.assertEqual(run(['command']).returncode, 1)
         self.assertEqual(run(['command'], input='stdin').returncode, 0)
         self.assertEqual(
             run(['command'], stdin=BytesIO(b'stdin')).returncode, 0)
 def test_ordered(self):
     with OutputCapture(), mocks.Subprocess(
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=0)),
             mocks.Subprocess.Route(
                 'command',
                 completion=mocks.ProcessCompletion(returncode=1)),
             ordered=True,
     ):
         self.assertEqual(run(['command']).returncode, 0)
         self.assertEqual(run(['command']).returncode, 1)
         with self.assertRaises(OSError):
             run(['command'])
    def test_implied_route(self):
        with mocks.Subprocess(
                'command', completion=mocks.ProcessCompletion(returncode=0)):
            self.assertEqual(run(['command']).returncode, 0)

            with self.assertRaises(OSError):
                run(['invalid-file'])
Exemple #9
0
    def _log_range(self, branch=None, end=None, begin=None):
        if end < begin:
            return mocks.ProcessCompletion(returncode=1)

        output = ''
        previous = None
        for b in [branch, 'trunk']:
            for candidate in reversed(self.commits.get(b, [])):
                if candidate.revision > end or candidate.revision < begin:
                    continue
                if previous and previous.revision <= candidate.revision:
                    continue
                previous = candidate
                output += ('------------------------------------------------------------------------\n'
                    '{line} | {lines} lines\n\n'
                    '{log}\n').format(
                        line=self.log_line(candidate),
                        lines=len(candidate.message.splitlines()),
                        log=candidate.message
                )
        return mocks.ProcessCompletion(returncode=0, stdout=output)
Exemple #10
0
    def filter_branch(self,
                      range,
                      identifier_template=None,
                      environment_shell=None):
        # We can't effectively mock the bash script in the command, but we can mock the python code that
        # script calls, which is where the program logic is.
        head, start = range.split('...')
        head = self.find(head)
        start = self.find(start)

        commits_to_edit = []
        for commit in reversed(self.commits[head.branch]):
            if commit.branch == start.branch and commit.identifier <= start.identifier:
                break
            commits_to_edit.insert(0, commit)
        if head.branch != self.default_branch:
            for commit in reversed(
                    self.commits[self.default_branch][:head.branch_point]):
                if commit.identifier <= start.identifier:
                    break
                commits_to_edit.insert(0, commit)

        stdout = StringIO()
        original_env = {
            key: os.environ.get('OLDPWD')
            for key in [
                'OLDPWD',
                'GIT_COMMIT',
                'GIT_AUTHOR_NAME',
                'GIT_AUTHOR_EMAIL',
                'GIT_COMMITTER_NAME',
                'GIT_COMMITTER_EMAIL',
            ]
        }

        try:
            count = 0
            os.environ['OLDPWD'] = self.path
            for commit in commits_to_edit:
                count += 1
                os.environ['GIT_COMMIT'] = commit.hash
                os.environ['GIT_AUTHOR_NAME'] = commit.author.name
                os.environ['GIT_AUTHOR_EMAIL'] = commit.author.email
                os.environ['GIT_COMMITTER_NAME'] = commit.author.name
                os.environ['GIT_COMMITTER_EMAIL'] = commit.author.email

                stdout.write(
                    'Rewrite {hash} ({count}/{total}) (--- seconds passed, remaining --- predicted)\n'
                    .format(
                        hash=commit.hash,
                        count=count,
                        total=len(commits_to_edit),
                    ))

                if identifier_template:
                    messagefile = StringIO()
                    messagefile.write(commit.message)
                    messagefile.seek(0)
                    with OutputCapture() as captured:
                        message_main(messagefile, identifier_template)
                    lines = captured.stdout.getvalue().splitlines()
                    if lines[-1].startswith('git-svn-id: https://svn'):
                        lines.pop(-1)
                    commit.message = '\n'.join(lines)

                if not environment_shell:
                    continue
                if re.search(r'echo "Overwriting', environment_shell):
                    stdout.write('Overwriting {}\n'.format(commit.hash))

                match = re.search(r'(?P<json>\S+\.json)', environment_shell)
                if match:
                    with OutputCapture() as captured:
                        committer_main(match.group('json'))
                    captured.stdout.seek(0)
                    for line in captured.stdout.readlines():
                        line = line.rstrip()
                        os.environ[line.split(' ')[0]] = ' '.join(
                            line.split(' ')[1:])

                commit.author = Contributor(
                    name=os.environ['GIT_AUTHOR_NAME'],
                    emails=[os.environ['GIT_AUTHOR_EMAIL']])

                if re.search(r'echo "\s+', environment_shell):
                    for key in [
                            'GIT_AUTHOR_NAME', 'GIT_AUTHOR_EMAIL',
                            'GIT_COMMITTER_NAME', 'GIT_COMMITTER_EMAIL'
                    ]:
                        stdout.write('    {}={}\n'.format(
                            key, os.environ[key]))

        finally:
            for key, value in original_env.items():
                if value is not None:
                    os.environ[key] = value
                else:
                    del os.environ[key]

        return mocks.ProcessCompletion(
            returncode=0,
            stdout=stdout.getvalue(),
        )
Exemple #11
0
    def __init__(
        self,
        path='/.invalid-git',
        datafile=None,
        remote=None,
        tags=None,
        detached=None,
        default_branch='main',
        git_svn=False,
    ):
        self.path = path
        self.default_branch = default_branch
        self.remote = remote or '[email protected]:/mock/{}'.format(
            os.path.basename(path))
        self.detached = detached or False

        self.tags = tags or {}

        try:
            self.executable = local.Git.executable()
        except (OSError, AssertionError):
            self.executable = '/usr/bin/git'

        with open(datafile
                  or os.path.join(os.path.dirname(os.path.dirname(__file__)),
                                  'git-repo.json')) as file:
            self.commits = json.load(file)
        for key, commits in self.commits.items():
            self.commits[key] = [Commit(**kwargs) for kwargs in commits]
            if not git_svn:
                for commit in self.commits[key]:
                    commit.revision = None

        self.head = self.commits[self.default_branch][-1]
        self.remotes = {
            'origin/{}'.format(branch): commits[-1]
            for branch, commits in self.commits.items()
        }
        self.tags = {}

        # If the directory provided actually exists, populate it
        if os.path.isdir(self.path):
            if not os.path.isdir(os.path.join(self.path, '.git')):
                os.mkdir(os.path.join(self.path, '.git'))
            with open(os.path.join(self.path, '.git', 'config'),
                      'w') as config:
                config.write('[core]\n'
                             '\trepositoryformatversion = 0\n'
                             '\tfilemode = true\n'
                             '\tbare = false\n'
                             '\tlogallrefupdates = true\n'
                             '\tignorecase = true\n'
                             '\tprecomposeunicode = true\n'
                             '[remote "origin"]\n'
                             '\turl = {remote}\n'
                             '\tfetch = +refs/heads/*:refs/remotes/origin/*\n'
                             '[branch "{branch}"]\n'
                             '\tremote = origin\n'
                             '\tmerge = refs/heads/{branch}\n'.format(
                                 remote=self.remote,
                                 branch=self.default_branch,
                             ))
                if git_svn:
                    domain = 'webkit.org'
                    if self.remote.startswith('https://'):
                        domain = self.remote.split('/')[2]
                    elif '@' in self.remote:
                        domain = self.remote.split('@')[1].split(':')[0]

                    config.write(
                        '[svn-remote "svn"]\n'
                        '    url = https://svn.{domain}/repository/webkit\n'
                        '    fetch = trunk:refs/remotes/origin/{branch}'.
                        format(
                            domain=domain,
                            branch=self.default_branch,
                        ))

        if git_svn:
            git_svn_routes = [
                mocks.Subprocess.Route(
                    self.executable,
                    'svn',
                    'find-rev',
                    re.compile(r'r\d+'),
                    cwd=self.path,
                    generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                        returncode=0,
                        stdout=getattr(self.find(args[3][1:]), 'hash', '\n'),
                    )),
                mocks.Subprocess.Route(
                    self.executable,
                    'svn',
                    'info',
                    cwd=self.path,
                    generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                        returncode=0,
                        stdout='Path: .\n'
                        'URL: {remote}/{branch}\n'
                        'Repository Root: {remote}\n'
                        'Revision: {revision}\n'
                        'Node Kind: directory\n'
                        'Schedule: normal\n'
                        'Last Changed Author: {author}\n'
                        'Last Changed Rev: {revision}\n'
                        'Last Changed Date: {date}'.format(
                            path=self.path,
                            remote=self.remote,
                            branch=self.head.branch,
                            revision=self.head.revision,
                            author=self.head.author.email,
                            date=datetime.fromtimestamp(self.head.timestamp).
                            strftime('%Y-%m-%d %H:%M:%S'),
                        ),
                    ),
                ),
            ]

        else:
            git_svn_routes = [
                mocks.Subprocess.Route(
                    self.executable,
                    'svn',
                    cwd=self.path,
                    completion=mocks.ProcessCompletion(returncode=1,
                                                       elapsed=2),
                )
            ]

        super(Git, self).__init__(
            mocks.Subprocess.Route(
                '/usr/bin/which',
                'git',
                completion=mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.executable),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'status',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='''HEAD detached at b8a315ed93c
nothing to commit, working tree clean
''' if self.detached else ''''On branch {branch}
Your branch is up to date with 'origin/{branch}'.

nothing to commit, working tree clean
'''.format(branch=self.branch),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'rev-parse',
                '--show-toplevel',
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.path),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'rev-parse',
                '--abbrev-ref',
                'HEAD',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format('HEAD'
                                         if self.detached else self.branch),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'remote',
                'get-url',
                '.*',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.remote),
                ) if args[3] == 'origin' else mocks.ProcessCompletion(
                    returncode=128,
                    stderr="fatal: No such remote '{}'\n".format(args[3]),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'branch',
                '-a',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(
                        sorted(['* ' + self.branch] + list(
                            ({default_branch} | set(self.commits.keys())) - {
                                self.branch
                            }))) + '\nremotes/origin/HEAD -> origin/{}\n'.
                    format(default_branch),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'tag',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(sorted(self.tags.keys())) + '\n',
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'rev-parse',
                '--abbrev-ref',
                'origin/HEAD',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='origin/{}\n'.format(default_branch),
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'rev-parse',
                '.*',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.find(args[2]).hash),
                ) if self.find(args[2]) else mocks.ProcessCompletion(returncode
                                                                     =128)),
            mocks.Subprocess.Route(
                self.executable,
                'log',
                re.compile(r'.+'),
                '-1',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout=
                    'commit {hash} (HEAD -> {branch}, origin/{branch}, origin/HEAD)\n'
                    'Author: {author} <{email}>\n'
                    'Date:   {date}\n'
                    '\n{log}'.format(
                        hash=self.find(args[2]).hash,
                        branch=self.branch,
                        author=self.find(args[2]
                                         ).author.name,
                        email=self.find(args[
                            2]).author.email,
                        date
                        =datetime.fromtimestamp(self.find(
                            args[2]).timestamp).strftime('%a %b %d %H:%M:%S %Y'
                                                         ),
                        log
                        ='\n'.join(
                            [('    ' + line) if line else '' for line in self.
                             find(args[2])
                             .message.splitlines()] +
                            ([
                                'git-svn-id: https://svn.{}/repository/{}/trunk@{} 268f45cc-cd09-0410-ab3c-d52691b4dbfc'
                                .format(
                                    self.remote.split('@')[-1].split(':')[0],
                                    os.path.basename(path),
                                    self.find(args[2]).revision,
                                )
                            ] if git_svn else []), )),
                ) if self.find(args[2]) else mocks.ProcessCompletion(returncode
                                                                     =128),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'rev-list',
                '--count',
                '--no-merges',
                re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0, stdout='{}\n'.format(self.count(args[4])))
                if self.find(args[4]) else mocks.ProcessCompletion(returncode=
                                                                   128),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'show',
                '-s',
                '--format=%ct',
                re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.find(args[4]).timestamp, ))
                if self.find(args[4]) else mocks.ProcessCompletion(returncode=
                                                                   128),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'branch',
                '-a',
                '--contains',
                re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(sorted(self.branches_on(args[4]))) + '\n',
                ) if self.find(args[4]) else mocks.ProcessCompletion(returncode
                                                                     =128),
            ),
            mocks.Subprocess.Route(self.executable,
                                   'checkout',
                                   re.compile(r'.+'),
                                   cwd=self.path,
                                   generator=lambda *args, **kwargs: mocks.
                                   ProcessCompletion(returncode=0)
                                   if self.checkout(args[2]) else mocks.
                                   ProcessCompletion(returncode=1)),
            mocks.Subprocess.Route(
                self.executable,
                'filter-branch',
                '-f',
                cwd=self.path,
                generator=lambda *args, **kwargs: self.filter_branch(
                    args[-1],
                    identifier_template=args[-2].split("'")[-2]
                    if args[-3] == '--msg-filter' else None,
                    environment_shell=args[4]
                    if args[3] == '--env-filter' and args[4] else None,
                )),
            mocks.Subprocess.Route(
                self.executable,
                'svn',
                'fetch',
                '--log-window-size=5000',
                '-r',
                re.compile(r'\d+:HEAD'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0) if git_svn or local.Git(self.path).is_svn
                else mocks.ProcessCompletion(returncode=-1),
            ),
            mocks.Subprocess.Route(
                self.executable,
                'pull',
                cwd=self.path,
                completion=mocks.ProcessCompletion(returncode=0),
            ),
            mocks.Subprocess.Route(
                self.executable,
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=1,
                    stderr='usage: git [--version] [--help]...\n',
                ),
            ),
            mocks.Subprocess.Route(
                self.executable,
                completion=mocks.ProcessCompletion(
                    returncode=128,
                    stderr=
                    'fatal: not a git repository (or any parent up to mount point)\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).\n',
                ),
            ), *git_svn_routes)
Exemple #12
0
    def __init__(
        self, path='/.invalid-git', datafile=None,
        remote=None, branches=None, tags=None,
        detached=None, default_branch='main',
        git_svn=False,
    ):
        self.path = path
        self.default_branch = default_branch
        self.remote = remote or '[email protected]:/mock/{}'.format(os.path.basename(path))
        self.detached = detached or False

        self.branches = branches or []
        self.tags = tags or {}

        try:
            self.executable = local.Git.executable()
        except (OSError, AssertionError):
            self.executable = '/usr/bin/git'

        with open(datafile or os.path.join(os.path.dirname(os.path.dirname(__file__)), 'git-repo.json')) as file:
            self.commits = json.load(file)
        for key, commits in self.commits.items():
            self.commits[key] = [Commit(**kwargs) for kwargs in commits]
            if not git_svn:
                for commit in self.commits[key]:
                    commit.revision = None

        self.head = self.commits[self.default_branch][-1]
        self.tags = {}

        if git_svn:
            git_svn_routes = [
                mocks.Subprocess.Route(
                    self.executable, 'svn', 'find-rev', re.compile(r'r\d+'),
                    cwd=self.path,
                    generator=lambda *args, **kwargs:
                        mocks.ProcessCompletion(
                            returncode=0,
                            stdout=getattr(self.find(args[3][1:]), 'hash', '\n'),
                        )
                ), mocks.Subprocess.Route(
                    self.executable, 'svn', 'info',
                    cwd=self.path,
                    generator=lambda *args, **kwargs:
                        mocks.ProcessCompletion(
                            returncode=0,
                            stdout=
                                'Path: .\n'
                                'URL: {remote}/{branch}\n'
                                'Repository Root: {remote}\n'
                                'Revision: {revision}\n'
                                'Node Kind: directory\n'
                                'Schedule: normal\n'
                                'Last Changed Author: {author}\n'
                                'Last Changed Rev: {revision}\n'
                                'Last Changed Date: {date}'.format(
                                    path=self.path,
                                    remote=self.remote,
                                    branch=self.head.branch,
                                    revision=self.head.revision,
                                    author=self.head.author.email,
                                    date=datetime.fromtimestamp(self.head.timestamp).strftime('%Y-%m-%d %H:%M:%S'),
                                ),
                        ),
                ),
            ]

        else:
            git_svn_routes = [mocks.Subprocess.Route(
                self.executable, 'svn',
                cwd=self.path,
                completion=mocks.ProcessCompletion(returncode=1, elapsed=2),
            )]

        super(Git, self).__init__(
            mocks.Subprocess.Route(
                '/usr/bin/which', 'git',
                completion=mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.executable),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'status',
                cwd=self.path,
                generator=lambda *args, **kwargs:
                    mocks.ProcessCompletion(
                        returncode=0,
                        stdout='''HEAD detached at b8a315ed93c
nothing to commit, working tree clean
''' if self.detached else ''''On branch {branch}
Your branch is up to date with 'origin/{branch}'.

nothing to commit, working tree clean
'''.format(branch=self.branch),
                    ),
            ),
            mocks.Subprocess.Route(
                self.executable, 'rev-parse', '--show-toplevel',
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.path),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'rev-parse', '--abbrev-ref', 'HEAD',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format('HEAD' if self.detached else self.branch),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'remote', 'get-url', '.*',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.remote),
                ) if args[3] == 'origin' else mocks.ProcessCompletion(
                    returncode=128,
                    stderr="fatal: No such remote '{}'\n".format(args[3]),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'branch', '-a',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(sorted(['* ' + self.branch] + list(({default_branch} | set(self.commits.keys()) | set(self.branches)) - {self.branch}))) +
                           '\nremotes/origin/HEAD -> origin/{}\n'.format(default_branch),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'tag',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(sorted(self.tags.keys())) + '\n',
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'rev-parse', '--abbrev-ref', 'origin/HEAD',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='origin/{}\n'.format(default_branch),
                ),
            ), mocks.Subprocess.Route(
                self.executable, 'rev-parse', '.*',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.find(args[2]).hash),
                ) if self.find(args[2]) else mocks.ProcessCompletion(returncode=128)
            ), mocks.Subprocess.Route(
                self.executable, 'log', re.compile(r'.+'), '-1',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout=
                        'commit {hash} (HEAD -> {branch}, origin/{branch}, origin/HEAD)\n'
                        'Author: {author} <{email}>\n'
                        'Date:   {date}\n'
                        '\n{log}'.format(
                            hash=self.find(args[2]).hash,
                            branch=self.branch,
                            author=self.find(args[2]).author.name,
                            email=self.find(args[2]).author.email,
                            date=datetime.fromtimestamp(self.find(args[2]).timestamp).strftime('%a %b %d %H:%M:%S %Y'),
                            log='\n'.join([
                                    ('    ' + line) if line else '' for line in self.find(args[2]).message.splitlines()
                                ] + ['git-svn-id: https://svn.{}/repository/{}/trunk@{} 268f45cc-cd09-0410-ab3c-d52691b4dbfc'.format(
                                    self.remote.split('@')[-1].split(':')[0],
                                    os.path.basename(path),
                                    self.find(args[2]).revision,
                                )] if git_svn else [],
                            )
                        ),
                ) if self.find(args[2]) else mocks.ProcessCompletion(returncode=128),
            ), mocks.Subprocess.Route(
                self.executable, 'rev-list', '--count', '--no-merges', re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.count(args[4]))
                ) if self.find(args[4]) else mocks.ProcessCompletion(returncode=128),
            ), mocks.Subprocess.Route(
                self.executable, 'show', '-s', '--format=%ct', re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(
                        self.find(args[4]).timestamp,
                    )
                ) if self.find(args[4]) else mocks.ProcessCompletion(returncode=128),
            ), mocks.Subprocess.Route(
                self.executable, 'branch', '-a', '--contains', re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(sorted(self.branches_on(args[4]))) + '\n',
                ) if self.find(args[4]) else mocks.ProcessCompletion(returncode=128),
            ), mocks.Subprocess.Route(
                self.executable, 'checkout', re.compile(r'.+'),
                cwd=self.path,
                generator=lambda *args, **kwargs:
                    mocks.ProcessCompletion(returncode=0) if self.checkout(args[2]) else mocks.ProcessCompletion(returncode=1)
            ), mocks.Subprocess.Route(
                self.executable,
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=1,
                    stderr='usage: git [--version] [--help]...\n',
                ),
            ), mocks.Subprocess.Route(
                self.executable,
                completion=mocks.ProcessCompletion(
                    returncode=128,
                    stderr='fatal: not a git repository (or any parent up to mount point)\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).\n',
                ),
            ), *git_svn_routes
        )
Exemple #13
0
    def __init__(self, path='/.invalid-svn', datafile=None, remote=None, utc_offset=None):
        self.path = path
        self.remote = remote or 'https://svn.mock.org/repository/{}'.format(os.path.basename(path))
        self.utc_offset = utc_offset or '0000'

        self.connected = True

        try:
            self.executable = local.Svn.executable()
        except (OSError, AssertionError):
            self.executable = '/usr/bin/svn'

        with open(datafile or os.path.join(os.path.dirname(os.path.dirname(__file__)), 'svn-repo.json')) as file:
            self.commits = json.load(file)
        for key, commits in self.commits.items():
            self.commits[key] = [Commit(**kwargs) for kwargs in commits]

        self.head = self.commits['trunk'][-1]

        super(Svn, self).__init__(
            mocks.Subprocess.Route(
                self.executable, 'info',
                cwd=self.path,
                generator=lambda *args, **kwargs: self._info(cwd=kwargs.get('cwd', ''))
            ), mocks.Subprocess.Route(
                self.executable, 'info', self.BRANCH_RE,
                cwd=self.path,
                generator=lambda *args, **kwargs: self._info(branch=self.BRANCH_RE.match(args[2]).group('branch'), cwd=kwargs.get('cwd', ''))
            ), mocks.Subprocess.Route(
                self.executable, 'list', '^/branches',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='/\n'.join(sorted(set(self.commits.keys()) - {'trunk'} - self.tags)) + '/\n',
                ) if self.connected else mocks.ProcessCompletion(returncode=1),
            ), mocks.Subprocess.Route(
                self.executable, 'list', '^/tags',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='/\n'.join([tag[len('tags/'):] for tag in sorted(self.tags)]) + '/\n',
                ) if self.connected else mocks.ProcessCompletion(returncode=1),
            ), mocks.Subprocess.Route(
                self.executable, 'log', '-v', '-q', self.remote, '-r', re.compile(r'\d+'),
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout=
                        '{line}\n'
                        'Changed paths:\n'
                        '    M /{branch}/ChangeLog\n'
                        '    M /{branch}/file.cpp\n'
                        '    D /{branch}/deleted.cpp\n'
                        '    A /{branch}/added.cpp\n'.format(
                            line=self.log_line(self.find(revision=args[6])),
                            branch=self.find(revision=args[6]).branch if self.find(revision=args[6]).branch.split('/')[0] in ['trunk', 'tags'] else 'branches/{}'.format(self.find(revision=args[6]).branch)
                        ),
                ) if self.connected and self.find(revision=args[6]) else mocks.ProcessCompletion(returncode=1),
            ), mocks.Subprocess.Route(
                self.executable, 'log', '-q', self.BRANCH_RE,
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n{}\n'.format('-' * 72).join([
                        self.log_line(commit) for commit in self._commits_for(branch=self.BRANCH_RE.match(args[3]).group('branch'))
                    ]),
                ) if self.connected and self.BRANCH_RE.match(args[3]).group('branch') in self.commits else mocks.ProcessCompletion(returncode=1)
            ), mocks.Subprocess.Route(
                self.executable, 'log', '-l', '1', '-r', re.compile(r'\d+'), self.BRANCH_RE,
                cwd=self.path,
                generator=lambda *args, **kwargs: self._log_for(
                    branch=self.BRANCH_RE.match(args[6]).group('branch'),
                    revision=args[5],
                ) if self.connected else mocks.ProcessCompletion(returncode=1)
            ), mocks.Subprocess.Route(
                self.executable, 'up', '-r', re.compile(r'\d+'),
                cwd=self.path,
                generator=lambda *args, **kwargs:
                    mocks.ProcessCompletion(returncode=0) if self.up(args[3]) else mocks.ProcessCompletion(returncode=1)
            ), mocks.Subprocess.Route(
                self.executable, 'up',
                cwd=self.path,
                completion=mocks.ProcessCompletion(returncode=0),
            ), mocks.Subprocess.Route(
                self.executable,
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=1,
                    stderr="Type 'svn help' for usage.\n",
                )
            ), mocks.Subprocess.Route(
                self.executable,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=1,
                    stderr="svn: E155007: '{}' is not a working copy\n".format(kwargs.get('cwd')),
                )
            ),
        )
Exemple #14
0
    def __init__(self,
                 path='/.invalid-svn',
                 branch=None,
                 remote=None,
                 branches=None,
                 tags=None):
        self.path = path
        self.branch = branch or 'trunk'
        self.remote = remote or 'https://svn.mock.org/repository/{}'.format(
            os.path.basename(path))

        self.branches = branches or []
        self.tags = tags or []

        super(Svn, self).__init__(
            mocks.Subprocess.Route(
                local.Svn.executable,
                'info',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='Path: .\n'
                    'Working Copy Root Path: {path}\n'
                    'URL: {remote}/{branch}{directory}\n'
                    'Relative URL: ^/{branch}{directory}\n'
                    'Repository Root: {remote}\n'.format(
                        directory=kwargs.get('cwd', '')[len(self.path):],
                        path=self.path,
                        remote=self.remote,
                        branch=self.branch,
                    ),
                ),
            ),
            mocks.Subprocess.Route(
                local.Svn.executable,
                'list',
                '^/branches',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='/\n'.join(self.branches) + '/\n',
                ),
            ),
            mocks.Subprocess.Route(
                local.Svn.executable,
                'list',
                '^/tags',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='/\n'.join(self.tags) + '/\n',
                ),
            ),
            mocks.Subprocess.Route(local.Svn.executable,
                                   cwd=self.path,
                                   completion=mocks.ProcessCompletion(
                                       returncode=1,
                                       stderr="Type 'svn help' for usage.\n",
                                   )),
            mocks.Subprocess.Route(
                local.Svn.executable,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=1,
                    stderr="svn: E155007: '{}' is not a working copy\n".format(
                        kwargs.get('cwd')),
                )),
        )
Exemple #15
0
class MockSubprocess(unittest.TestCase):
    LS = mocks.Subprocess.Route(
        'ls',
        completion=mocks.ProcessCompletion(returncode=0,
                                           stdout='file1.txt\nfile2.txt\n'),
    )
    SLEEP = mocks.Subprocess.Route(
        'sleep',
        generator=lambda *args, **kwargs: mocks.ProcessCompletion(
            returncode=0, elapsed=int(args[1])),
    )

    def test_documentation(self):
        with OutputCapture():
            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                result = run(['ls'], capture_output=True, encoding='utf-8')
                assert result.returncode == 0
                assert result.stdout == 'file1.txt\nfile2.txt\n'

            with mocks.Subprocess(
                    'ls',
                    completion=mocks.ProcessCompletion(
                        returncode=0, stdout='file1.txt\nfile2.txt\n'),
            ):
                assert subprocess.check_output(['ls'
                                                ]) == b'file1.txt\nfile2.txt\n'
                assert subprocess.check_call(['ls']) == 0

            with mocks.Subprocess(
                    mocks.Subprocess.CommandRoute(
                        'command-a',
                        'argument',
                        completion=mocks.ProcessCompletion(returncode=0)),
                    mocks.Subprocess.CommandRoute(
                        'command-b',
                        completion=mocks.ProcessCompletion(returncode=-1)),
            ):
                result = run(['command-a', 'argument'])
                assert result.returncode == 0

                result = run(['command-b'])
                assert result.returncode == -1

    def test_no_file(self):
        with mocks.Subprocess(self.LS, self.SLEEP):
            with self.assertRaises(OSError):
                run(['invalid-file'])

    def test_implied_route(self):
        with mocks.Subprocess(
                'command', completion=mocks.ProcessCompletion(returncode=0)):
            self.assertEqual(run(['command']).returncode, 0)

            with self.assertRaises(OSError):
                run(['invalid-file'])

    def test_popen(self):
        with mocks.Time:
            with mocks.Subprocess(self.LS, self.SLEEP):
                ls = subprocess.Popen(['ls'],
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
                ls.wait()
                self.assertEqual(0, ls.poll())
                self.assertEqual(b'file1.txt\nfile2.txt\n', ls.stdout.read())

                sleep = subprocess.Popen(['sleep', '1'],
                                         stdout=subprocess.PIPE,
                                         stderr=subprocess.PIPE)
                self.assertEqual(None, sleep.poll())
                sleep.wait()
                self.assertEqual(0, sleep.poll())

    def test_ordered(self):
        with OutputCapture(), mocks.Subprocess(
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=0)),
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=1)),
                ordered=True,
        ):
            self.assertEqual(run(['command']).returncode, 0)
            self.assertEqual(run(['command']).returncode, 1)
            with self.assertRaises(OSError):
                run(['command'])

    def test_argument_priority(self):
        with OutputCapture(), mocks.Subprocess(
                mocks.Subprocess.Route(
                    'command',
                    '--help',
                    completion=mocks.ProcessCompletion(returncode=0)),
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=1)),
        ):
            self.assertEqual(run(['command']).returncode, 1)
            self.assertEqual(run(['command', '--help']).returncode, 0)

    def test_cwd_priority(self):
        with OutputCapture(), mocks.Subprocess(
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=0),
                    cwd='/example'),
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=1)),
        ):
            self.assertEqual(run(['command']).returncode, 1)
            self.assertEqual(run(['command'], cwd='/example').returncode, 0)

    def test_input_priority(self):
        with OutputCapture(), mocks.Subprocess(
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=0),
                    input='stdin'),
                mocks.Subprocess.Route(
                    'command',
                    completion=mocks.ProcessCompletion(returncode=1)),
        ):
            self.assertEqual(run(['command']).returncode, 1)
            self.assertEqual(run(['command'], input='stdin').returncode, 0)
            self.assertEqual(
                run(['command'], stdin=BytesIO(b'stdin')).returncode, 0)
Exemple #16
0
    def __init__(
        self,
        path='/.invalid-git',
        branch=None,
        remote=None,
        branches=None,
        tags=None,
        detached=None,
        default_branch='main',
    ):
        self.path = path
        self.branch = branch or default_branch
        self.remote = remote or '[email protected]:/mock/{}'.format(
            os.path.basename(path))
        self.detached = detached or False

        self.branches = branches or []
        self.tags = tags or []

        super(Git, self).__init__(
            mocks.Subprocess.Route(
                local.Git.executable,
                'status',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='''HEAD detached at b8a315ed93c
nothing to commit, working tree clean
''' if self.detached else ''''On branch {branch}
Your branch is up to date with 'origin/{branch}'.

nothing to commit, working tree clean
'''.format(branch=self.branch),
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                'rev-parse',
                '--show-toplevel',
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.path),
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                'rev-parse',
                '--abbrev-ref',
                'HEAD',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format('HEAD'
                                         if self.detached else self.branch),
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                'remote',
                'get-url',
                '.*',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='{}\n'.format(self.remote),
                ) if args[3] == 'origin' else mocks.ProcessCompletion(
                    returncode=128,
                    stderr="fatal: No such remote '{}'\n".format(args[3]),
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                'branch',
                '-a',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(
                        sorted(['* ' + self.branch] + list(
                            ({default_branch} | set(self.branches)) - {
                                self.branch
                            }))) + '\nremotes/origin/HEAD -> origin/{}\n'.
                    format(default_branch),
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                'tag',
                cwd=self.path,
                generator=lambda *args, **kwargs: mocks.ProcessCompletion(
                    returncode=0,
                    stdout='\n'.join(self.tags) + '\n',
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                cwd=self.path,
                completion=mocks.ProcessCompletion(
                    returncode=1,
                    stderr='usage: git [--version] [--help]...\n',
                ),
            ),
            mocks.Subprocess.Route(
                local.Git.executable,
                completion=mocks.ProcessCompletion(
                    returncode=128,
                    stderr=
                    'fatal: not a git repository (or any parent up to mount point)\nStopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).\n',
                ),
            ),
        )