bh@118: # Copyright (C) 2007, 2008 by Intevation GmbH bh@118: # Authors: bh@118: # Bernhard Herzog bh@118: # bh@118: # This program is free software under the GPL (>=v2) bh@118: # Read the file COPYING coming with the software for details. bh@118: bh@118: """Tests for treepkg.builder""" bh@118: bh@118: import sys bh@118: import os bh@118: import unittest bh@170: import StringIO bh@118: bh@118: from treepkg.builder import PBuilder bh@121: from treepkg.run import call bh@118: bh@118: from filesupport import FileTestMixin bh@118: bh@118: # helper program to dump the command line arguments into a file so that bh@126: # test cases can check them. Also if the environment variable bh@126: # TREEPKG_TEST is set, create the file named by it. bh@118: dump_command_line_py = """ bh@126: import sys, os bh@118: open(sys.argv[1], 'w').write(repr(sys.argv[2:])) bh@126: value = os.environ.get('TREEPKG_TEST') bh@126: if value: bh@126: open(value, 'w').close() bh@118: """ bh@118: bh@121: class PBuilderTests(unittest.TestCase, FileTestMixin): bh@118: bh@118: def setUp(self): bh@118: self.dump_command_line = self.create_temp_file("dump_command_line.py", bh@118: dump_command_line_py) bh@118: self.command_line_file = self.temp_file_name("command_line") bh@118: self.root_command = [sys.executable, self.dump_command_line, bh@118: self.command_line_file] bh@118: bh@118: def check_command_line(self, args): bh@195: self.check_file_contents(self.command_line_file, repr(args)) bh@118: bh@121: bh@121: class TestPBuilder(PBuilderTests): bh@121: bh@170: def test_init_pbuilder(self): bh@170: """Tests the PBuilder.init_pbuilder method.""" bh@185: basedir = self.create_temp_dir("pbuilder") bh@170: pbuilderrc = os.path.join(basedir, "pbuilderrc") bh@170: builder = PBuilder(pbuilderrc, self.root_command) bh@170: old_stdout = sys.stdout bh@170: sys.stdout = captured_stdout = StringIO.StringIO() bh@170: try: bh@170: builder.init_pbuilder(distribution="etch", bh@170: mirrorsite="http://example.com/debian", bh@170: extramirrors=None) bh@170: finally: bh@170: sys.stdout = old_stdout bh@170: bh@170: # check whether the necessary directories were created bh@170: missing = [dirname for dirname in ["base", "build", "result", bh@170: "aptcache", "extra-pkg"] bh@170: if not os.path.isdir(os.path.join(basedir, dirname))] bh@170: if missing: bh@170: self.fail("init_pbuilder did not create these directories: %s" bh@170: % " ".join(missing)) bh@170: bh@170: # check the pbuilderrc. This test is a little too strict bh@170: # because it checks the exact contents of the file. Instread it bh@170: # should normalize the contents in some way and check that. bh@170: pbuilderrc_contents = ( bh@170: "# This file was automatically generated by initpbuilder.py.\n" bh@170: "# for the possible settings see \"man pbuilderrc\"\n" bh@170: "\n" bh@170: "BASETGZ=%(basedir)s/base/base.tgz\n" bh@170: "BUILDPLACE=%(basedir)s/build\n" bh@170: "USEPROC=yes\n" bh@170: "USEDEVPTS=yes\n" bh@170: "BUILDRESULT=%(basedir)s/result\n" bh@170: "DISTRIBUTION=etch\n" bh@173: "APTCACHE=%(basedir)s/aptcache\n" bh@170: "APTCACHEHARDLINK=yes\n" bh@170: "REMOVEPACKAGES=lilo\n" bh@170: "MIRRORSITE=\"http://example.com/debian\"\n" bh@170: "OTHERMIRROR=\"deb file://%(basedir)s/extra-pkg ./\"\n" bh@170: "BINDMOUNTS=\"%(basedir)s/extra-pkg\"\n" bh@170: "PKGNAME_LOGFILE=yes\n" % locals()) bh@195: self.check_file_contents(pbuilderrc, pbuilderrc_contents) bh@170: bh@170: # The Packages file is empty for now. bh@195: self.check_file_contents(os.path.join(basedir, "extra-pkg", "Packages"), bh@195: "") bh@170: # check the text written to stdout. This test is a little too bh@170: # strict because it checks the exact output. bh@170: self.assertEquals(captured_stdout.getvalue(), bh@170: "creating directory: '%(basedir_repr)s/base'\n" bh@170: "creating directory: '%(basedir_repr)s/build'\n" bh@170: "creating directory: '%(basedir_repr)s/result'\n" bh@170: "creating directory: '%(basedir_repr)s/aptcache'\n" bh@170: "creating directory: '%(basedir_repr)s/extra-pkg'\n" bh@170: "creating pbuilderrc: '%(basedir_repr)s/pbuilderrc'\n" bh@170: "turning the extra-pkg dir into a debian archive\n" bh@170: "running pbuilder create\n" bh@170: % dict(basedir_repr=repr(basedir)[1:-1])) bh@170: bh@170: def test_init_pbuilder_run_twice(self): bh@170: """Tests whether PBuilder.init_pbuilder prints an error when run twice. bh@170: """ bh@185: basedir = self.create_temp_dir("pbuilder") bh@170: bh@170: # run it once bh@170: pbuilderrc = os.path.join(basedir, "pbuilderrc") bh@170: builder = PBuilder(pbuilderrc, self.root_command) bh@170: old_stdout = sys.stdout bh@170: sys.stdout = captured_stdout = StringIO.StringIO() bh@170: try: bh@170: builder.init_pbuilder(distribution="etch", bh@170: mirrorsite="http://example.com/debian", bh@170: extramirrors=None) bh@170: finally: bh@170: sys.stdout = old_stdout bh@170: bh@170: # running it again should not modify anything in the directory bh@170: # (which we don't check currently), it should print an error bh@170: # message and exit with exit code 1. bh@170: old_stderr = sys.stderr bh@170: sys.stderr = captured_stderr = StringIO.StringIO() bh@170: try: bh@170: try: bh@170: builder.init_pbuilder(distribution="etch", bh@170: mirrorsite="http://example.com/debian", bh@170: extramirrors=None) bh@170: except SystemExit, exc: bh@170: self.assertEquals(exc.code, 1) bh@170: finally: bh@170: sys.stderr = old_stderr bh@170: self.assertEquals("pbuilderrc %r already exists.\n" bh@170: % os.path.join(basedir, "pbuilderrc"), bh@170: captured_stderr.getvalue()) bh@170: bh@178: def test_update(self): bh@178: """Tests the PBuilder.update method.""" bh@178: builder = PBuilder("my_pbuilderrc", self.root_command) bh@178: builder.update() bh@178: self.check_command_line(['/usr/sbin/pbuilder', 'update', bh@178: '--configfile', 'my_pbuilderrc']) bh@170: bh@118: def test_build(self): bh@118: """Tests the PBuilder.build method. bh@118: The test checks whether the build method creates the binary_dir bh@118: and then checks the arguments with which the root command is bh@118: called. The test is a little too strict because it expects a bh@118: specific order of the arguments even though the order of some of bh@118: the arguments doesn't matter. bh@118: bh@118: A more thorough test of the build method is implicity done by bh@118: the packager tests. bh@118: """ bh@118: binary_dir_name = self.temp_file_name("binary") bh@118: if os.path.exists(binary_dir_name): bh@118: os.rmdir(binary_dir_name) bh@118: # sanity check: the binary directory must not exist yet. bh@118: self.failIf(os.path.exists(binary_dir_name)) bh@118: bh@186: logfilename = self.temp_file_name("the_logfile") bh@186: bh@118: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.build("my_dsc_file", binary_dir_name, logfilename) bh@118: self.check_command_line(['/usr/sbin/pbuilder', 'build', bh@118: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, bh@118: '--buildresult', binary_dir_name, bh@171: '--debbuildopts', '-b', bh@118: 'my_dsc_file']) bh@118: self.failUnless(os.path.isdir(binary_dir_name)) bh@119: bh@122: def test_build_with_bindmounts(self): bh@122: """Tests the PBuilder.build method with the bindmounts parameter""" bh@122: binary_dir_name = self.temp_file_name("binary") bh@122: if os.path.exists(binary_dir_name): bh@122: os.rmdir(binary_dir_name) bh@122: # sanity check: the binary directory must not exist yet. bh@122: self.failIf(os.path.exists(binary_dir_name)) bh@122: bh@186: logfilename = self.temp_file_name("the_logfile") bh@186: bh@122: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.build("my_dsc_file", binary_dir_name, logfilename, bh@122: bindmounts=["/home/builder/tracks", bh@122: "/home/builder/pbuilder"]) bh@122: self.check_command_line(['/usr/sbin/pbuilder', 'build', bh@122: '--configfile', 'my_pbuilderrc', bh@209: '--logfile', logfilename, bh@209: '--buildresult', binary_dir_name, bh@122: '--bindmounts', "/home/builder/tracks", bh@122: '--bindmounts', "/home/builder/pbuilder", bh@171: '--debbuildopts', '-b', bh@122: 'my_dsc_file']) bh@122: self.failUnless(os.path.isdir(binary_dir_name)) bh@122: bh@122: def test_build_with_extra_packages(self): bh@122: """Tests the PBuilder.build method with the extra_packages parameter""" bh@122: binary_dir_name = self.temp_file_name("binary") bh@122: if os.path.exists(binary_dir_name): bh@122: os.rmdir(binary_dir_name) bh@122: # sanity check: the binary directory must not exist yet. bh@122: self.failIf(os.path.exists(binary_dir_name)) bh@122: bh@186: logfilename = self.temp_file_name("the_logfile") bh@186: bh@122: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.build("my_dsc_file", binary_dir_name, logfilename, bh@122: extra_packages=["subversion", "texinfo"]) bh@122: self.check_command_line(['/usr/sbin/pbuilder', 'build', bh@122: '--configfile', 'my_pbuilderrc', bh@209: '--logfile', logfilename, bh@209: '--buildresult', binary_dir_name, bh@122: '--extrapackages', "subversion", bh@122: '--extrapackages', "texinfo", bh@171: '--debbuildopts', '-b', bh@122: 'my_dsc_file']) bh@122: self.failUnless(os.path.isdir(binary_dir_name)) bh@122: bh@126: def test_build_with_extra_env(self): bh@126: """Tests the PBuilder.build method with the extra_env parameter""" bh@126: binary_dir_name = self.temp_file_name("binary") bh@126: if os.path.exists(binary_dir_name): bh@126: os.rmdir(binary_dir_name) bh@185: env_test_file = self.temp_file_name("envtest") bh@126: # sanity check: the binary directory must not exist yet. bh@126: self.failIf(os.path.exists(binary_dir_name)) bh@126: # sanity check: the environment variable TREEPKG_TEST must not bh@126: # be set yet bh@126: self.failIf("TREEPKG_TEST" in os.environ) bh@126: bh@186: logfilename = self.temp_file_name("the_logfile") bh@186: bh@126: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.build("my_dsc_file", binary_dir_name, logfilename, bh@126: extra_env=dict(TREEPKG_TEST=env_test_file)) bh@126: self.check_command_line(['/usr/sbin/pbuilder', 'build', bh@126: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, bh@126: '--buildresult', binary_dir_name, bh@171: '--debbuildopts', '-b', bh@126: 'my_dsc_file']) bh@126: self.failUnless(os.path.isdir(binary_dir_name)) bh@126: self.failUnless(os.path.exists(env_test_file)) bh@126: bh@119: def test_run_script(self): bh@186: logfilename = self.temp_file_name("the_logfile") bh@119: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.run_script(["my_script"], logfile=logfilename) bh@119: self.check_command_line(['/usr/sbin/pbuilder', 'execute', bh@119: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, '--', bh@119: 'my_script']) bh@119: bh@181: def test_run_script_with_arguments(self): bh@186: logfilename = self.temp_file_name("the_logfile") bh@181: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.run_script(["my_script", "--verbose"], logfile=logfilename) bh@181: self.check_command_line(['/usr/sbin/pbuilder', 'execute', bh@181: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, '--', bh@181: 'my_script', '--verbose']) bh@181: bh@119: def test_run_script_with_bindmounts(self): bh@186: logfilename = self.temp_file_name("the_logfile") bh@119: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.run_script(["my_script"], logfile=logfilename, bh@119: bindmounts=("/home/builder/foo", bh@119: "/home/builder/treepkg")) bh@119: self.check_command_line(['/usr/sbin/pbuilder', 'execute', bh@119: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, bh@119: '--bindmounts', '/home/builder/foo', bh@119: '--bindmounts', '/home/builder/treepkg', bh@183: '--', 'my_script']) bh@183: bh@183: def test_run_script_save_after_exec(self): bh@186: logfilename = self.temp_file_name("the_logfile") bh@183: builder = PBuilder("my_pbuilderrc", self.root_command) bh@186: builder.run_script(["my_script", "--verbose"], logfilename, bh@183: save_after_exec=True) bh@183: self.check_command_line(['/usr/sbin/pbuilder', 'execute', bh@183: '--configfile', 'my_pbuilderrc', bh@186: '--logfile', logfilename, bh@183: '--save-after-exec', '--', bh@183: 'my_script', '--verbose']) bh@121: bh@121: bh@121: class TestPBuilderWithBinaryPackage(PBuilderTests): bh@121: bh@121: minimal_package = [ bh@121: ("debian", bh@121: [("control", """\ bh@121: Source: minimal bh@121: Section: utils bh@121: Priority: optional bh@121: Maintainer: Bernhard Herzog bh@121: Standards-Version: 3.7.2.2 bh@121: Build-Depends: debhelper bh@121: bh@121: Package: minimal bh@121: Architecture: any bh@121: Depends: ${shlibs:Depends} bh@121: Description: Minimal package for test purposes bh@121: """), bh@121: ("rules", 0755, """\ bh@121: #!/usr/bin/make -f bh@121: bh@121: build: build-stamp bh@121: build-stamp: bh@121: dh_testdir bh@121: touch build-stamp bh@121: bh@121: clean: bh@121: dh_testdir bh@121: dh_testroot bh@121: rm -f build-stamp bh@121: dh_clean bh@121: bh@121: # Build architecture-dependent files here. bh@121: binary-arch: bh@121: dh_testdir bh@121: dh_testroot bh@121: dh_installdocs README bh@121: dh_installchangelogs bh@121: dh_fixperms bh@121: dh_installdeb bh@121: dh_gencontrol bh@121: dh_md5sums bh@121: dh_builddeb bh@121: bh@121: binary: binary-arch bh@121: .PHONY: build build-stamp clean binary-arch binary bh@121: """), bh@121: ("changelog", """\ bh@121: minimal (1.0-1) unstable; urgency=low bh@121: bh@121: * Newly packaged bh@121: bh@121: -- Bernhard Herzog Wed, 21 May 2008 16:10:29 +0200 bh@121: """)]), bh@121: ("README", """\ bh@121: This is a minimal debian package for test purposes bh@121: """), bh@121: ] bh@121: bh@121: pbuilder_files = [("pbuilderrc", ""), bh@121: ("extra-pkg", [])] bh@121: bh@121: def setUp(self): bh@121: PBuilderTests.setUp(self) bh@185: self.temp_base_dir = self.create_temp_dir("pbuilder") bh@121: self.minimal_packge_dir = os.path.join(self.temp_base_dir, bh@121: "minimal-1.0") bh@121: self.create_files(self.minimal_packge_dir, self.minimal_package) bh@121: call(["dpkg-buildpackage", "-rfakeroot", "-b", "-uc"], bh@121: cwd=self.minimal_packge_dir, suppress_output=True) bh@121: self.minimal_package_deb = os.path.join(self.temp_base_dir, bh@121: "minimal_1.0-1_i386.deb") bh@121: self.pbuilder_basedir = os.path.join(self.temp_base_dir, "pbuilder") bh@121: self.create_files(self.pbuilder_basedir, self.pbuilder_files) bh@121: self.extra_pkg_dir = os.path.join(self.pbuilder_basedir, "extra-pkg") bh@121: self.pbuilderrc = os.path.join(self.pbuilder_basedir, "pbuilderrc") bh@121: bh@121: def test_add_binaries_to_extra_pkg(self): bh@121: """Tests the PBuilder.add_binaries_to_extra_pkg method""" bh@121: builder = PBuilder(self.pbuilderrc, self.root_command) bh@121: # sanity check: the extra-pkg directory should be empty now bh@121: self.assertEquals(os.listdir(self.extra_pkg_dir), []) bh@121: bh@121: builder.add_binaries_to_extra_pkg([self.minimal_package_deb]) bh@121: bh@121: self.assertEquals(sorted(os.listdir(self.extra_pkg_dir)), bh@176: ["Packages", "Release", "minimal_1.0-1_i386.deb"]) bh@121: self.check_command_line(['/usr/sbin/pbuilder', 'update', bh@121: '--configfile', self.pbuilderrc])