| Index: testing_support/git_test_utils.py
|
| diff --git a/testing_support/git_test_utils.py b/testing_support/git_test_utils.py
|
| index 5becad94ba58e0ece7bbcbdaa812fee034d1d0d9..bc187d40e9e947cf5c9182fd1e32c3d2bdf50df3 100644
|
| --- a/testing_support/git_test_utils.py
|
| +++ b/testing_support/git_test_utils.py
|
| @@ -10,9 +10,12 @@ import hashlib
|
| import os
|
| import shutil
|
| import subprocess
|
| +import sys
|
| import tempfile
|
| import unittest
|
|
|
| +from cStringIO import StringIO
|
| +
|
|
|
| def git_hash_data(data, typ='blob'):
|
| """Calculate the git-style SHA1 for some data.
|
| @@ -254,11 +257,13 @@ class GitRepo(object):
|
| self._date = datetime.datetime(1970, 1, 1)
|
|
|
| self.git('init')
|
| + self.git('config', 'user.name', 'testcase')
|
| + self.git('config', 'user.email', 'testcase@example.com')
|
| for commit in schema.walk():
|
| self._add_schema_commit(commit, schema.data_for(commit.name))
|
| self.last_commit = self[commit.name]
|
| if schema.master:
|
| - self.git('update-ref', 'master', self[schema.master])
|
| + self.git('update-ref', 'refs/heads/master', self[schema.master])
|
|
|
| def __getitem__(self, commit_name):
|
| """Gets the hash of a commit by its schema name.
|
| @@ -269,8 +274,8 @@ class GitRepo(object):
|
| """
|
| return self.commit_map[commit_name]
|
|
|
| - def _add_schema_commit(self, commit, data):
|
| - data = data or {}
|
| + def _add_schema_commit(self, commit, commit_data):
|
| + commit_data = commit_data or {}
|
|
|
| if commit.parents:
|
| parents = list(commit.parents)
|
| @@ -281,22 +286,9 @@ class GitRepo(object):
|
| self.git('checkout', '--orphan', 'root_%s' % commit.name)
|
| self.git('rm', '-rf', '.')
|
|
|
| - env = {}
|
| - for prefix in ('AUTHOR', 'COMMITTER'):
|
| - for suffix in ('NAME', 'EMAIL', 'DATE'):
|
| - singleton = '%s_%s' % (prefix, suffix)
|
| - key = getattr(self, singleton)
|
| - if key in data:
|
| - val = data[key]
|
| - else:
|
| - if suffix == 'DATE':
|
| - val = self._date
|
| - self._date += datetime.timedelta(days=1)
|
| - else:
|
| - val = getattr(self, 'DEFAULT_%s' % singleton)
|
| - env['GIT_%s' % singleton] = str(val)
|
| + env = self.get_git_commit_env(commit_data)
|
|
|
| - for fname, file_data in data.iteritems():
|
| + for fname, file_data in commit_data.iteritems():
|
| deleted = False
|
| if 'data' in file_data:
|
| data = file_data.get('data')
|
| @@ -324,6 +316,25 @@ class GitRepo(object):
|
| if commit.is_branch:
|
| self.git('branch', '-f', 'branch_%s' % commit.name, self[commit.name])
|
|
|
| + def get_git_commit_env(self, commit_data=None):
|
| + commit_data = commit_data or {}
|
| + env = {}
|
| + for prefix in ('AUTHOR', 'COMMITTER'):
|
| + for suffix in ('NAME', 'EMAIL', 'DATE'):
|
| + singleton = '%s_%s' % (prefix, suffix)
|
| + key = getattr(self, singleton)
|
| + if key in commit_data:
|
| + val = commit_data[key]
|
| + else:
|
| + if suffix == 'DATE':
|
| + val = self._date
|
| + self._date += datetime.timedelta(days=1)
|
| + else:
|
| + val = getattr(self, 'DEFAULT_%s' % singleton)
|
| + env['GIT_%s' % singleton] = str(val)
|
| + return env
|
| +
|
| +
|
| def git(self, *args, **kwargs):
|
| """Runs a git command specified by |args| in this repo."""
|
| assert self.repo_path is not None
|
| @@ -335,6 +346,9 @@ class GitRepo(object):
|
| except subprocess.CalledProcessError as e:
|
| return self.COMMAND_OUTPUT(e.returncode, e.output)
|
|
|
| + def git_commit(self, message):
|
| + return self.git('commit', '-am', message, env=self.get_git_commit_env())
|
| +
|
| def nuke(self):
|
| """Obliterates the git repo on disk.
|
|
|
| @@ -354,11 +368,35 @@ class GitRepo(object):
|
| finally:
|
| os.chdir(curdir)
|
|
|
| + def capture_stdio(self, fn, *args, **kwargs):
|
| + """Run a python function with the given args and kwargs with the cwd set to
|
| + the git repo.
|
| +
|
| + Returns the (stdout, stderr) of whatever ran, instead of the what |fn|
|
| + returned.
|
| + """
|
| + stdout = sys.stdout
|
| + stderr = sys.stderr
|
| + try:
|
| + sys.stdout = StringIO()
|
| + sys.stderr = StringIO()
|
| + try:
|
| + self.run(fn, *args, **kwargs)
|
| + except SystemExit:
|
| + pass
|
| + return sys.stdout.getvalue(), sys.stderr.getvalue()
|
| + finally:
|
| + sys.stdout = stdout
|
| + sys.stderr = stderr
|
| +
|
| + def open(self, path, mode='rb'):
|
| + return open(os.path.join(self.repo_path, path), mode)
|
| +
|
|
|
| class GitRepoSchemaTestBase(unittest.TestCase):
|
| """A TestCase with a built-in GitRepoSchema.
|
|
|
| - Expects a class variable REPO to be a GitRepoSchema string in the form
|
| + Expects a class variable REPO_SCHEMA to be a GitRepoSchema string in the form
|
| described by that class.
|
|
|
| You may also set class variables in the form COMMIT_%(commit_name)s, which
|
| @@ -367,7 +405,7 @@ class GitRepoSchemaTestBase(unittest.TestCase):
|
| You probably will end up using either GitRepoReadOnlyTestBase or
|
| GitRepoReadWriteTestBase for real tests.
|
| """
|
| - REPO = None
|
| + REPO_SCHEMA = None
|
|
|
| @classmethod
|
| def getRepoContent(cls, commit):
|
| @@ -376,8 +414,8 @@ class GitRepoSchemaTestBase(unittest.TestCase):
|
| @classmethod
|
| def setUpClass(cls):
|
| super(GitRepoSchemaTestBase, cls).setUpClass()
|
| - assert cls.REPO is not None
|
| - cls.r_schema = GitRepoSchema(cls.REPO, cls.getRepoContent)
|
| + assert cls.REPO_SCHEMA is not None
|
| + cls.r_schema = GitRepoSchema(cls.REPO_SCHEMA, cls.getRepoContent)
|
|
|
|
|
| class GitRepoReadOnlyTestBase(GitRepoSchemaTestBase):
|
| @@ -387,12 +425,12 @@ class GitRepoReadOnlyTestBase(GitRepoSchemaTestBase):
|
| This GitRepo will appear as self.repo, and will be deleted and recreated once
|
| for the duration of all the tests in the subclass.
|
| """
|
| - REPO = None
|
| + REPO_SCHEMA = None
|
|
|
| @classmethod
|
| def setUpClass(cls):
|
| super(GitRepoReadOnlyTestBase, cls).setUpClass()
|
| - assert cls.REPO is not None
|
| + assert cls.REPO_SCHEMA is not None
|
| cls.repo = cls.r_schema.reify()
|
|
|
| def setUp(self):
|
| @@ -411,7 +449,7 @@ class GitRepoReadWriteTestBase(GitRepoSchemaTestBase):
|
| This GitRepo will appear as self.repo, and will be deleted and recreated for
|
| each test function in the subclass.
|
| """
|
| - REPO = None
|
| + REPO_SCHEMA = None
|
|
|
| def setUp(self):
|
| super(GitRepoReadWriteTestBase, self).setUp()
|
|
|