1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
|
# vim: set fileencoding=utf-8 :
#
# (C) 2015-2017 Guido Günther <agx@sigxcpu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, please see
# <http://www.gnu.org/licenses/>
import glob
import hashlib
import os
import subprocess
import tarfile
from tests.component import (ComponentTestBase,
ComponentTestGitRepository)
from tests.component.deb import DEB_TEST_DATA_DIR
from tests.component.deb.fixtures import (RepoFixtures,
DEFAULT_OVERLAY)
from tests.testutils import skip_without_cmd
from gbp.scripts.import_dsc import main as import_dsc
from gbp.scripts.buildpackage import main as buildpackage
from gbp.scripts.pq import main as pq
from gbp.deb.changelog import ChangeLog
class TestBuildpackage(ComponentTestBase):
"""Test building a debian package"""
@staticmethod
def _dsc_name(pkg, version, dir):
return os.path.join(DEB_TEST_DATA_DIR,
dir,
'%s_%s.dsc' % (pkg, version))
def _test_buildpackage(self, repo, opts=[]):
prebuild_out = os.path.join(repo.path, '..', 'prebuild.out')
postbuild_out = os.path.join(repo.path, '..', 'postbuild.out')
args = ['arg0',
'--git-prebuild=printenv > %s' % prebuild_out,
'--git-postbuild=printenv > %s' % postbuild_out,
'--git-builder=/bin/true',
'--git-cleaner=/bin/true'] + opts
os.chdir(repo.path)
ret = buildpackage(args)
assert ret == 0, "Building the package failed"
assert os.path.exists(prebuild_out) is True
assert os.path.exists(postbuild_out) is True
self.check_hook_vars('../prebuild', ["GBP_BUILD_DIR",
"GBP_GIT_DIR",
"GBP_BUILD_DIR"])
self.check_hook_vars('../postbuild', ["GBP_CHANGES_FILE",
"GBP_BUILD_DIR",
"GBP_CHANGES_FILE",
"GBP_BUILD_DIR"])
@RepoFixtures.native()
def test_debian_buildpackage(self, repo):
"""Test that building a native debian package works"""
self._test_buildpackage(repo)
@RepoFixtures.quilt30()
def test_non_native_buildpackage(self, repo):
"""Test that building a source 3.0 debian package works"""
self._test_buildpackage(repo)
@RepoFixtures.native()
def test_tag_only(self, repo):
"""Test that only tagging a native debian package works"""
repo.delete_tag('debian/0.4.14') # make sure we can tag again
ret = buildpackage(['arg0',
'--git-tag-only',
'--git-posttag=printenv > ../posttag.out',
'--git-builder=touch ../builder-run.stamp',
'--git-cleaner=/bin/true'])
assert ret == 0, "Building the package failed"
assert os.path.exists("../posttag.out") is True
assert os.path.exists("../builder-run.stamp") is False
self.check_hook_vars(
"../posttag", [("GBP_TAG", "debian/0.4.14"), ("GBP_BRANCH", "master"), "GBP_SHA1"]
)
def test_component_generation(self):
"""Test that generating tarball and additional tarball works without pristine-tar"""
pkg = 'hello-debhelper'
dsc = self._dsc_name(pkg, '2.8-1', 'dsc-3.0-additional-tarballs')
tarballs = ["../%s_2.8.orig-foo.tar.gz" % pkg,
"../%s_2.8.orig.tar.gz" % pkg]
assert import_dsc(['arg0', '--no-pristine-tar', dsc]) == 0
repo = ComponentTestGitRepository(pkg)
os.chdir(pkg)
assert not repo.has_branch("pristine-tar"), "Pristine-tar branch must not exist"
for t in tarballs:
self.assertFalse(os.path.exists(t), "Tarball %s must not exist" % t)
ret = buildpackage(['arg0',
'--git-component=foo',
'--git-no-pristine-tar',
'--git-posttag=printenv > posttag.out',
'--git-builder=touch builder-run.stamp',
'--git-cleaner=/bin/true'])
assert ret == 0, "Building the package failed"
for t in tarballs:
self.assertTrue(os.path.exists(t), "Tarball %s not found" % t)
def test_pristinetar_component_generation(self):
"""Test that generating tarball and additional tarball works with pristine-tar"""
pkg = 'hello-debhelper'
dsc = self._dsc_name(pkg, '2.8-1', 'dsc-3.0-additional-tarballs')
tarballs = ["../%s_2.8.orig-foo.tar.gz" % pkg,
"../%s_2.8.orig.tar.gz" % pkg]
assert import_dsc(['arg0', '--pristine-tar', dsc]) == 0
repo = ComponentTestGitRepository(pkg)
os.chdir(pkg)
assert repo.has_branch("pristine-tar"), "Pristine-tar branch must exist"
for t in tarballs:
self.assertFalse(os.path.exists(t), "Tarball %s must not exist" % t)
# Make sure the tree object for importing the main tarball is recreated
repo.collect_garbage(prune='all', aggressive=True)
ret = buildpackage(['arg0',
'--git-component=foo',
'--git-pristine-tar',
'--git-posttag=printenv > posttag.out',
'--git-builder=touch builder-run.stamp',
'--git-cleaner=/bin/true'])
assert ret == 0, "Building the package failed"
for t in tarballs:
self.assertTrue(os.path.exists(t), "Tarball %s not found" % t)
@RepoFixtures.quilt30()
def test_pristine_tar_commit(self, repo):
"""Test that committing to pristine-tar branch after building tarballs works"""
assert not repo.has_branch("pristine-tar"), "Pristine-tar branch must not exist"
ret = buildpackage(["arg0", "--git-builder=/bin/true", "--git-pristine-tar-commit"])
assert ret == 0, "Building the package failed"
assert repo.has_branch("pristine-tar"), "Pristine-tar branch must exist"
assert repo.ls_tree("pristine-tar") == {
b"hello-debhelper_2.8.orig.tar.gz.id",
b"hello-debhelper_2.8.orig.tar.gz.delta",
}
@RepoFixtures.quilt30()
def test_sloppy_tarball_generation(self, repo):
"""Test that generating tarball from Debian branch works"""
tarball = '../hello-debhelper_2.8.orig.tar.gz'
self.add_file(repo, 'foo.txt')
self._test_buildpackage(repo, ['--git-force-create',
'--git-upstream-tree=SLOPPY'])
self.assertTrue(os.path.exists(tarball))
t = tarfile.open(name=tarball, mode="r:gz")
names = t.getnames()
for f in ['hello-debhelper-2.8/build-aux',
'hello-debhelper-2.8/foo.txt']:
self.assertIn(f, names)
self.assertNotIn('hello-debhelper-2.8/debian', names)
@RepoFixtures.quilt30()
def test_export_dir_buildpackage(self, repo):
"""Test that building with a export dir works"""
self._test_buildpackage(repo, ["--git-export-dir=../foo/bar"])
assert os.path.exists("../foo/bar")
@RepoFixtures.quilt30_additional_tarball()
def test_export_dir_additional_tar(self, repo):
"""Test that building with a export dir and additional tarball works"""
self._test_buildpackage(repo, ['--git-export-dir=../foo/bar',
'--git-no-purge',
'--git-component=foo'])
# Check that all needed tarballs end up in the build-area
assert sorted(glob.glob("../foo/bar/*")) == [
"../foo/bar/hello-debhelper-2.8",
"../foo/bar/hello-debhelper_2.8.orig-foo.tar.gz",
"../foo/bar/hello-debhelper_2.8.orig.tar.gz",
]
# Check that directories from additional tarballs get exported too
assert os.path.exists("../foo/bar/hello-debhelper-2.8/foo")
@RepoFixtures.overlay()
def test_export_dir_overlay(self, repo):
"""Test that building in overlay mode with export dir works"""
tarball_dir = os.path.dirname(DEFAULT_OVERLAY)
self._test_buildpackage(repo, ['--git-overlay',
'--git-compression=auto',
'--git-tarball-dir=%s' % tarball_dir,
'--git-no-purge',
'--git-component=foo',
'--git-export-dir=../overlay'])
# Check if main tarball got unpacked
assert os.path.exists("../overlay/hello-debhelper-2.8/configure")
# Check if debian dir is there
assert os.path.exists("../overlay/hello-debhelper-2.8/debian/changelog")
# Check if additional tarball got unpacked
assert os.path.exists("../overlay/hello-debhelper-2.8/foo/test1")
# Check if upstream tarballs is in export_dir
assert sorted(glob.glob("../overlay/*")) == [
"../overlay/hello-debhelper-2.8",
"../overlay/hello-debhelper_2.8.orig-foo.tar.gz",
"../overlay/hello-debhelper_2.8.orig.tar.gz",
]
@RepoFixtures.quilt30()
def test_export_wc_buildpackage(self, repo):
"""Test that exporting working copy works and it ignores
modifications the source tree """
with open(os.path.join(repo.path, 'foo.txt'), 'w') as f:
f.write("foo")
self._test_buildpackage(repo, ["--git-export=WC", "--git-export-dir=../foo/bar"])
assert os.path.exists("../foo/bar")
@RepoFixtures.native()
def test_argument_quoting(self, repo):
"""Test that we quote arguments to builder (#850869)"""
with open('../arg with spaces', 'w'):
pass
# We use ls as builder to look for a file with spaces. This
# will fail if build arguments are not properly quoted and
# therefore split up
ret = buildpackage(['arg0',
'--git-builder=ls',
'--git-cleaner=/bin/true',
'../arg with spaces'])
assert ret == 0, "Building the package failed"
@RepoFixtures.quilt30()
def test_tarball_default_compression(self, repo):
"""Test that we use defaults for compression if not given (#820846)"""
self._test_buildpackage(repo, ['--git-no-pristine-tar'])
tarball = "../hello-debhelper_2.8.orig.tar.gz"
out = subprocess.check_output(["file", tarball])
assert b"max compression" not in out
m1 = hashlib.md5(open(tarball, 'rb').read()).hexdigest()
os.unlink(tarball)
assert (
buildpackage(
[
"arg0",
"--git-ignore-new",
"--git-builder=/bin/true",
"--git-cleaner=/bin/true",
"../arg with spaces",
]
) == 0
)
m2 = hashlib.md5(open(tarball, "rb").read()).hexdigest()
assert m1 == m2, "Regenerated tarball has different checksum"
@RepoFixtures.quilt30()
def test_tarball_max_compression(self, repo):
"""Test that passing max compression works (#820846)"""
self._test_buildpackage(repo, ['--git-no-pristine-tar', '--git-compression-level=9'])
out = subprocess.check_output(["file", "../hello-debhelper_2.8.orig.tar.gz"])
assert b"max compression" in out
@RepoFixtures.quilt30()
def test_tag_pq_branch(self, repo):
ret = pq(["argv0", "import"])
assert repo.rev_parse("master") == repo.rev_parse("debian/2.8-1^{}")
assert ret == 0
assert repo.branch == "patch-queue/master"
self.add_file(repo, "foo.txt")
ret = buildpackage(["argv0", "--git-tag-only", "--git-retag", "--git-ignore-branch"])
assert ret == 0
assert repo.branch == "patch-queue/master"
assert repo.rev_parse("patch-queue/master^{}^") == repo.rev_parse("debian/2.8-1^{}")
@RepoFixtures.quilt30()
def test_tag_detached_head(self, repo):
"""
Test that tagging works with an detached head (#863167)
"""
assert repo.rev_parse("master^{}") == repo.rev_parse("debian/2.8-1^{}")
self.add_file(repo, "debian/foo.txt")
repo.checkout("HEAD~")
ret = buildpackage(['argv0',
'--git-tag-only',
'--git-retag',
'--git-ignore-branch'])
assert ret == 0
repo.checkout("master")
assert repo.rev_parse("master~^{}") == repo.rev_parse("debian/2.8-1^{}")
@skip_without_cmd('debchange')
@RepoFixtures.quilt30()
def test_broken_upstream_version(self, repo):
cl = ChangeLog(filename='debian/changelog')
cl.add_section(["broken versionnumber"],
"unstable",
version={'version': "3.0"})
ret = buildpackage(['argv0',
'--git-ignore-new',
'--git-builder=/bin/true',
'--git-tarball-dir=../tarballs'])
assert ret == 1
self._check_log(-1, "gbp:error: Non-native package 'hello-debhelper' has invalid version '3.0'")
@RepoFixtures.quilt30()
def test_preexport(self, repo):
"""Test the pre-export hook """
preexport_out = os.path.join(repo.path, '..', 'preexport.out')
self._test_buildpackage(repo, ['--git-export-dir=../export-dir',
'--git-preexport=printenv > %s' % preexport_out])
assert os.path.exists(preexport_out)
self.check_hook_vars('../preexport', ["GBP_BUILD_DIR", "GBP_GIT_DIR"])
@RepoFixtures.overlay()
def test_export_dir_version_replacement(self, repo):
"""Test that building in overlay mode with export dir with versioned name works"""
tarball_dir = os.path.join(DEB_TEST_DATA_DIR, 'foo-%(version)s')
self._test_buildpackage(repo, ['--git-overlay',
'--git-compression=auto',
'--git-tarball-dir=%s' % tarball_dir,
'--git-no-purge',
'--git-component=foo',
'--git-export-dir=../foo'])
# Check if main tarball got unpacked
assert os.path.exists("../foo/hello-debhelper-2.8/configure")
# Check if debian dir is there
assert os.path.exists("../foo/hello-debhelper-2.8/debian/changelog")
# Check if additional tarball got unpacked
assert os.path.exists("../foo/hello-debhelper-2.8/foo/test1")
# Check if upstream tarballs is in export_dir
assert sorted(glob.glob("../foo/*")) == [
"../foo/hello-debhelper-2.8",
"../foo/hello-debhelper_2.8.orig-foo.tar.gz",
"../foo/hello-debhelper_2.8.orig.tar.gz",
]
|