view test/test_builder.py @ 440:383d23c6bfde

Merged revisions 346-386 via svnmerge from svn+ssh://svn.wald.intevation.org/treepkg/branches/treepkg-status ........ r346 | bricks | 2010-07-07 17:40:48 +0200 (Mi, 07 Jul 2010) | 2 lines added classed for treepkg status xml generation ........ r347 | bricks | 2010-07-08 12:07:39 +0200 (Do, 08 Jul 2010) | 10 lines renamed new status dir to info because of a naming conflict with status.py let the user specify a treepkg name in the config the name is propagated to PackagerGroup [treepkg] name: <treepkgname> becomes: pg = PackagerGroup(...) pg.name ........ r348 | bricks | 2010-07-08 15:25:07 +0200 (Do, 08 Jul 2010) | 3 lines moved test file to test main dir fixed missing : after def statement ........ r349 | bricks | 2010-07-08 17:59:52 +0200 (Do, 08 Jul 2010) | 2 lines added treepkg_dir andd tracks_dir attributes to PackageGroup ........ r350 | bricks | 2010-07-08 18:00:32 +0200 (Do, 08 Jul 2010) | 2 lines changed <millpath> to <trackspath> ........ r351 | bricks | 2010-07-08 18:08:39 +0200 (Do, 08 Jul 2010) | 2 lines check if config file exists to get usefull error output ........ r352 | bricks | 2010-07-08 18:11:13 +0200 (Do, 08 Jul 2010) | 2 lines write first info about tracks ........ r353 | bricks | 2010-07-09 12:20:49 +0200 (Fr, 09 Jul 2010) | 2 lines get all log files ........ r354 | bricks | 2010-07-09 14:42:42 +0200 (Fr, 09 Jul 2010) | 2 lines added md5sum function ........ r355 | bricks | 2010-07-09 15:15:15 +0200 (Fr, 09 Jul 2010) | 4 lines implemented nearly all info only arch and os info are missing ........ r356 | bricks | 2010-07-09 16:19:17 +0200 (Fr, 09 Jul 2010) | 2 lines Bugfix: source was not defined ........ r357 | bricks | 2010-07-09 16:44:52 +0200 (Fr, 09 Jul 2010) | 3 lines fixed some typos added missing add_checksum methond ........ r358 | bricks | 2010-07-09 17:06:15 +0200 (Fr, 09 Jul 2010) | 2 lines fixed status line for revision ........ r359 | bricks | 2010-07-12 14:10:34 +0200 (Mo, 12 Jul 2010) | 2 lines let the user specify num revisions that should be shown in the info ........ r360 | bricks | 2010-07-12 14:21:39 +0200 (Mo, 12 Jul 2010) | 2 lines missed in last commit ........ r361 | bricks | 2010-07-12 17:06:22 +0200 (Mo, 12 Jul 2010) | 2 lines add os config statement ........ r362 | bricks | 2010-07-12 17:47:42 +0200 (Mo, 12 Jul 2010) | 3 lines moved packages and logs to revision tag implemented os and arch info ........ r363 | bricks | 2010-07-13 14:23:28 +0200 (Di, 13 Jul 2010) | 2 lines updated test readconfig for os config variable ........ r364 | bricks | 2010-07-13 14:24:14 +0200 (Di, 13 Jul 2010) | 2 lines moved common publish functions to a seperate module ........ r365 | bricks | 2010-07-13 16:26:11 +0200 (Di, 13 Jul 2010) | 2 lines moved arch info to each package info ........ r366 | bricks | 2010-07-13 18:46:17 +0200 (Di, 13 Jul 2010) | 2 lines inital checkin for new publishpackages processing ........ r367 | bricks | 2010-07-21 17:52:15 +0200 (Mi, 21 Jul 2010) | 2 lines implemented parsing from xml string ........ r368 | bricks | 2010-07-22 12:17:42 +0200 (Do, 22 Jul 2010) | 2 lines copy binary-all packages in all binary-xyz dirs ........ r369 | bricks | 2010-07-22 12:26:40 +0200 (Do, 22 Jul 2010) | 2 lines fixed small bugs ........ r370 | bricks | 2010-07-22 13:02:36 +0200 (Do, 22 Jul 2010) | 2 lines added a new root element which is called TreepkgRoot for Treepkg Info classes ........ r371 | bricks | 2010-07-22 13:09:52 +0200 (Do, 22 Jul 2010) | 3 lines fixed some small issues remember: run pychecker BEFORE the commit ........ r372 | bricks | 2010-07-22 18:01:43 +0200 (Do, 22 Jul 2010) | 2 lines improved publishdebianpackages and fixed a lot of bugs in the xml info parsing part ........ r373 | bricks | 2010-07-23 18:40:38 +0200 (Fr, 23 Jul 2010) | 2 lines implemented CacheDb to store copied Packages from build host ........ r374 | bricks | 2010-07-26 10:28:48 +0200 (Mo, 26 Jul 2010) | 2 lines moved data handling in publishdebianpackages into seperate module ........ r375 | bricks | 2010-07-26 11:42:07 +0200 (Mo, 26 Jul 2010) | 2 lines fixed some typos ........ r376 | bricks | 2010-07-26 12:12:40 +0200 (Mo, 26 Jul 2010) | 2 lines first version of incremental copying debian packages to cachedir ........ r377 | bricks | 2010-07-26 14:58:50 +0200 (Mo, 26 Jul 2010) | 2 lines incremental copying only changed debian packages ........ r378 | bricks | 2010-07-26 15:39:10 +0200 (Mo, 26 Jul 2010) | 3 lines use md5 instead of hashlib module (md5 is deprecated in favour of hashlib in python 2.5) ........ r379 | bricks | 2010-07-26 15:46:19 +0200 (Mo, 26 Jul 2010) | 2 lines make treepkg compatible to python 2.4 ........ r380 | bricks | 2010-07-26 15:50:49 +0200 (Mo, 26 Jul 2010) | 2 lines fixed last commit (db instead of sqlite3) ........ r381 | bricks | 2010-07-27 10:54:15 +0200 (Di, 27 Jul 2010) | 2 lines fixed wrong import statement ........ r382 | bricks | 2010-07-27 10:54:34 +0200 (Di, 27 Jul 2010) | 2 lines removed unnecessary debug output ........ r383 | bricks | 2010-07-27 18:28:22 +0200 (Di, 27 Jul 2010) | 2 lines check if upload hook is empty ........ r384 | bricks | 2010-07-28 09:35:21 +0200 (Mi, 28 Jul 2010) | 2 lines run rsync only an arch dirs that are present in the current treepkg ........ r385 | bricks | 2010-07-28 09:35:54 +0200 (Mi, 28 Jul 2010) | 2 lines add helper tool to list content of a cache db ........ r386 | bricks | 2010-07-28 10:33:48 +0200 (Mi, 28 Jul 2010) | 3 lines fixed a typo regex fails if option is empty ........
author Bjoern Ricks <bricks@intevation.de>
date Fri, 06 Aug 2010 13:28:47 +0000
parents f06f707d9fda
children
line wrap: on
line source
# Copyright (C) 2007, 2008, 2009 by Intevation GmbH
# Authors:
# Bernhard Herzog <bh@intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with the software for details.

"""Tests for treepkg.builder"""

import sys
import os
import unittest
import StringIO

from treepkg.builder import PBuilder
from treepkg.run import call

from filesupport import FileTestMixin

# helper program to dump the command line arguments into a file so that
# test cases can check them.  Also if the environment variable
# TREEPKG_TEST is set, create the file named by it.
dump_command_line_py = """
import sys, os
open(sys.argv[1], 'w').write(repr(sys.argv[2:]))
value = os.environ.get('TREEPKG_TEST')
if value:
    open(value, 'w').close()
"""

class PBuilderTests(unittest.TestCase, FileTestMixin):

    def setUp(self):
        self.dump_command_line = self.create_temp_file("dump_command_line.py",
                                                       dump_command_line_py)
        self.command_line_file = self.temp_file_name("command_line")
        self.root_command = [sys.executable, self.dump_command_line,
                             self.command_line_file]

    def check_command_line(self, args):
        self.check_file_contents(self.command_line_file, repr(args))


class TestPBuilder(PBuilderTests):

    def test_init_pbuilder(self):
        """Tests the PBuilder.init_builder method."""
        basedir = self.create_temp_dir("pbuilder")
        pbuilderrc = os.path.join(basedir, "pbuilderrc")
        builder = PBuilder(pbuilderrc, self.root_command)
        old_stdout = sys.stdout
        sys.stdout = captured_stdout = StringIO.StringIO()
        try:
            builder.init_builder(distribution="etch",
                                  mirrorsite="http://example.com/debian",
                                  extramirrors=None)
        finally:
            sys.stdout = old_stdout

        # check whether the necessary directories were created
        missing = [dirname for dirname in ["base", "build", "result",
                                           "aptcache", "extra-pkg"]
                   if not os.path.isdir(os.path.join(basedir, dirname))]
        if missing:
            self.fail("init_builder did not create these directories: %s"
                      % " ".join(missing))

        # check the pbuilderrc.  This test is a little too strict
        # because it checks the exact contents of the file.  Instread it
        # should normalize the contents in some way and check that.
        pbuilderrc_contents = (
            "# This file was automatically generated by initpbuilder.py.\n"
            "# for the possible settings see \"man pbuilderrc\"\n"
            "\n"
            "BASETGZ=%(basedir)s/base/base.tgz\n"
            "BUILDPLACE=%(basedir)s/build\n"
            "USEPROC=yes\n"
            "USEDEVPTS=yes\n"
            "BUILDRESULT=%(basedir)s/result\n"
            "DISTRIBUTION=etch\n"
            "APTCACHE=%(basedir)s/aptcache\n"
            "APTCACHEHARDLINK=yes\n"
            "REMOVEPACKAGES=lilo\n"
            "MIRRORSITE=\"http://example.com/debian\"\n"
            "OTHERMIRROR=\"deb file://%(basedir)s/extra-pkg ./\"\n"
            "BINDMOUNTS=\"%(basedir)s/extra-pkg\"\n"
            "PKGNAME_LOGFILE=yes\n" % locals())
        self.check_file_contents(pbuilderrc, pbuilderrc_contents)

        # The Packages file is empty for now.
        self.check_file_contents(os.path.join(basedir, "extra-pkg", "Packages"),
                                 "")
        # check the text written to stdout.  This test is a little too
        # strict because it checks the exact output.
        self.assertEquals(captured_stdout.getvalue(),
                          "creating directory: '%(basedir_repr)s/base'\n"
                          "creating directory: '%(basedir_repr)s/build'\n"
                          "creating directory: '%(basedir_repr)s/result'\n"
                          "creating directory: '%(basedir_repr)s/aptcache'\n"
                          "creating directory: '%(basedir_repr)s/extra-pkg'\n"
                          "creating pbuilderrc: '%(basedir_repr)s/pbuilderrc'\n"
                          "turning the extra-pkg dir into a debian archive\n"
                          "running pbuilder create\n"
                          % dict(basedir_repr=repr(basedir)[1:-1]))

    def test_init_pbuilder_run_twice(self):
        """Tests whether PBuilder.init_builder prints an error when run twice.
        """
        basedir = self.create_temp_dir("pbuilder")

        # run it once
        pbuilderrc = os.path.join(basedir, "pbuilderrc")
        builder = PBuilder(pbuilderrc, self.root_command)
        old_stdout = sys.stdout
        sys.stdout = captured_stdout = StringIO.StringIO()
        try:
            builder.init_builder(distribution="etch",
                                  mirrorsite="http://example.com/debian",
                                  extramirrors=None)
        finally:
            sys.stdout = old_stdout

        # running it again should not modify anything in the directory
        # (which we don't check currently), it should print an error
        # message and exit with exit code 1.
        old_stderr = sys.stderr
        sys.stderr = captured_stderr = StringIO.StringIO()
        try:
            try:
                builder.init_builder(distribution="etch",
                                      mirrorsite="http://example.com/debian",
                                      extramirrors=None)
            except SystemExit, exc:
                self.assertEquals(exc.code, 1)
        finally:
            sys.stderr = old_stderr
        self.assertEquals("pbuilderrc %r already exists.\n"
                          % os.path.join(basedir, "pbuilderrc"),
                          captured_stderr.getvalue())

    def test_update(self):
        """Tests the PBuilder.update method."""
        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.update()
        self.check_command_line(['/usr/sbin/pbuilder', 'update',
                                 '--configfile', 'my_pbuilderrc'])

    def test_build(self):
        """Tests the PBuilder.build method.
        The test checks whether the build method creates the binary_dir
        and then checks the arguments with which the root command is
        called.  The test is a little too strict because it expects a
        specific order of the arguments even though the order of some of
        the arguments doesn't matter.

        A more thorough test of the build method is implicity done by
        the packager tests.
        """
        binary_dir_name = self.temp_file_name("binary")
        if os.path.exists(binary_dir_name):
            os.rmdir(binary_dir_name)
        # sanity check: the binary directory must not exist yet.
        self.failIf(os.path.exists(binary_dir_name))

        logfilename = self.temp_file_name("the_logfile")

        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.build("my_dsc_file", binary_dir_name, logfilename)
        self.check_command_line(['/usr/sbin/pbuilder', 'build',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--buildresult', binary_dir_name,
                                 '--debbuildopts', '-b',
                                 'my_dsc_file'])
        self.failUnless(os.path.isdir(binary_dir_name))

    def test_build_with_bindmounts(self):
        """Tests the PBuilder.build method with the bindmounts parameter"""
        binary_dir_name = self.temp_file_name("binary")
        if os.path.exists(binary_dir_name):
            os.rmdir(binary_dir_name)
        # sanity check: the binary directory must not exist yet.
        self.failIf(os.path.exists(binary_dir_name))

        logfilename = self.temp_file_name("the_logfile")

        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.build("my_dsc_file", binary_dir_name, logfilename,
                      bindmounts=["/home/builder/tracks",
                                  "/home/builder/pbuilder"])
        self.check_command_line(['/usr/sbin/pbuilder', 'build',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--buildresult', binary_dir_name,
                                 '--bindmounts', "/home/builder/tracks",
                                 '--bindmounts', "/home/builder/pbuilder",
                                 '--debbuildopts', '-b',
                                 'my_dsc_file'])
        self.failUnless(os.path.isdir(binary_dir_name))

    def test_build_with_extra_packages(self):
        """Tests the PBuilder.build method with the extra_packages parameter"""
        binary_dir_name = self.temp_file_name("binary")
        if os.path.exists(binary_dir_name):
            os.rmdir(binary_dir_name)
        # sanity check: the binary directory must not exist yet.
        self.failIf(os.path.exists(binary_dir_name))

        logfilename = self.temp_file_name("the_logfile")

        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.build("my_dsc_file", binary_dir_name, logfilename,
                      extra_packages=["subversion", "texinfo"])
        self.check_command_line(['/usr/sbin/pbuilder', 'build',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--buildresult', binary_dir_name,
                                 '--extrapackages', "subversion",
                                 '--extrapackages', "texinfo",
                                 '--debbuildopts', '-b',
                                 'my_dsc_file'])
        self.failUnless(os.path.isdir(binary_dir_name))

    def test_build_with_extra_env(self):
        """Tests the PBuilder.build method with the extra_env parameter"""
        binary_dir_name = self.temp_file_name("binary")
        if os.path.exists(binary_dir_name):
            os.rmdir(binary_dir_name)
        env_test_file = self.temp_file_name("envtest")
        # sanity check: the binary directory must not exist yet.
        self.failIf(os.path.exists(binary_dir_name))
        # sanity check: the environment variable TREEPKG_TEST must not
        # be set yet
        self.failIf("TREEPKG_TEST" in os.environ)

        logfilename = self.temp_file_name("the_logfile")

        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.build("my_dsc_file", binary_dir_name, logfilename,
                      extra_env=dict(TREEPKG_TEST=env_test_file))
        self.check_command_line(['/usr/sbin/pbuilder', 'build',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--buildresult', binary_dir_name,
                                 '--debbuildopts', '-b',
                                 'my_dsc_file'])
        self.failUnless(os.path.isdir(binary_dir_name))
        self.failUnless(os.path.exists(env_test_file))

    def test_run_script(self):
        logfilename = self.temp_file_name("the_logfile")
        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.run_script(["my_script"], logfile=logfilename)
        self.check_command_line(['/usr/sbin/pbuilder', 'execute',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename, '--',
                                 'my_script'])

    def test_run_script_with_arguments(self):
        logfilename = self.temp_file_name("the_logfile")
        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.run_script(["my_script", "--verbose"], logfile=logfilename)
        self.check_command_line(['/usr/sbin/pbuilder', 'execute',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename, '--',
                                 'my_script', '--verbose'])

    def test_run_script_with_bindmounts(self):
        logfilename = self.temp_file_name("the_logfile")
        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.run_script(["my_script"], logfile=logfilename,
                           bindmounts=("/home/builder/foo",
                                       "/home/builder/treepkg"))
        self.check_command_line(['/usr/sbin/pbuilder', 'execute',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--bindmounts', '/home/builder/foo',
                                 '--bindmounts', '/home/builder/treepkg',
                                 '--', 'my_script'])

    def test_run_script_save_after_exec(self):
        logfilename = self.temp_file_name("the_logfile")
        builder = PBuilder("my_pbuilderrc", self.root_command)
        builder.run_script(["my_script", "--verbose"], logfilename,
                           save_after_exec=True)
        self.check_command_line(['/usr/sbin/pbuilder', 'execute',
                                 '--configfile', 'my_pbuilderrc',
                                 '--logfile', logfilename,
                                 '--save-after-exec', '--',
                                 'my_script', '--verbose'])


class TestPBuilderWithBinaryPackage(PBuilderTests):

    minimal_package = [
        ("debian",
         [("control", """\
Source: minimal
Section: utils
Priority: optional
Maintainer: Bernhard Herzog <bh@intevation.de>
Standards-Version: 3.7.2.2
Build-Depends: debhelper

Package: minimal
Architecture: any
Depends: ${shlibs:Depends}
Description: Minimal package for test purposes
"""),
          ("rules", 0755, """\
#!/usr/bin/make -f

build: build-stamp
build-stamp:
	dh_testdir
	touch build-stamp

clean:
	dh_testdir
	dh_testroot
	rm -f build-stamp
	dh_clean

# Build architecture-dependent files here.
binary-arch:
	dh_testdir
	dh_testroot
	dh_installdocs README
	dh_installchangelogs
	dh_fixperms
	dh_installdeb
	dh_gencontrol
	dh_md5sums
	dh_builddeb

binary: binary-arch
.PHONY: build build-stamp clean binary-arch binary
"""),
          ("changelog", """\
minimal (1.0-1) unstable; urgency=low

  * Newly packaged

 -- Bernhard Herzog <bh@intevation.de>  Wed, 21 May 2008 16:10:29 +0200
""")]),
        ("README", """\
This is a minimal debian package for test purposes
"""),
        ]

    pbuilder_files = [("pbuilderrc", ""),
                      ("extra-pkg", [])]

    def setUp(self):
        PBuilderTests.setUp(self)
        self.temp_base_dir = self.create_temp_dir("pbuilder")
        self.minimal_packge_dir = os.path.join(self.temp_base_dir,
                                               "minimal-1.0")
        self.create_files(self.minimal_packge_dir, self.minimal_package)
        call(["dpkg-buildpackage", "-rfakeroot", "-b", "-uc"],
             cwd=self.minimal_packge_dir, suppress_output=True)
        self.minimal_package_deb = os.path.join(self.temp_base_dir,
                                                "minimal_1.0-1_i386.deb")
        self.pbuilder_basedir = os.path.join(self.temp_base_dir, "pbuilder")
        self.create_files(self.pbuilder_basedir, self.pbuilder_files)
        self.extra_pkg_dir = os.path.join(self.pbuilder_basedir, "extra-pkg")
        self.pbuilderrc = os.path.join(self.pbuilder_basedir, "pbuilderrc")

    def test_add_binaries_to_extra_pkg(self):
        """Tests the PBuilder.add_binaries_to_extra_pkg method"""
        builder = PBuilder(self.pbuilderrc, self.root_command)
        # sanity check: the extra-pkg directory should be empty now
        self.assertEquals(os.listdir(self.extra_pkg_dir), [])

        builder.add_binaries_to_extra_pkg([self.minimal_package_deb])

        self.assertEquals(sorted(os.listdir(self.extra_pkg_dir)),
                          ["Packages", "Release", "auto"])
        self.assertEquals(sorted(os.listdir(os.path.join(self.extra_pkg_dir,
                                                         "auto"))),
                          ["minimal_1.0-1_i386.deb"])
        self.check_command_line(['/usr/sbin/pbuilder', 'update',
                                 '--configfile', self.pbuilderrc])
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)