__init__.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. # vim: set fileencoding=utf-8 :
  2. #
  3. # (C) 2012 Intel Corporation <markus.lehtonen@linux.intel.com>
  4. # 2013 Guido Günther <agx@sigxcpu.org>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, please see
  18. # <http://www.gnu.org/licenses/>
  19. """
  20. Module for testing individual command line tools of the git-buildpackage suite
  21. """
  22. import os
  23. import shutil
  24. import tempfile
  25. import unittest
  26. from nose import SkipTest
  27. from nose.tools import eq_, ok_ # pylint: disable=E0611
  28. from .. testutils import GbpLogTester
  29. from gbp.git import GitRepository, GitRepositoryError
  30. class ComponentTestGitRepository(GitRepository):
  31. """Git repository class for component tests"""
  32. def submodule_status(self):
  33. """
  34. Determine submodules and their status
  35. """
  36. out, err, ret = self._git_inout('submodule', ['status'],
  37. capture_stderr=True)
  38. if ret:
  39. raise GitRepositoryError("Cannot get submodule status: %s" %
  40. err.strip())
  41. submodules = {}
  42. for line in out.splitlines():
  43. module = line.strip()
  44. # Uninitialized
  45. status = module[0]
  46. if status == '-':
  47. sha1, path = module[1:].rsplit(' ', 1)
  48. else:
  49. commitpath = module[1:].rsplit(' ', 1)[0]
  50. sha1, path = commitpath.split(' ', 1)
  51. submodules[path] = (status, sha1)
  52. return submodules
  53. @classmethod
  54. def check_testdata(cls, data):
  55. """Check whether the testdata is current"""
  56. try:
  57. repo = cls('.')
  58. except GitRepositoryError:
  59. raise SkipTest("Skipping '%s', since this is not a git checkout."
  60. % __name__)
  61. submodules = repo.submodule_status()
  62. try:
  63. status = submodules[data]
  64. except KeyError:
  65. raise SkipTest("Skipping '%s', testdata directory not a known "
  66. "submodule." % __name__)
  67. if status[0] == '-':
  68. raise SkipTest("Skipping '%s', testdata directory not initialized. "
  69. "Consider doing 'git submodule update'" % __name__)
  70. def ls_tree(self, treeish):
  71. """List contents (blobs) in a git treeish"""
  72. objs = self.list_tree(treeish, True)
  73. blobs = [obj[3] for obj in objs if obj[1] == 'blob']
  74. return set(blobs)
  75. class ComponentTestBase(unittest.TestCase, GbpLogTester):
  76. """Base class for testing cmdline tools of git-buildpackage"""
  77. @classmethod
  78. def setUpClass(cls):
  79. """Test class case setup"""
  80. # Don't let git see that we're (possibly) under a git directory
  81. cls.orig_env = os.environ.copy()
  82. os.environ['GIT_CEILING_DIRECTORIES'] = os.getcwd()
  83. # Create a top-level tmpdir for the test
  84. cls._tmproot = tempfile.mkdtemp(prefix='gbp_%s_' % cls.__name__,
  85. dir='.')
  86. cls._tmproot = os.path.abspath(cls._tmproot)
  87. # Prevent local config files from messing up the tests
  88. os.environ['GBP_CONF_FILES'] = ':'.join(['%(top_dir)s/.gbp.conf',
  89. '%(top_dir)s/debian/gbp.conf',
  90. '%(git_dir)s/gbp.conf'])
  91. @classmethod
  92. def tearDownClass(cls):
  93. """Test class case teardown"""
  94. # Return original environment
  95. os.environ.clear()
  96. os.environ.update(cls.orig_env)
  97. # Remove top-level tmpdir
  98. if not os.getenv("GBP_TESTS_NOCLEAN"):
  99. shutil.rmtree(cls._tmproot)
  100. def __init__(self, methodName='runTest'):
  101. """Object initialization"""
  102. self._orig_dir = None
  103. self._tmpdir = None
  104. unittest.TestCase.__init__(self, methodName)
  105. GbpLogTester.__init__(self)
  106. def setUp(self):
  107. """Test case setup"""
  108. # Change to a temporary directory
  109. self._orig_dir = os.getcwd()
  110. self._tmpdir = tempfile.mkdtemp(prefix='tmp_%s_' % self._testMethodName,
  111. dir=self._tmproot)
  112. os.chdir(self._tmpdir)
  113. self._capture_log(True)
  114. def tearDown(self):
  115. """Test case teardown"""
  116. # Restore original working dir
  117. os.chdir(self._orig_dir)
  118. if not os.getenv("GBP_TESTS_NOCLEAN"):
  119. shutil.rmtree(self._tmpdir)
  120. self._capture_log(False)
  121. @staticmethod
  122. def check_files(reference, filelist):
  123. """Compare two file lists"""
  124. extra = set(filelist) - set(reference)
  125. missing = set(reference) - set(filelist)
  126. assert_msg = "Unexpected files: %s, Missing files: %s" % \
  127. (list(extra), list(missing))
  128. assert not extra and not missing, assert_msg
  129. @classmethod
  130. def check_tags(cls, repo, tags):
  131. local_tags = repo.tags
  132. assert_msg = "Tags: expected %s, found %s" % (tags,
  133. local_tags)
  134. eq_(set(local_tags), set(tags), assert_msg)
  135. @classmethod
  136. def _check_repo_state(cls, repo, current_branch, branches, files=None,
  137. dirs=None, tags=None):
  138. """
  139. Check that repository is clean and given branches, tags, files
  140. and dirs exist
  141. """
  142. branch = repo.branch
  143. eq_(branch, current_branch)
  144. ok_(repo.is_clean())
  145. local_branches = repo.get_local_branches()
  146. assert_msg = "Branches: expected %s, found %s" % (branches,
  147. local_branches)
  148. eq_(set(local_branches), set(branches), assert_msg)
  149. if files is not None or dirs is not None:
  150. # Get files of the working copy recursively
  151. local_f = set()
  152. local_d = set()
  153. for dirpath, dirnames, filenames in os.walk(repo.path):
  154. # Skip git dir(s)
  155. if '.git' in dirnames:
  156. dirnames.remove('.git')
  157. for filename in filenames:
  158. local_f.add(os.path.relpath(os.path.join(dirpath, filename),
  159. repo.path))
  160. for dirname in dirnames:
  161. local_d.add(os.path.relpath(os.path.join(dirpath, dirname),
  162. repo.path) + '/')
  163. if files is not None:
  164. cls.check_files(files, local_f)
  165. if dirs is not None:
  166. cls.check_files(dirs, local_d)
  167. if tags is not None:
  168. cls.check_tags(repo, tags)
  169. @classmethod
  170. def rem_refs(cls, repo, refs):
  171. """Remember the SHA1 of the given refs"""
  172. rem = []
  173. for name in refs:
  174. rem.append((name, repo.rev_parse(name)))
  175. return rem
  176. @classmethod
  177. def check_refs(cls, repo, rem):
  178. """
  179. Check that the heads given n (head, sha1) tuples are
  180. still pointing to the given sha1
  181. """
  182. for (h, s) in rem:
  183. n = repo.rev_parse(h)
  184. ok_(n == s, "Head '%s' points to %s' instead of '%s'" % (h, n, s))