]> git.decadent.org.uk Git - dak.git/commitdiff
Merge commit 'ftpmaster/master'
authorMark Hymers <mhy@debian.org>
Sun, 1 Nov 2009 09:22:53 +0000 (09:22 +0000)
committerMark Hymers <mhy@debian.org>
Sun, 1 Nov 2009 09:22:53 +0000 (09:22 +0000)
58 files changed:
config/debian/common
config/debian/cron.hourly
config/debian/cron.unchecked
config/debian/lintian.tags
dak/test/001/1.dsc [deleted file]
dak/test/001/2.dsc [deleted file]
dak/test/001/3.dsc [deleted file]
dak/test/001/4.dsc [deleted file]
dak/test/001/5.dsc [deleted file]
dak/test/001/6.dsc [deleted file]
dak/test/001/test.py [deleted file]
dak/test/002/empty.changes [deleted file]
dak/test/002/test.py [deleted file]
dak/test/003/krb5_1.2.2-4_m68k.changes [deleted file]
dak/test/003/test.py [deleted file]
dak/test/004/test.py [deleted file]
dak/test/005/bogus-post.changes [deleted file]
dak/test/005/bogus-pre.changes [deleted file]
dak/test/005/test.py [deleted file]
dak/test/005/valid.changes [deleted file]
dak/test/006/test.py [deleted file]
daklib/binary.py [changed mode: 0755->0644]
daklib/changes.py [changed mode: 0755->0644]
daklib/config.py [changed mode: 0755->0644]
daklib/dak_exceptions.py [changed mode: 0755->0644]
daklib/daklog.py [changed mode: 0755->0644]
daklib/dbconn.py [changed mode: 0755->0644]
daklib/holding.py [changed mode: 0755->0644]
daklib/lintian.py [new file with mode: 0644]
daklib/queue.py [changed mode: 0755->0644]
daklib/regexes.py [changed mode: 0755->0644]
daklib/singleton.py [deleted file]
daklib/summarystats.py [changed mode: 0755->0644]
daklib/textutils.py [changed mode: 0755->0644]
daklib/urgencylog.py [changed mode: 0755->0644]
daklib/utils.py [changed mode: 0755->0644]
tests/base_test.py [new file with mode: 0644]
tests/fixtures/changes/1.changes [new file with mode: 0644]
tests/fixtures/changes/2.changes [new file with mode: 0644]
tests/fixtures/changes/bogus-post.changes [new file with mode: 0644]
tests/fixtures/changes/bogus-pre.changes [new file with mode: 0644]
tests/fixtures/changes/valid.changes [new file with mode: 0644]
tests/fixtures/dak.conf [new file with mode: 0644]
tests/fixtures/dsc/1.dsc [new file with mode: 0644]
tests/fixtures/dsc/2.dsc [new file with mode: 0644]
tests/fixtures/dsc/3.dsc [new file with mode: 0644]
tests/fixtures/dsc/4.dsc [new file with mode: 0644]
tests/fixtures/dsc/5.dsc [new file with mode: 0644]
tests/fixtures/dsc/6.dsc [new file with mode: 0644]
tests/fixtures/dsc/7.dsc [new file with mode: 0644]
tests/test_extract_component_from_section.py [new file with mode: 0755]
tests/test_fix_maintainer.py [new file with mode: 0755]
tests/test_formats.py
tests/test_lintian.py [new file with mode: 0755]
tests/test_parse_changes.py [new file with mode: 0755]
tests/test_process_gpgv_output.py [new file with mode: 0755]
tests/test_regexes.py
tests/test_srcformats.py

index 599f8dc55a02c517cfc3e39852a253b9c1161064..c79ad810b3cc12a77f673e5e3e040e4eaf5133ab 100644 (file)
@@ -45,22 +45,23 @@ function make_buildd_dir () {
 
 # move accepted NEW packages from stagedir into queue/accepted
 function acceptnew () {
-    cd $newstage
-    for file in $(find . -maxdepth 1 -mindepth 1 -type f -name \*.changes | sed -e "s,./,," | xargs); do
-        sed '1,/Files:/d' "${file}" | sed '/BEGIN PGP SIGNATURE/,$d' \
-            | while read notused1 notused2 notused3 notused4 NAME; do
-            if [ -z "${NAME}" ]; then
-                # Sometimes there is a newline after the Files:, ignore it
-                continue
-            fi
-            if [ -f "${NAME}" ]; then
-                mv --target-directory="${accepted}" "${NAME}"
-            else
-                log_error "Error, couldn't find file ${NAME} to move to ${accepted}"
-            fi
-        done
-        mv --target-directory="${accepted}"  "${file}" "${file%%.changes}.dak"
-    done
+    return
+    # cd $newstage
+    # for file in $(find . -maxdepth 1 -mindepth 1 -type f -name \*.changes | sed -e "s,./,," | xargs); do
+    #     sed '1,/Files:/d' "${file}" | sed '/BEGIN PGP SIGNATURE/,$d' \
+    #         | while read notused1 notused2 notused3 notused4 NAME; do
+    #         if [ -z "${NAME}" ]; then
+    #             # Sometimes there is a newline after the Files:, ignore it
+    #             continue
+    #         fi
+    #         if [ -f "${NAME}" ]; then
+    #             mv --target-directory="${accepted}" "${NAME}"
+    #         else
+    #             log_error "Error, couldn't find file ${NAME} to move to ${accepted}"
+    #         fi
+    #     done
+    #     mv --target-directory="${accepted}"  "${file}" "${file%%.changes}.dak"
+    # done
 }
 
 # Do the unchecked processing, in case we have files.
@@ -73,7 +74,7 @@ function do_unchecked () {
     UNCHECKED_WITHOUT_LOCK=${UNCHECKED_WITHOUT_LOCK:-""}
 
     echo "$timestamp": ${changes:-"Nothing to do"}  >> $report
-    dak process-unchecked -a ${UNCHECKED_WITHOUT_LOCK} -d "$unchecked" >> $report
+    dak process-upload -a ${UNCHECKED_WITHOUT_LOCK} -d "$unchecked" >> $report
 }
 
 function sync_debbugs () {
index 649445c293177aeae55c26cbe5629e94a2842dea..34d1b59e144eba9cdc2e261d623f593d877751b7 100755 (executable)
@@ -10,11 +10,11 @@ export SCRIPTVARS=/srv/ftp.debian.org/dak/config/debian/vars
 date -u > $ftpdir/project/trace/ftp-master.debian.org
 echo "Using dak v1" >> $ftpdir/project/trace/ftp-master.debian.org
 echo "Running on host: $(hostname -f)" >> $ftpdir/project/trace/ftp-master.debian.org
-dak import-users-from-passwd
-dak queue-report -n > $webdir/new.html
-dak queue-report -8 -d accepted,new,byhand,proposedupdates,oldproposedupdates
+#dak import-users-from-passwd
+#dak queue-report -n > $webdir/new.html
+#dak queue-report -8 -d accepted,new,byhand,proposedupdates,oldproposedupdates
 dak show-deferred > ${webdir}/deferred.html
-cd $queuedir/new ; dak show-new *.changes > /dev/null
+#cd $queuedir/new ; dak show-new *.changes > /dev/null
 $base/dak/tools/queue_rss.py -q $queuedir/new -o $webdir/rss/ -d $base/misc
 $base/dak/tools/removals.pl > $webdir/rss/removals.rss
 
index b3c078e30d3925ba565782627e34462e67656b5d..70a3ae766ffe8e660644334ca0f645dc29ffdfd6 100755 (executable)
@@ -59,7 +59,7 @@ cleanup() {
 function do_buildd () {
     if lockfile -r3 $NOTICE; then
         LOCKDAILY="YES"
-        psql projectb -A -t -q -c "SELECT filename FROM queue_build WHERE queue = 0 AND suite = 5 AND in_queue = true AND filename ~ 'd(sc|eb)$'" > $dbdir/dists/unstable_accepted.list
+        psql projectb -A -t -q -c "SELECT build_queue.path || '/' || build_queue_files.filename FROM build_queue_files LEFT JOIN build_queue ON (build_queue.id = build_queue_files.build_queue_id) WHERE queue_name = 'accepted' AND filename ~ 'd(sc|eb)$';" > $dbdir/dists/unstable_accepted.list
         cd $overridedir
         dak make-overrides &>/dev/null
         rm -f override.sid.all3 override.sid.all3.src
@@ -79,9 +79,9 @@ function do_buildd () {
 # the actual unchecked functions follow                                #
 ########################################################################
 
-lockfile -r3 "$LOCK_NEW"
-acceptnew
-rm -f "$LOCK_NEW"
+#lockfile -r3 "$LOCK_NEW"
+acceptnew
+#rm -f "$LOCK_NEW"
 
 # only run one cron.unchecked
 lockfile -r3 $LOCKFILE || exit 0
index bf489144599b2392f0bdcc11492af22caf8359fd..e736be35d82ce114ddea4b95a6191a2a577ea963 100644 (file)
@@ -1,5 +1,5 @@
 lintian:
-  warning:
+  nonfatal:
     - statically-linked-binary
     - arch-independent-package-contains-binary-or-object
     - arch-dependent-file-in-usr-share
@@ -12,7 +12,7 @@ lintian:
     - mknod-in-maintainer-script
     - package-contains-info-dir-file
     - copyright-lists-upstream-authors-with-dh_make-boilerplate
-  error:
+  fatal:
     - wrong-file-owner-uid-or-gid
     - bad-relation
     - FSSTND-dir-in-usr
diff --git a/dak/test/001/1.dsc b/dak/test/001/1.dsc
deleted file mode 100644 (file)
index dfdd92f..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/2.dsc b/dak/test/001/2.dsc
deleted file mode 100644 (file)
index a6c9d85..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/3.dsc b/dak/test/001/3.dsc
deleted file mode 100644 (file)
index 211340e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/4.dsc b/dak/test/001/4.dsc
deleted file mode 100644 (file)
index 91e361f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/5.dsc b/dak/test/001/5.dsc
deleted file mode 100644 (file)
index db9d8d3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
-
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/6.dsc b/dak/test/001/6.dsc
deleted file mode 100644 (file)
index ae36d64..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-
-Format: 1.0
-Source: amaya
-Version: 3.2.1-1
-Binary: amaya
-Maintainer: Steve Dunham <dunham@debian.org>
-Architecture: any
-Standards-Version: 2.4.0.0
-Files: 
- 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
- da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.2 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
-rhYnRmVuNMa8oYSvL4hl/Yw=
-=EFAA
------END PGP SIGNATURE-----
diff --git a/dak/test/001/test.py b/dak/test/001/test.py
deleted file mode 100644 (file)
index 8238c20..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-
-# Check utils.parse_changes()'s .dsc file validation
-# Copyright (C) 2000, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import utils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-def main ():
-    # Valid .dsc
-    utils.parse_changes('1.dsc',1)
-
-    # Missing blank line before signature body
-    try:
-        utils.parse_changes('2.dsc',1)
-    except utils.invalid_dsc_format_exc, line:
-        if line != 14:
-            fail("Incorrect line number ('%s') for test #2." % (line))
-    else:
-        fail("Test #2 wasn't recognised as invalid.")
-
-    # Missing blank line after signature header
-    try:
-        utils.parse_changes('3.dsc',1)
-    except utils.invalid_dsc_format_exc, line:
-        if line != 14:
-            fail("Incorrect line number ('%s') for test #3." % (line))
-    else:
-        fail("Test #3 wasn't recognised as invalid.")
-
-    # No blank lines at all
-    try:
-        utils.parse_changes('4.dsc',1)
-    except utils.invalid_dsc_format_exc, line:
-        if line != 19:
-            fail("Incorrect line number ('%s') for test #4." % (line))
-    else:
-        fail("Test #4 wasn't recognised as invalid.")
-
-    # Extra blank line before signature body
-    try:
-        utils.parse_changes('5.dsc',1)
-    except utils.invalid_dsc_format_exc, line:
-        if line != 15:
-            fail("Incorrect line number ('%s') for test #5." % (line))
-    else:
-        fail("Test #5 wasn't recognised as invalid.")
-
-    # Extra blank line after signature header
-    try:
-        utils.parse_changes('6.dsc',1)
-    except utils.invalid_dsc_format_exc, line:
-        if line != 5:
-            fail("Incorrect line number ('%s') for test #6." % (line))
-    else:
-        fail("Test #6 wasn't recognised as invalid.")
-
-    # Valid .dsc ; ignoring errors
-    utils.parse_changes('1.dsc', 0)
-
-    # Invalid .dsc ; ignoring errors
-    utils.parse_changes('2.dsc', 0)
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
diff --git a/dak/test/002/empty.changes b/dak/test/002/empty.changes
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/dak/test/002/test.py b/dak/test/002/test.py
deleted file mode 100644 (file)
index 919a70a..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-# Check utils.parse_changes()'s for handling empty files
-# Copyright (C) 2000, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import utils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-def main ():
-    # Empty .changes file; should raise a 'parse error' exception.
-    try:
-        utils.parse_changes('empty.changes', 0)
-    except utils.changes_parse_error_exc, line:
-        if line != "[Empty changes file]":
-            fail("Returned exception with unexcpected error message `%s'." % (line))
-    else:
-        fail("Didn't raise a 'parse error' exception for a zero-length .changes file.")
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
diff --git a/dak/test/003/krb5_1.2.2-4_m68k.changes b/dak/test/003/krb5_1.2.2-4_m68k.changes
deleted file mode 100644 (file)
index 9d264c1..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-
-Format: 1.7
-Date: Fri, 20 Apr 2001 02:47:21 -0400
-Source: krb5
-Binary: krb5-kdc krb5-doc krb5-rsh-server libkrb5-dev libkrb53 krb5-ftpd
- krb5-clients krb5-user libkadm54 krb5-telnetd krb5-admin-server
-Architecture: m68k
-Version: 1.2.2-4
-Distribution: unstable
-Urgency: low
-Maintainer: buildd m68k user account <buildd@ax.westfalen.de>
-Changed-By: Sam Hartman <hartmans@debian.org>
-Description: 
- krb5-admin-server - Mit Kerberos master server (kadmind)
- krb5-clients - Secure replacements for ftp, telnet and rsh using MIT Kerberos
- krb5-ftpd  - Secure FTP server supporting MIT Kerberos
- krb5-kdc   - Mit Kerberos key server (KDC)
- krb5-rsh-server - Secure replacements for rshd and rlogind  using MIT Kerberos
- krb5-telnetd - Secure telnet server supporting MIT Kerberos
- krb5-user  - Basic programs to authenticate using MIT Kerberos
- libkadm54  - MIT Kerberos administration runtime libraries
- libkrb5-dev - Headers and development libraries for MIT Kerberos
- libkrb53   - MIT Kerberos runtime libraries
-Closes: 94407
-Changes: 
- krb5 (1.2.2-4) unstable; urgency=low
- .
-   * Fix shared libraries to build with gcc not ld to properly include
-     -lgcc symbols, closes: #94407
-Files: 
- 563dac1cdd3ba922f9301fe074fbfc80 65836 non-us/main optional libkadm54_1.2.2-4_m68k.deb
- bb620f589c17ab0ebea1aa6e10ca52ad 272198 non-us/main optional libkrb53_1.2.2-4_m68k.deb
- 40af6e64b3030a179e0de25bd95c95e9 143264 non-us/main optional krb5-user_1.2.2-4_m68k.deb
- ffe4e5e7b2cab162dc608d56278276cf 141870 non-us/main optional krb5-clients_1.2.2-4_m68k.deb
- 4fe01d1acb4b82ce0b8b72652a9a15ae 54592 non-us/main optional krb5-rsh-server_1.2.2-4_m68k.deb
- b3c8c617ea72008a33b869b75d2485bf 41292 non-us/main optional krb5-ftpd_1.2.2-4_m68k.deb
- 5908f8f60fe536d7bfc1ef3fdd9d74cc 42090 non-us/main optional krb5-telnetd_1.2.2-4_m68k.deb
- 650ea769009a312396e56503d0059ebc 160236 non-us/main optional krb5-kdc_1.2.2-4_m68k.deb
- 399c9de4e9d7d0b0f5626793808a4391 160392 non-us/main optional krb5-admin-server_1.2.2-4_m68k.deb
- 6f962fe530c3187e986268b4e4d27de9 398662 non-us/main optional libkrb5-dev_1.2.2-4_m68k.deb
-
------BEGIN PGP SIGNATURE-----
-Version: 2.6.3i
-Charset: noconv
-
-iQCVAwUBOvVPPm547I3m3eHJAQHyaQP+M7RXVEqZ2/xHiPzaPcZRJ4q7o0zbMaU8
-qG/Mi6kuR1EhRNMjMH4Cp6ctbhRDHK5FR/8v7UkOd+ETDAhiw7eqJnLC60EZxZ/H
-CiOs8JklAXDERkQ3i7EYybv46Gxx91pIs2nE4xVKnG16d/wFELWMBLY6skF1B2/g
-zZju3cuFCCE=
-=Vm59
------END PGP SIGNATURE-----
-
-
diff --git a/dak/test/003/test.py b/dak/test/003/test.py
deleted file mode 100755 (executable)
index ce07c11..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-
-# Check utils.parse_changes()'s for handling of multi-line fields
-# Copyright (C) 2000, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-# The deal here is that for the first 6 months of dak's
-# implementation it has been misparsing multi-line fields in .changes
-# files; specifically multi-line fields where there _is_ data on the
-# first line. So, for example:
-
-# Foo: bar baz
-#  bat bant
-
-# Became "foo: bar bazbat bant" rather than "foo: bar baz\nbat bant"
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import utils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-def main ():
-    # Valid .changes file with a multi-line Binary: field
-    try:
-        changes = utils.parse_changes('krb5_1.2.2-4_m68k.changes', 0)
-    except utils.changes_parse_error_exc, line:
-        fail("parse_changes() returned an exception with error message `%s'." % (line))
-
-    o = changes.get("binary", "")
-    if o != "":
-        del changes["binary"]
-    changes["binary"] = {}
-    for j in o.split():
-        changes["binary"][j] = 1
-
-    if not changes["binary"].has_key("krb5-ftpd"):
-        fail("parse_changes() is broken; 'krb5-ftpd' is not in the Binary: dictionary.")
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
diff --git a/dak/test/004/test.py b/dak/test/004/test.py
deleted file mode 100755 (executable)
index 4aa6b48..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-
-# Check utils.extract_component_from_section()
-# Copyright (C) 2000, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import utils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-# prefix: non-US
-# component: main, contrib, non-free
-# section: games, admin, libs, [...]
-
-# [1] Order is as above.
-# [2] Prefix is optional for the default archive, but mandatory when
-#     uploads are going anywhere else.
-# [3] Default component is main and may be omitted.
-# [4] Section is optional.
-# [5] Prefix is case insensitive
-# [6] Everything else is case sensitive.
-
-def test(input, output):
-    result = utils.extract_component_from_section(input)
-    if result != output:
-        fail ("%s -> %r [should have been %r]" % (input, result, output))
-
-def main ():
-    # Err, whoops?  should probably be "utils", "main"...
-    input = "main/utils"; output = ("main/utils", "main")
-    test (input, output)
-
-
-    # Validate #3
-    input = "utils"; output = ("utils", "main")
-    test (input, output)
-
-    input = "non-free/libs"; output = ("non-free/libs", "non-free")
-    test (input, output)
-
-    input = "contrib/net"; output = ("contrib/net", "contrib")
-    test (input, output)
-
-
-    # Validate #3 with a prefix
-    input = "non-US"; output = ("non-US", "non-US/main")
-    test (input, output)
-
-
-    # Validate #4
-    input = "main"; output = ("main", "main")
-    test (input, output)
-
-    input = "contrib"; output = ("contrib", "contrib")
-    test (input, output)
-
-    input = "non-free"; output = ("non-free", "non-free")
-    test (input, output)
-
-
-    # Validate #4 with a prefix
-    input = "non-US/main"; output = ("non-US/main", "non-US/main")
-    test (input, output)
-
-    input = "non-US/contrib"; output = ("non-US/contrib", "non-US/contrib")
-    test (input, output)
-
-    input = "non-US/non-free"; output = ("non-US/non-free", "non-US/non-free")
-    test (input, output)
-
-
-    # Validate #5
-    input = "non-us"; output = ("non-us", "non-US/main")
-    test (input, output)
-
-    input = "non-us/contrib"; output = ("non-us/contrib", "non-US/contrib")
-    test (input, output)
-
-
-    # Validate #6 (section)
-    input = "utIls"; output = ("utIls", "main")
-    test (input, output)
-
-    # Others..
-    input = "non-US/libs"; output = ("non-US/libs", "non-US/main")
-    test (input, output)
-    input = "non-US/main/libs"; output = ("non-US/main/libs", "non-US/main")
-    test (input, output)
-    input = "non-US/contrib/libs"; output = ("non-US/contrib/libs", "non-US/contrib")
-    test (input, output)
-    input = "non-US/non-free/libs"; output = ("non-US/non-free/libs", "non-US/non-free")
-    test (input, output)
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
diff --git a/dak/test/005/bogus-post.changes b/dak/test/005/bogus-post.changes
deleted file mode 100644 (file)
index 95e5a1f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.7
-Date: Tue,  9 Sep 2003 01:16:01 +0100
-Source: gawk
-Binary: gawk
-Architecture: source i386
-Version: 1:3.1.3-2
-Distribution: unstable
-Urgency: low
-Maintainer: James Troup <james@nocrew.org>
-Changed-By: James Troup <james@nocrew.org>
-Description: 
- gawk       - GNU awk, a pattern scanning and processing language
-Closes: 204699 204701
-Changes: 
- gawk (1:3.1.3-2) unstable; urgency=low
- .
-   * debian/control (Standards-Version): bump to 3.6.1.0.
- .
-   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
-     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
-     upstream.  Closes: #204701
- .
-   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
-     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
-     forwarding it upstream.  Closes: #204699
-Files: 
- 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
- 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
- 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.6 (GNU/Linux)
-
-iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
-fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
-=O7Gh
------END PGP SIGNATURE-----
-You: have been 0wned
diff --git a/dak/test/005/bogus-pre.changes b/dak/test/005/bogus-pre.changes
deleted file mode 100644 (file)
index 0234d8b..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-You: have been 0wned
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.7
-Date: Tue,  9 Sep 2003 01:16:01 +0100
-Source: gawk
-Binary: gawk
-Architecture: source i386
-Version: 1:3.1.3-2
-Distribution: unstable
-Urgency: low
-Maintainer: James Troup <james@nocrew.org>
-Changed-By: James Troup <james@nocrew.org>
-Description: 
- gawk       - GNU awk, a pattern scanning and processing language
-Closes: 204699 204701
-Changes: 
- gawk (1:3.1.3-2) unstable; urgency=low
- .
-   * debian/control (Standards-Version): bump to 3.6.1.0.
- .
-   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
-     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
-     upstream.  Closes: #204701
- .
-   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
-     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
-     forwarding it upstream.  Closes: #204699
-Files: 
- 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
- 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
- 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.6 (GNU/Linux)
-
-iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
-fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
-=O7Gh
------END PGP SIGNATURE-----
diff --git a/dak/test/005/test.py b/dak/test/005/test.py
deleted file mode 100755 (executable)
index b5d3bbc..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python
-
-# Check utils.parse_changes() correctly ignores data outside the signed area
-# Copyright (C) 2004, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import utils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-def main ():
-    for file in [ "valid", "bogus-pre", "bogus-post" ]:
-        for strict_whitespace in [ 0, 1 ]:
-            try:
-                changes = utils.parse_changes("%s.changes" % (file), strict_whitespace)
-            except utils.changes_parse_error_exc, line:
-                fail("%s[%s]: parse_changes() returned an exception with error message `%s'." % (file, strict_whitespace, line))
-            oh_dear = changes.get("you")
-            if oh_dear:
-                fail("%s[%s]: parsed and accepted unsigned data!" % (file, strict_whitespace))
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
diff --git a/dak/test/005/valid.changes b/dak/test/005/valid.changes
deleted file mode 100644 (file)
index 0e77d27..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-Format: 1.7
-Date: Tue,  9 Sep 2003 01:16:01 +0100
-Source: gawk
-Binary: gawk
-Architecture: source i386
-Version: 1:3.1.3-2
-Distribution: unstable
-Urgency: low
-Maintainer: James Troup <james@nocrew.org>
-Changed-By: James Troup <james@nocrew.org>
-Description: 
- gawk       - GNU awk, a pattern scanning and processing language
-Closes: 204699 204701
-Changes: 
- gawk (1:3.1.3-2) unstable; urgency=low
- .
-   * debian/control (Standards-Version): bump to 3.6.1.0.
- .
-   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
-     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
-     upstream.  Closes: #204701
- .
-   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
-     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
-     forwarding it upstream.  Closes: #204699
-Files: 
- 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
- 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
- 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
-
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.6 (GNU/Linux)
-
-iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
-fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
-=O7Gh
------END PGP SIGNATURE-----
diff --git a/dak/test/006/test.py b/dak/test/006/test.py
deleted file mode 100755 (executable)
index 51a3317..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Test textutils.fix_maintainer()
-# Copyright (C) 2004, 2006  James Troup <james@nocrew.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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-import os, sys
-
-sys.path.append(os.path.abspath('../../'))
-
-import textutils
-
-################################################################################
-
-def fail(message):
-    sys.stderr.write("%s\n" % (message))
-    sys.exit(1)
-
-################################################################################
-
-def check_valid(s, xa, xb, xc, xd):
-    (a, b, c, d) = textutils.fix_maintainer(s)
-    if a != xa:
-        fail("rfc822_maint: %s (returned) != %s (expected [From: '%s']" % (a, xa, s))
-    if b != xb:
-        fail("rfc2047_maint: %s (returned) != %s (expected [From: '%s']" % (b, xb, s))
-    if c != xc:
-        fail("name: %s (returned) != %s (expected [From: '%s']" % (c, xc, s))
-    if d != xd:
-        fail("email: %s (returned) != %s (expected [From: '%s']" % (d, xd, s))
-
-def check_invalid(s):
-    try:
-        textutils.fix_maintainer(s)
-        fail("%s was parsed successfully but is expected to be invalid." % (s))
-    except utils.ParseMaintError, unused:
-        pass
-
-def main ():
-    # Check Valid UTF-8 maintainer field
-    s = "Noèl Köthe <noel@debian.org>"
-    xa = "Noèl Köthe <noel@debian.org>"
-    xb = "=?utf-8?b?Tm/DqGwgS8O2dGhl?= <noel@debian.org>"
-    xc = "Noèl Köthe"
-    xd = "noel@debian.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check valid ISO-8859-1 maintainer field
-    s = "Noèl Köthe <noel@debian.org>"
-    xa = "Noèl Köthe <noel@debian.org>"
-    xb = "=?iso-8859-1?q?No=E8l_K=F6the?= <noel@debian.org>"
-    xc = "Noèl Köthe"
-    xd = "noel@debian.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check valid ASCII maintainer field
-    s = "James Troup <james@nocrew.org>"
-    xa = "James Troup <james@nocrew.org>"
-    xb = "James Troup <james@nocrew.org>"
-    xc = "James Troup"
-    xd = "james@nocrew.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check "Debian vs RFC822" fixup of names with '.' or ',' in them
-    s = "James J. Troup <james@nocrew.org>"
-    xa = "james@nocrew.org (James J. Troup)"
-    xb = "james@nocrew.org (James J. Troup)"
-    xc = "James J. Troup"
-    xd = "james@nocrew.org"
-    check_valid(s, xa, xb, xc, xd)
-    s = "James J, Troup <james@nocrew.org>"
-    xa = "james@nocrew.org (James J, Troup)"
-    xb = "james@nocrew.org (James J, Troup)"
-    xc = "James J, Troup"
-    xd = "james@nocrew.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check just-email form
-    s = "james@nocrew.org"
-    xa = " <james@nocrew.org>"
-    xb = " <james@nocrew.org>"
-    xc = ""
-    xd = "james@nocrew.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check bracketed just-email form
-    s = "<james@nocrew.org>"
-    xa = " <james@nocrew.org>"
-    xb = " <james@nocrew.org>"
-    xc = ""
-    xd = "james@nocrew.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check Krazy quoted-string local part email address
-    s = "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>"
-    xa = "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>"
-    xb = "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>"
-    xc = "Cris van Pelt"
-    xd = "\"Cris van Pelt\"@tribe.eu.org"
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check empty string
-    s = xa = xb = xc = xd = ""
-    check_valid(s, xa, xb, xc, xd)
-
-    # Check for missing email address
-    check_invalid("James Troup")
-    # Check for invalid email address
-    check_invalid("James Troup <james@nocrew.org")
-
-################################################################################
-
-if __name__ == '__main__':
-    main()
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 2f24cd3..2d0b8e8
@@ -32,25 +32,27 @@ import os
 import apt_pkg
 import socket
 
-from singleton import Singleton
-
 ################################################################################
 
 default_config = "/etc/dak/dak.conf" #: default dak config, defines host properties
 
 def which_conf_file():
-    if os.getenv("DAK_CONFIG"):
-        return os.getenv("DAK_CONFIG")
-    else:
-        return default_config
+    return os.getenv("DAK_CONFIG", default_config)
 
-class Config(Singleton):
+class Config(object):
     """
     A Config object is a singleton containing
     information about the DAK configuration
     """
+
+    __shared_state = {}
+
     def __init__(self, *args, **kwargs):
-        super(Config, self).__init__(*args, **kwargs)
+        self.__dict__ = self.__shared_state
+
+        if not getattr(self, 'initialised', False):
+            self.initialised = True
+            self._readconf()
 
     def _readconf(self):
         apt_pkg.init()
@@ -74,9 +76,6 @@ class Config(Singleton):
         self.Find = self.Cnf.Find
         self.FindB = self.Cnf.FindB
 
-    def _startup(self, *args, **kwargs):
-        self._readconf()
-
     def has_key(self, name):
         return self.Cnf.has_key(name)
 
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index 26191ae..adf119b
@@ -51,7 +51,6 @@ from sqlalchemy.exc import *
 from sqlalchemy.orm.exc import NoResultFound
 
 from config import Config
-from singleton import Singleton
 from textutils import fix_maintainer
 
 ################################################################################
@@ -2502,65 +2501,72 @@ __all__.append('UploadBlock')
 
 ################################################################################
 
-class DBConn(Singleton):
+class DBConn(object):
     """
     database module init.
     """
+    __shared_state = {}
+
     def __init__(self, *args, **kwargs):
-        super(DBConn, self).__init__(*args, **kwargs)
+        self.__dict__ = self.__shared_state
 
-    def _startup(self, *args, **kwargs):
-        self.debug = False
-        if kwargs.has_key('debug'):
-            self.debug = True
-        self.__createconn()
+        if not getattr(self, 'initialised', False):
+            self.initialised = True
+            self.debug = kwargs.has_key('debug')
+            self.__createconn()
 
     def __setuptables(self):
-        self.tbl_architecture = Table('architecture', self.db_meta, autoload=True)
-        self.tbl_archive = Table('archive', self.db_meta, autoload=True)
-        self.tbl_bin_associations = Table('bin_associations', self.db_meta, autoload=True)
-        self.tbl_binaries = Table('binaries', self.db_meta, autoload=True)
-        self.tbl_binary_acl = Table('binary_acl', self.db_meta, autoload=True)
-        self.tbl_binary_acl_map = Table('binary_acl_map', self.db_meta, autoload=True)
-        self.tbl_build_queue = Table('build_queue', self.db_meta, autoload=True)
-        self.tbl_build_queue_files = Table('build_queue_files', self.db_meta, autoload=True)
-        self.tbl_component = Table('component', self.db_meta, autoload=True)
-        self.tbl_config = Table('config', self.db_meta, autoload=True)
-        self.tbl_content_associations = Table('content_associations', self.db_meta, autoload=True)
-        self.tbl_content_file_names = Table('content_file_names', self.db_meta, autoload=True)
-        self.tbl_content_file_paths = Table('content_file_paths', self.db_meta, autoload=True)
-        self.tbl_changes_pending_binary = Table('changes_pending_binaries', self.db_meta, autoload=True)
-        self.tbl_changes_pending_files = Table('changes_pending_files', self.db_meta, autoload=True)
-        self.tbl_changes_pending_files_map = Table('changes_pending_files_map', self.db_meta, autoload=True)
-        self.tbl_changes_pending_source = Table('changes_pending_source', self.db_meta, autoload=True)
-        self.tbl_changes_pending_source_files = Table('changes_pending_source_files', self.db_meta, autoload=True)
-        self.tbl_changes_pool_files = Table('changes_pool_files', self.db_meta, autoload=True)
-        self.tbl_dsc_files = Table('dsc_files', self.db_meta, autoload=True)
-        self.tbl_files = Table('files', self.db_meta, autoload=True)
-        self.tbl_fingerprint = Table('fingerprint', self.db_meta, autoload=True)
-        self.tbl_keyrings = Table('keyrings', self.db_meta, autoload=True)
-        self.tbl_changes = Table('changes', self.db_meta, autoload=True)
-        self.tbl_keyring_acl_map = Table('keyring_acl_map', self.db_meta, autoload=True)
-        self.tbl_location = Table('location', self.db_meta, autoload=True)
-        self.tbl_maintainer = Table('maintainer', self.db_meta, autoload=True)
-        self.tbl_new_comments = Table('new_comments', self.db_meta, autoload=True)
-        self.tbl_override = Table('override', self.db_meta, autoload=True)
-        self.tbl_override_type = Table('override_type', self.db_meta, autoload=True)
-        self.tbl_pending_content_associations = Table('pending_content_associations', self.db_meta, autoload=True)
-        self.tbl_policy_queue = Table('policy_queue', self.db_meta, autoload=True)
-        self.tbl_priority = Table('priority', self.db_meta, autoload=True)
-        self.tbl_section = Table('section', self.db_meta, autoload=True)
-        self.tbl_source = Table('source', self.db_meta, autoload=True)
-        self.tbl_source_acl = Table('source_acl', self.db_meta, autoload=True)
-        self.tbl_src_associations = Table('src_associations', self.db_meta, autoload=True)
-        self.tbl_src_format = Table('src_format', self.db_meta, autoload=True)
-        self.tbl_src_uploaders = Table('src_uploaders', self.db_meta, autoload=True)
-        self.tbl_suite = Table('suite', self.db_meta, autoload=True)
-        self.tbl_suite_architectures = Table('suite_architectures', self.db_meta, autoload=True)
-        self.tbl_suite_src_formats = Table('suite_src_formats', self.db_meta, autoload=True)
-        self.tbl_suite_build_queue_copy = Table('suite_build_queue_copy', self.db_meta, autoload=True)
-        self.tbl_uid = Table('uid', self.db_meta, autoload=True)
-        self.tbl_upload_blocks = Table('upload_blocks', self.db_meta, autoload=True)
+        tables = (
+            'architecture',
+            'archive',
+            'bin_associations',
+            'binaries',
+            'binary_acl',
+            'binary_acl_map',
+            'build_queue',
+            'build_queue_files',
+            'component',
+            'config',
+            'content_associations',
+            'content_file_names',
+            'content_file_paths',
+            'changes_pending_binaries',
+            'changes_pending_files',
+            'changes_pending_files_map',
+            'changes_pending_source',
+            'changes_pending_source_files',
+            'changes_pool_files',
+            'dsc_files',
+            'files',
+            'fingerprint',
+            'keyrings',
+            'changes',
+            'keyring_acl_map',
+            'location',
+            'maintainer',
+            'new_comments',
+            'override',
+            'override_type',
+            'pending_content_associations',
+            'policy_queue',
+            'priority',
+            'section',
+            'source',
+            'source_acl',
+            'src_associations',
+            'src_format',
+            'src_uploaders',
+            'suite',
+            'suite_architectures',
+            'suite_src_formats',
+            'suite_build_queue_copy',
+            'uid',
+            'upload_blocks',
+        )
+
+        for table_name in tables:
+            table = Table('tbl_%s' % table_name, self.db_meta, autoload=True)
+            setattr(self, table_name, table)
 
     def __setupmappers(self):
         mapper(Architecture, self.tbl_architecture,
old mode 100755 (executable)
new mode 100644 (file)
index 0c472d1..b637738
@@ -30,19 +30,22 @@ import os
 from errno import ENOENT, EEXIST, EACCES
 import shutil
 
-from singleton import Singleton
 from config import Config
 from utils import fubar
 
 ###############################################################################
 
-class Holding(Singleton):
+class Holding(object):
+    __shared_state = {}
+
     def __init__(self, *args, **kwargs):
-        super(Holding, self).__init__(*args, **kwargs)
+        self.__dict__ = self.__shared_state
 
-    def _startup(self):
-        self.in_holding = {}
-        self.holding_dir = Config()["Dir::Queue::Holding"]
+        if not getattr(self, 'initialised', False):
+            self.initialised = True
+
+            self.in_holding = {}
+            self.holding_dir = Config()["Dir::Queue::Holding"]
 
     def copy_to_holding(self, filename):
         base_filename = os.path.basename(filename)
diff --git a/daklib/lintian.py b/daklib/lintian.py
new file mode 100644 (file)
index 0000000..3d1afc8
--- /dev/null
@@ -0,0 +1,58 @@
+from regexes import re_parse_lintian
+
+def parse_lintian_output(output):
+    """
+    Parses Lintian output and returns a generator with the data.
+
+    >>> list(parse_lintian_output('W: pkgname: some-tag path/to/file'))
+    [('W', 'pkgname', 'some-tag', 'path/to/file')]
+    """
+
+    for line in output.split('\n'):
+        m = re_parse_lintian.match(line)
+        if m:
+            yield m.groupdict()
+
+def generate_reject_messages(parsed_tags, tag_definitions, log=lambda *args: args):
+    """
+    Generates package reject messages by comparing parsed lintian output with
+    tag definitions. Returns a generator containing the reject messages.
+    """
+
+    tags = set()
+    for values in tag_definitions.values():
+        for tag_name in values:
+            tags.add(tag_name)
+
+    for tag in parsed_tags:
+        tag_name = tag['tag']
+
+        if tag_name not in tags:
+            continue
+
+        # Was tag overridden?
+        if tag['level'] == 'O':
+
+            if tag_name in tag_definitions['nonfatal']:
+                # Overriding this tag is allowed.
+                pass
+
+            elif tag_name in tag_definitions['fatal']:
+                # Overriding this tag is NOT allowed.
+
+                log('ftpmaster does not allow tag to be overridable', tag_name)
+                yield "%(package)s: Overriden tag %(tag)s found, but this " \
+                    "tag may not be overridden." % tag
+
+        else:
+            # Tag is known and not overridden; reject
+            yield "%(package)s: lintian output: '%(tag)s %(description)s', " \
+                "automatically rejected package." % tag
+
+            # Now tell if they *might* override it.
+            if tag_name in tag_definitions['nonfatal']:
+                log("auto rejecting", "overridable", tag_name)
+                yield "%(package)s: If you have a good reason, you may " \
+                   "override this lintian tag." % tag
+            else:
+                log("auto rejecting", "not overridable", tag_name)
old mode 100755 (executable)
new mode 100644 (file)
index 9526852..a91bcdf
@@ -54,6 +54,7 @@ from summarystats import SummaryStats
 from utils import parse_changes, check_dsc_files
 from textutils import fix_maintainer
 from binary import Binary
+from lintian import parse_lintian_output, generate_reject_messages
 
 ###############################################################################
 
@@ -1247,6 +1248,11 @@ class Upload(object):
     ###########################################################################
 
     def check_lintian(self):
+        """
+        Extends self.rejects by checking the output of lintian against tags
+        specified in Dinstall::LintianTags.
+        """
+
         cnf = Config()
 
         # Don't reject binary uploads
@@ -1254,24 +1260,22 @@ class Upload(object):
             return
 
         # Only check some distributions
-        valid_dist = False
         for dist in ('unstable', 'experimental'):
             if dist in self.pkg.changes['distribution']:
-                valid_dist = True
                 break
-
-        if not valid_dist:
+        else:
             return
 
+        # If we do not have a tagfile, don't do anything
         tagfile = cnf.get("Dinstall::LintianTags")
         if tagfile is None:
-            # We don't have a tagfile, so just don't do anything.
             return
 
         # Parse the yaml file
         sourcefile = file(tagfile, 'r')
         sourcecontent = sourcefile.read()
         sourcefile.close()
+
         try:
             lintiantags = yaml.load(sourcecontent)['lintian']
         except yaml.YAMLError, msg:
@@ -1281,78 +1285,42 @@ class Upload(object):
         # Try and find all orig mentioned in the .dsc
         symlinked = self.ensure_orig()
 
-        # Now setup the input file for lintian. lintian wants "one tag per line" only,
-        # so put it together like it. We put all types of tags in one file and then sort
-        # through lintians output later to see if its a fatal tag we detected, or not.
-        # So we only run lintian once on all tags, even if we might reject on some, but not
-        # reject on others.
-        # Additionally build up a set of tags
-        tags = set()
-        (fd, temp_filename) = utils.temp_filename()
+        # Setup the input file for lintian
+        fd, temp_filename = utils.temp_filename()
         temptagfile = os.fdopen(fd, 'w')
-        for tagtype in lintiantags:
-            for tag in lintiantags[tagtype]:
-                temptagfile.write("%s\n" % tag)
-                tags.add(tag)
+        for tags in lintiantags.values():
+            temptagfile.writelines(['%s\n' % x for x in tags])
         temptagfile.close()
 
-        # So now we should look at running lintian at the .changes file, capturing output
-        # to then parse it.
-        command = "lintian --show-overrides --tags-from-file %s %s" % (temp_filename, self.pkg.changes_file)
-        (result, output) = commands.getstatusoutput(command)
+        try:
+            cmd = "lintian --show-overrides --tags-from-file %s %s" % \
+                (temp_filename, self.pkg.changes_file)
 
-        # We are done with lintian, remove our tempfile and any symlinks we created
-        os.unlink(temp_filename)
-        for symlink in symlinked:
-            os.unlink(symlink)
+            result, output = commands.getstatusoutput(cmd)
+        finally:
+            # Remove our tempfile and any symlinks we created
+            os.unlink(temp_filename)
 
-        if (result == 2):
-            utils.warn("lintian failed for %s [return code: %s]." % (self.pkg.changes_file, result))
-            utils.warn(utils.prefix_multi_line_string(output, " [possible output:] "))
+            for symlink in symlinked:
+                os.unlink(symlink)
 
-        if len(output) == 0:
-            return
+        if result == 2:
+            utils.warn("lintian failed for %s [return code: %s]." % \
+                (self.pkg.changes_file, result))
+            utils.warn(utils.prefix_multi_line_string(output, \
+                " [possible output:] "))
 
         def log(*txt):
             if self.logger:
-                self.logger.log([self.pkg.changes_file, "check_lintian"] + list(txt))
-
-        # We have output of lintian, this package isn't clean. Lets parse it and see if we
-        # are having a victim for a reject.
-        # W: tzdata: binary-without-manpage usr/sbin/tzconfig
-        for line in output.split('\n'):
-            m = re_parse_lintian.match(line)
-            if m is None:
-                continue
-
-            etype = m.group(1)
-            epackage = m.group(2)
-            etag = m.group(3)
-            etext = m.group(4)
-
-            # So lets check if we know the tag at all.
-            if etag not in tags:
-                continue
+                self.logger.log(
+                    [self.pkg.changes_file, "check_lintian"] + list(txt)
+                )
 
-            if etype == 'O':
-                # We know it and it is overriden. Check that override is allowed.
-                if etag in lintiantags['warning']:
-                    # The tag is overriden, and it is allowed to be overriden.
-                    # Don't add a reject message.
-                    pass
-                elif etag in lintiantags['error']:
-                    # The tag is overriden - but is not allowed to be
-                    self.rejects.append("%s: Overriden tag %s found, but this tag may not be overwritten." % (epackage, etag))
-                    log("ftpmaster does not allow tag to be overridable", etag)
-            else:
-                # Tag is known, it is not overriden, direct reject.
-                self.rejects.append("%s: Found lintian output: '%s %s', automatically rejected package." % (epackage, etag, etext))
-                # Now tell if they *might* override it.
-                if etag in lintiantags['warning']:
-                    log("auto rejecting", "overridable", etag)
-                    self.rejects.append("%s: If you have a good reason, you may override this lintian tag." % (epackage))
-                else:
-                    log("auto rejecting", "not overridable", etag)
+        # Generate messages
+        parsed_tags = parse_lintian_output(output)
+        self.rejects.extend(
+            generate_reject_messages(parsed_tags, lintiantags, log=log)
+        )
 
     ###########################################################################
     def check_urgency(self):
@@ -2362,8 +2330,6 @@ distribution."""
     ################################################################################
 
     def check_source_against_db(self, filename, session):
-        """
-        """
         source = self.pkg.dsc.get("source")
         version = self.pkg.dsc.get("version")
 
old mode 100755 (executable)
new mode 100644 (file)
index 6be9997..9040e21
@@ -112,4 +112,4 @@ re_user_mails = re.compile(r"^(pub|uid):[^rdin].*<(.*@.*)>.*$", re.MULTILINE);
 re_user_name = re.compile(r"^pub:.*:(.*)<.*$", re.MULTILINE);
 re_re_mark = re.compile(r'^RE:')
 
-re_parse_lintian = re.compile(r"^(W|E|O): (.*?): ([^ ]*) ?(.*)$")
+re_parse_lintian = re.compile(r"^(?P<level>W|E|O): (?P<package>.*?): (?P<tag>[^ ]*) ?(?P<description>.*)$")
diff --git a/daklib/singleton.py b/daklib/singleton.py
deleted file mode 100644 (file)
index 535a25a..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-# vim:set et ts=4 sw=4:
-
-"""
-Singleton pattern code
-
-Inspiration for this very simple ABC was taken from various documents /
-tutorials / mailing lists.  This may not be thread safe but given that
-(as I write) large chunks of dak aren't even type-safe, I'll live with
-it for now
-
-@contact: Debian FTPMaster <ftpmaster@debian.org>
-@copyright: 2008  Mark Hymers <mhy@debian.org>
-@license: GNU General Public License version 2 or later
-"""
-
-################################################################################
-
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-################################################################################
-
-# < sgran> NCommander: in SQL, it's better to join than to repeat information
-# < tomv_w> that makes SQL the opposite to Debian mailing lists!
-
-################################################################################
-
-"""
-This class set implements objects that may need to be instantiated multiple
-times, but we don't want the overhead of actually creating and init'ing
-them more than once.  It also saves us using globals all over the place
-"""
-
-class Singleton(object):
-    """This is the ABC for other dak Singleton classes"""
-    __single = None
-    def __new__(cls, *args, **kwargs):
-        # Check to see if a __single exists already for this class
-        # Compare class types instead of just looking for None so
-        # that subclasses will create their own __single objects
-        if cls != type(cls.__single):
-            cls.__single = object.__new__(cls, *args, **kwargs)
-            cls.__single._startup(*args, **kwargs)
-        return cls.__single
-
-    def __init__(self, *args, **kwargs):
-        if type(self) == "Singleton":
-            raise NotImplementedError("Singleton is an ABC")
-
-    def _startup(self):
-        """
-        _startup is a private method used instead of __init__ due to the way
-        we instantiate this object
-        """
-        raise NotImplementedError("Singleton is an ABC")
-
old mode 100755 (executable)
new mode 100644 (file)
index 86300cc..60702c3
@@ -26,16 +26,15 @@ Simple summary class for dak
 
 ###############################################################################
 
-from singleton import Singleton
+class SummaryStats(object):
+    __shared_state = {}
 
-###############################################################################
-
-class SummaryStats(Singleton):
     def __init__(self, *args, **kwargs):
-        super(SummaryStats, self).__init__(*args, **kwargs)
+        self.__dict__ = self.__shared_state
 
-    def _startup(self):
-        self.reset_accept()
+        if not getattr(self, 'initialised', False):
+            self.initialised = True
+            self.reset_accept()
 
     def reset_accept(self):
         self.accept_count = 0
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index fb2e7fa..7d67905
@@ -29,33 +29,35 @@ Urgency Logger class for dak
 import os
 import time
 
-from singleton import Singleton
 from config import Config
 from utils import warn, open_file, move
 
 ###############################################################################
 
-class UrgencyLog(Singleton):
+class UrgencyLog(object):
     "Urgency Logger object"
+
+    __shared_state = {}
+
     def __init__(self, *args, **kwargs):
-        super(UrgencyLog, self).__init__(*args, **kwargs)
+        self.__dict__ = self.__shared_state
 
-    def _startup(self):
-        "Initialize a new Urgency Logger object"
+        if not getattr(self, 'initialised', False):
+            self.initialised = True
 
-        self.timestamp = time.strftime("%Y%m%d%H%M%S")
+            self.timestamp = time.strftime("%Y%m%d%H%M%S")
 
-        # Create the log directory if it doesn't exist
-        self.log_dir = Config()["Dir::UrgencyLog"]
+            # Create the log directory if it doesn't exist
+            self.log_dir = Config()["Dir::UrgencyLog"]
 
-        if not os.path.exists(self.log_dir) or not os.access(self.log_dir, os.W_OK):
-            warn("UrgencyLog directory %s does not exist or is not writeable, using /srv/ftp.debian.org/tmp/ instead" % (self.log_dir))
-            self.log_dir = '/srv/ftp.debian.org/tmp/'
+            if not os.path.exists(self.log_dir) or not os.access(self.log_dir, os.W_OK):
+                warn("UrgencyLog directory %s does not exist or is not writeable, using /srv/ftp.debian.org/tmp/ instead" % (self.log_dir))
+                self.log_dir = '/srv/ftp.debian.org/tmp/'
 
-        # Open the logfile
-        self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp)
-        self.log_file = open_file(self.log_filename, 'w')
-        self.writes = 0
+            # Open the logfile
+            self.log_filename = "%s/.install-urgencies-%s.new" % (self.log_dir, self.timestamp)
+            self.log_file = open_file(self.log_filename, 'w')
+            self.writes = 0
 
     def log(self, source, version, urgency):
         "Log an event"
old mode 100755 (executable)
new mode 100644 (file)
index 0528748..3cc4053
@@ -712,24 +712,23 @@ def where_am_i ():
         return res[0]
 
 def which_conf_file ():
-    if os.getenv("DAK_CONFIG"):
-        print(os.getenv("DAK_CONFIG"))
-        return os.getenv("DAK_CONFIG")
-    else:
-        res = socket.gethostbyaddr(socket.gethostname())
-        # In case we allow local config files per user, try if one exists
-        if Cnf.FindB("Config::" + res[0] + "::AllowLocalConfig"):
-            homedir = os.getenv("HOME")
-            confpath = os.path.join(homedir, "/etc/dak.conf")
-            if os.path.exists(confpath):
-                apt_pkg.ReadConfigFileISC(Cnf,default_config)
-
-        # We are still in here, so there is no local config file or we do
-        # not allow local files. Do the normal stuff.
-        if Cnf.get("Config::" + res[0] + "::DakConfig"):
-            return Cnf["Config::" + res[0] + "::DakConfig"]
-        else:
-            return default_config
+    if os.getenv('DAK_CONFIG'):
+        return os.getenv('DAK_CONFIG')
+
+    res = socket.gethostbyaddr(socket.gethostname())
+    # In case we allow local config files per user, try if one exists
+    if Cnf.FindB("Config::" + res[0] + "::AllowLocalConfig"):
+        homedir = os.getenv("HOME")
+        confpath = os.path.join(homedir, "/etc/dak.conf")
+        if os.path.exists(confpath):
+            apt_pkg.ReadConfigFileISC(Cnf,default_config)
+
+    # We are still in here, so there is no local config file or we do
+    # not allow local files. Do the normal stuff.
+    if Cnf.get("Config::" + res[0] + "::DakConfig"):
+        return Cnf["Config::" + res[0] + "::DakConfig"]
+
+    return default_config
 
 def which_apt_conf_file ():
     res = socket.gethostbyaddr(socket.gethostname())
@@ -1504,7 +1503,8 @@ def get_changes_files(from_dir):
 apt_pkg.init()
 
 Cnf = apt_pkg.newConfiguration()
-apt_pkg.ReadConfigFileISC(Cnf,default_config)
+if not os.getenv("DAK_TEST"):
+    apt_pkg.ReadConfigFileISC(Cnf,default_config)
 
 if which_conf_file() != default_config:
     apt_pkg.ReadConfigFileISC(Cnf,which_conf_file())
diff --git a/tests/base_test.py b/tests/base_test.py
new file mode 100644 (file)
index 0000000..d99ce41
--- /dev/null
@@ -0,0 +1,20 @@
+import os
+import sys
+import unittest
+
+from os.path import abspath, dirname, join
+
+DAK_ROOT_DIR = dirname(dirname(abspath(__file__)))
+
+class DakTestCase(unittest.TestCase):
+    def setUp(self):
+        pass
+
+def fixture(*dirs):
+    return join(DAK_ROOT_DIR, 'tests', 'fixtures', *dirs)
+
+os.environ['DAK_TEST'] = '1'
+os.environ['DAK_CONFIG'] = fixture('dak.conf')
+
+if DAK_ROOT_DIR not in sys.path:
+    sys.path.insert(0, DAK_ROOT_DIR)
diff --git a/tests/fixtures/changes/1.changes b/tests/fixtures/changes/1.changes
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/fixtures/changes/2.changes b/tests/fixtures/changes/2.changes
new file mode 100644 (file)
index 0000000..9d264c1
--- /dev/null
@@ -0,0 +1,54 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+
+Format: 1.7
+Date: Fri, 20 Apr 2001 02:47:21 -0400
+Source: krb5
+Binary: krb5-kdc krb5-doc krb5-rsh-server libkrb5-dev libkrb53 krb5-ftpd
+ krb5-clients krb5-user libkadm54 krb5-telnetd krb5-admin-server
+Architecture: m68k
+Version: 1.2.2-4
+Distribution: unstable
+Urgency: low
+Maintainer: buildd m68k user account <buildd@ax.westfalen.de>
+Changed-By: Sam Hartman <hartmans@debian.org>
+Description: 
+ krb5-admin-server - Mit Kerberos master server (kadmind)
+ krb5-clients - Secure replacements for ftp, telnet and rsh using MIT Kerberos
+ krb5-ftpd  - Secure FTP server supporting MIT Kerberos
+ krb5-kdc   - Mit Kerberos key server (KDC)
+ krb5-rsh-server - Secure replacements for rshd and rlogind  using MIT Kerberos
+ krb5-telnetd - Secure telnet server supporting MIT Kerberos
+ krb5-user  - Basic programs to authenticate using MIT Kerberos
+ libkadm54  - MIT Kerberos administration runtime libraries
+ libkrb5-dev - Headers and development libraries for MIT Kerberos
+ libkrb53   - MIT Kerberos runtime libraries
+Closes: 94407
+Changes: 
+ krb5 (1.2.2-4) unstable; urgency=low
+ .
+   * Fix shared libraries to build with gcc not ld to properly include
+     -lgcc symbols, closes: #94407
+Files: 
+ 563dac1cdd3ba922f9301fe074fbfc80 65836 non-us/main optional libkadm54_1.2.2-4_m68k.deb
+ bb620f589c17ab0ebea1aa6e10ca52ad 272198 non-us/main optional libkrb53_1.2.2-4_m68k.deb
+ 40af6e64b3030a179e0de25bd95c95e9 143264 non-us/main optional krb5-user_1.2.2-4_m68k.deb
+ ffe4e5e7b2cab162dc608d56278276cf 141870 non-us/main optional krb5-clients_1.2.2-4_m68k.deb
+ 4fe01d1acb4b82ce0b8b72652a9a15ae 54592 non-us/main optional krb5-rsh-server_1.2.2-4_m68k.deb
+ b3c8c617ea72008a33b869b75d2485bf 41292 non-us/main optional krb5-ftpd_1.2.2-4_m68k.deb
+ 5908f8f60fe536d7bfc1ef3fdd9d74cc 42090 non-us/main optional krb5-telnetd_1.2.2-4_m68k.deb
+ 650ea769009a312396e56503d0059ebc 160236 non-us/main optional krb5-kdc_1.2.2-4_m68k.deb
+ 399c9de4e9d7d0b0f5626793808a4391 160392 non-us/main optional krb5-admin-server_1.2.2-4_m68k.deb
+ 6f962fe530c3187e986268b4e4d27de9 398662 non-us/main optional libkrb5-dev_1.2.2-4_m68k.deb
+
+-----BEGIN PGP SIGNATURE-----
+Version: 2.6.3i
+Charset: noconv
+
+iQCVAwUBOvVPPm547I3m3eHJAQHyaQP+M7RXVEqZ2/xHiPzaPcZRJ4q7o0zbMaU8
+qG/Mi6kuR1EhRNMjMH4Cp6ctbhRDHK5FR/8v7UkOd+ETDAhiw7eqJnLC60EZxZ/H
+CiOs8JklAXDERkQ3i7EYybv46Gxx91pIs2nE4xVKnG16d/wFELWMBLY6skF1B2/g
+zZju3cuFCCE=
+=Vm59
+-----END PGP SIGNATURE-----
+
+
diff --git a/tests/fixtures/changes/bogus-post.changes b/tests/fixtures/changes/bogus-post.changes
new file mode 100644 (file)
index 0000000..95e5a1f
--- /dev/null
@@ -0,0 +1,41 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.7
+Date: Tue,  9 Sep 2003 01:16:01 +0100
+Source: gawk
+Binary: gawk
+Architecture: source i386
+Version: 1:3.1.3-2
+Distribution: unstable
+Urgency: low
+Maintainer: James Troup <james@nocrew.org>
+Changed-By: James Troup <james@nocrew.org>
+Description: 
+ gawk       - GNU awk, a pattern scanning and processing language
+Closes: 204699 204701
+Changes: 
+ gawk (1:3.1.3-2) unstable; urgency=low
+ .
+   * debian/control (Standards-Version): bump to 3.6.1.0.
+ .
+   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
+     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
+     upstream.  Closes: #204701
+ .
+   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
+     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
+     forwarding it upstream.  Closes: #204699
+Files: 
+ 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
+ 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
+ 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.6 (GNU/Linux)
+
+iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
+fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
+=O7Gh
+-----END PGP SIGNATURE-----
+You: have been 0wned
diff --git a/tests/fixtures/changes/bogus-pre.changes b/tests/fixtures/changes/bogus-pre.changes
new file mode 100644 (file)
index 0000000..0234d8b
--- /dev/null
@@ -0,0 +1,41 @@
+You: have been 0wned
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.7
+Date: Tue,  9 Sep 2003 01:16:01 +0100
+Source: gawk
+Binary: gawk
+Architecture: source i386
+Version: 1:3.1.3-2
+Distribution: unstable
+Urgency: low
+Maintainer: James Troup <james@nocrew.org>
+Changed-By: James Troup <james@nocrew.org>
+Description: 
+ gawk       - GNU awk, a pattern scanning and processing language
+Closes: 204699 204701
+Changes: 
+ gawk (1:3.1.3-2) unstable; urgency=low
+ .
+   * debian/control (Standards-Version): bump to 3.6.1.0.
+ .
+   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
+     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
+     upstream.  Closes: #204701
+ .
+   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
+     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
+     forwarding it upstream.  Closes: #204699
+Files: 
+ 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
+ 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
+ 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.6 (GNU/Linux)
+
+iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
+fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
+=O7Gh
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/changes/valid.changes b/tests/fixtures/changes/valid.changes
new file mode 100644 (file)
index 0000000..0e77d27
--- /dev/null
@@ -0,0 +1,40 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.7
+Date: Tue,  9 Sep 2003 01:16:01 +0100
+Source: gawk
+Binary: gawk
+Architecture: source i386
+Version: 1:3.1.3-2
+Distribution: unstable
+Urgency: low
+Maintainer: James Troup <james@nocrew.org>
+Changed-By: James Troup <james@nocrew.org>
+Description: 
+ gawk       - GNU awk, a pattern scanning and processing language
+Closes: 204699 204701
+Changes: 
+ gawk (1:3.1.3-2) unstable; urgency=low
+ .
+   * debian/control (Standards-Version): bump to 3.6.1.0.
+ .
+   * 02_fix-ascii.dpatch: new patch from upstream to fix [[:ascii:]].
+     Thanks to <vle@gmx.net> for reporting the bug and forwarding it
+     upstream.  Closes: #204701
+ .
+   * 03_fix-high-char-ranges.dpatch: new patch from upstream to fix
+     [\x80-\xff].  Thanks to <vle@gmx.net> for reporting the bug and
+     forwarding it upstream.  Closes: #204699
+Files: 
+ 0e6542c48bcc9d9586fc8ebe4e7242a4 561 interpreters optional gawk_3.1.3-2.dsc
+ 50a29dce4a2c6e2ac38069eb7c41d9c4 8302 interpreters optional gawk_3.1.3-2.diff.gz
+ 5a255c7b421ac699804212e10205f22d 871114 interpreters optional gawk_3.1.3-2_i386.deb
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.6 (GNU/Linux)
+
+iEYEARECAAYFAj9dHWsACgkQgD/uEicUG7DUnACglndvU4LCA0/k36Qp873N0Sau
+fCwAoMdgIOUBcUfMqXvVnxdW03ev5bNB
+=O7Gh
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dak.conf b/tests/fixtures/dak.conf
new file mode 100644 (file)
index 0000000..94992fe
--- /dev/null
@@ -0,0 +1,19 @@
+# For extract_component_from_section tests
+
+Component
+{
+  main
+  {
+       Description "Main";
+  };
+
+  contrib
+  {
+       Description "Contrib";
+  };
+
+  non-free
+  {
+       Description "Software that fails to meet the DFSG";
+  };
+};
diff --git a/tests/fixtures/dsc/1.dsc b/tests/fixtures/dsc/1.dsc
new file mode 100644 (file)
index 0000000..dfdd92f
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/2.dsc b/tests/fixtures/dsc/2.dsc
new file mode 100644 (file)
index 0000000..a6c9d85
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/3.dsc b/tests/fixtures/dsc/3.dsc
new file mode 100644 (file)
index 0000000..211340e
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/4.dsc b/tests/fixtures/dsc/4.dsc
new file mode 100644 (file)
index 0000000..91e361f
--- /dev/null
@@ -0,0 +1,19 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/5.dsc b/tests/fixtures/dsc/5.dsc
new file mode 100644 (file)
index 0000000..db9d8d3
--- /dev/null
@@ -0,0 +1,23 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/6.dsc b/tests/fixtures/dsc/6.dsc
new file mode 100644 (file)
index 0000000..ae36d64
--- /dev/null
@@ -0,0 +1,23 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+
+Format: 1.0
+Source: amaya
+Version: 3.2.1-1
+Binary: amaya
+Maintainer: Steve Dunham <dunham@debian.org>
+Architecture: any
+Standards-Version: 2.4.0.0
+Files: 
+ 07f95f92b7cb0f12f7cf65ee5c5fbde2 4532418 amaya_3.2.1.orig.tar.gz
+ da06b390946745d9efaf9e7df8e05092 4817 amaya_3.2.1-1.diff.gz
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.2 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE5j091iPgEjVqvb1kRAvFtAJ0asUAaac6ebfR3YeaH16HjL7F3GwCfV+AQ
+rhYnRmVuNMa8oYSvL4hl/Yw=
+=EFAA
+-----END PGP SIGNATURE-----
diff --git a/tests/fixtures/dsc/7.dsc b/tests/fixtures/dsc/7.dsc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/test_extract_component_from_section.py b/tests/test_extract_component_from_section.py
new file mode 100755 (executable)
index 0000000..3493f41
--- /dev/null
@@ -0,0 +1,59 @@
+#!/usr/bin/env python
+
+from base_test import DakTestCase
+
+import unittest
+
+from daklib.utils import extract_component_from_section
+
+class ExtractComponentTestCase(DakTestCase):
+    """
+    prefix: non-US
+    component: main, contrib, non-free
+    section: games, admin, libs, [...]
+
+    [1] Order is as above.
+    [2] Prefix is optional for the default archive, but mandatory when
+        uploads are going anywhere else.
+    [3] Default component is main and may be omitted.
+    [4] Section is optional.
+    [5] Prefix is case insensitive
+    [6] Everything else is case sensitive.
+    """
+
+    def assertExtract(self, input, output):
+        self.assertEqual(
+            extract_component_from_section(input)[1],
+            output,
+        )
+
+    def test_1(self):
+        # Validate #3
+        self.assertExtract('utils', 'main')
+
+    def test_2(self):
+        # Err, whoops?  should probably be 'utils', 'main'...
+        self.assertExtract('main/utils', 'main')
+
+    def test_3(self):
+        self.assertExtract('non-free/libs', 'non-free')
+
+    def test_4(self):
+        self.assertExtract('contrib/net', 'contrib')
+
+    def test_5(self):
+        # Validate #4
+        self.assertExtract('main', 'main')
+
+    def test_6(self):
+        self.assertExtract('contrib', 'contrib')
+
+    def test_7(self):
+        self.assertExtract('non-free', 'non-free')
+
+    def test_8(self):
+        # Validate #6 (section)
+        self.assertExtract('utIls', 'main')
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_fix_maintainer.py b/tests/test_fix_maintainer.py
new file mode 100755 (executable)
index 0000000..203fbfc
--- /dev/null
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from base_test import DakTestCase
+
+import unittest
+
+from daklib.textutils import fix_maintainer
+from daklib.dak_exceptions import ParseMaintError
+
+class FixMaintainerTestCase(DakTestCase):
+    def assertValid(self, input, a, b, c, d):
+        a_, b_, c_, d_ = fix_maintainer(input)
+
+        self.assertEqual(a, a_)
+        self.assertEqual(b, b_)
+        self.assertEqual(c, c_)
+        self.assertEqual(d, d_)
+
+    def assertNotValid(self, input):
+        self.assertRaises(ParseMaintError, lambda: fix_maintainer(input))
+
+    def testUTF8Maintainer(self):
+        # Check Valid UTF-8 maintainer field
+        self.assertValid(
+            "Noèl Köthe <noel@debian.org>",
+            "Noèl Köthe <noel@debian.org>",
+            "=?utf-8?b?Tm/DqGwgS8O2dGhl?= <noel@debian.org>",
+            "Noèl Köthe",
+            "noel@debian.org",
+        )
+
+    def testASCII(self):
+        # Check valid ASCII maintainer field
+        self.assertValid(
+            "James Troup <james@nocrew.org>",
+            "James Troup <james@nocrew.org>",
+            "James Troup <james@nocrew.org>",
+            "James Troup",
+            "james@nocrew.org",
+        )
+
+    def testRFC822(self):
+        # Check "Debian vs RFC822" fixup of names with '.' or ',' in them
+        self.assertValid(
+            "James J. Troup <james@nocrew.org>",
+            "james@nocrew.org (James J. Troup)",
+            "james@nocrew.org (James J. Troup)",
+            "James J. Troup",
+            "james@nocrew.org",
+        )
+
+    def testSimple(self):
+        self.assertValid(
+            "James J, Troup <james@nocrew.org>",
+            "james@nocrew.org (James J, Troup)",
+            "james@nocrew.org (James J, Troup)",
+            "James J, Troup",
+            "james@nocrew.org",
+        )
+
+    def testJustEmail(self):
+        # Check just-email form
+        self.assertValid(
+            "james@nocrew.org",
+            " <james@nocrew.org>",
+            " <james@nocrew.org>",
+            "",
+            "james@nocrew.org",
+        )
+
+    def testBracketedEmail(self):
+        # Check bracketed just-email form
+        self.assertValid(
+            "<james@nocrew.org>",
+            " <james@nocrew.org>",
+            " <james@nocrew.org>",
+            "",
+            "james@nocrew.org",
+        )
+
+    def testKrazy(self):
+        # Check Krazy quoted-string local part email address
+        self.assertValid(
+            "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>",
+            "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>",
+            "Cris van Pelt <\"Cris van Pelt\"@tribe.eu.org>",
+            "Cris van Pelt",
+            "\"Cris van Pelt\"@tribe.eu.org",
+        )
+
+    def testEmptyString(self):
+        # Check empty string
+        self.assertValid("", "", "", "", "")
+
+    def testMissingEmailAddress(self):
+        # Check for missing email address
+        self.assertNotValid("James Troup")
+
+    def testInvalidEmail(self):
+        # Check for invalid email address
+        self.assertNotValid("James Troup <james@nocrew.org")
+
+if __name__ == '__main__':
+    unittest.main()
index 1ae6860aa60659ba890e9f00c31b1c02a9945ac9..a897eeb0b7df98a92b0c7b9acde9039363cd2fba 100755 (executable)
@@ -1,14 +1,13 @@
 #!/usr/bin/env python
 
-import unittest
+from base_test import DakTestCase
 
-import os, sys
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import unittest
 
 from daklib.formats import parse_format, validate_changes_format
 from daklib.dak_exceptions import UnknownFormatError
 
-class ParseFormatTestCase(unittest.TestCase):
+class ParseFormatTestCase(DakTestCase):
     def assertParse(self, format, expected):
         self.assertEqual(parse_format(format), expected)
 
@@ -30,7 +29,7 @@ class ParseFormatTestCase(unittest.TestCase):
         self.assertParse('1.2 (three)', (1, 2, 'three'))
         self.assertParseFail('0.0 ()')
 
-class ValidateChangesFormat(unittest.TestCase):
+class ValidateChangesFormat(DakTestCase):
     def assertValid(self, changes, field='files'):
         validate_changes_format(changes, field)
 
@@ -56,3 +55,6 @@ class ValidateChangesFormat(unittest.TestCase):
     def testFilesField(self):
         self.assertInvalid((1, 7), field='notfiles')
         self.assertValid((1, 8), field='notfiles')
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_lintian.py b/tests/test_lintian.py
new file mode 100755 (executable)
index 0000000..f4ed98e
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+
+from base_test import DakTestCase
+
+import unittest
+
+from daklib.lintian import parse_lintian_output, generate_reject_messages
+
+class ParseLintianTestCase(DakTestCase):
+    def assertParse(self, output, expected):
+        self.assertEqual(
+            list(parse_lintian_output(output)),
+            expected,
+        )
+
+    def testSimple(self):
+        self.assertParse(
+            'W: pkgname: some-tag path/to/file', [{
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'some-tag',
+                'description': 'path/to/file',
+            }],
+        )
+
+        self.assertParse('', [])
+        self.assertParse('\n\n', [])
+        self.assertParse('dummy error test', [])
+
+    def testBinaryNoDescription(self):
+        self.assertParse(
+            'W: pkgname: some-tag', [{
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'some-tag',
+                'description': '',
+            }],
+        )
+
+    def testSource(self):
+        self.assertParse(
+            'W: pkgname source: some-tag', [{
+                'level': 'W',
+                'package': 'pkgname source',
+                'tag': 'some-tag',
+                'description': '',
+            }]
+        )
+
+    def testSourceNoDescription(self):
+        self.assertParse(
+            'W: pkgname source: some-tag path/to/file', [{
+                'level': 'W',
+                'package': 'pkgname source',
+                'tag': 'some-tag',
+                'description': 'path/to/file',
+            }]
+        )
+
+class GenerateRejectMessages(DakTestCase):
+    def assertNumReject(self, input, defs, num):
+        msgs = list(generate_reject_messages(input, defs))
+        self.assertEqual(len(msgs), num)
+
+    def testUnknownTag(self):
+        self.assertNumReject([
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'unknown-tag',
+                'description': '',
+            }
+            ], {'fatal': ['known-tag'], 'nonfatal': []},
+            0,
+        )
+
+    def testFatalTags(self):
+        self.assertNumReject([
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'fatal-tag-1',
+                'description': '',
+            },
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'fatal-tag-2',
+                'description': '',
+            },
+            ], {'fatal': ['fatal-tag-1', 'fatal-tag-2'], 'nonfatal': []},
+            2,
+        )
+
+    def testMixture(self):
+        self.assertNumReject([
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'fatal-tag',
+                'description': '',
+            },
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'unknown-tag',
+                'description': '',
+            },
+            ], {'fatal': ['fatal-tag'], 'nonfatal': []},
+            1,
+        )
+
+    def testOverridable(self):
+        self.assertNumReject([
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'non-fatal-tag',
+                'description': '',
+            },
+            ], {'fatal': [], 'nonfatal': ['non-fatal-tag']},
+            1 + 1, # We add an extra 'reject' hint message
+        )
+
+    def testOverrideAllowed(self):
+        self.assertNumReject([
+                {'level': 'O',
+                'package': 'pkgname',
+                'tag': 'non-fatal-tag',
+                'description': ''},
+            ], {'fatal': [], 'nonfatal': ['non-fatal-tag']},
+            0,
+        )
+
+    def testOverrideNotAllowed(self):
+        self.assertNumReject([
+            {
+                'level': 'O',
+                'package': 'pkgname',
+                'tag': 'fatal-tag',
+                'description': '',
+            },
+            ], {'fatal': ['fatal-tag'], 'nonfatal': []},
+            1,
+        )
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_parse_changes.py b/tests/test_parse_changes.py
new file mode 100755 (executable)
index 0000000..2de4b8a
--- /dev/null
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+from base_test import DakTestCase, fixture
+
+import unittest
+
+from daklib.utils import parse_changes
+from daklib.dak_exceptions import InvalidDscError, ParseChangesError
+
+class ParseChangesTestCase(DakTestCase):
+    def assertParse(self, filename, *args):
+        return parse_changes(fixture(filename), *args)
+
+    def assertFails(self, filename, line=None, *args):
+        try:
+            self.assertParse(filename, *args)
+            self.fail('%s was not recognised as invalid' % filename)
+        except ParseChangesError:
+            pass
+        except InvalidDscError, actual_line:
+            if line is not None:
+                assertEqual(actual_line, line)
+
+class ParseDscTestCase(ParseChangesTestCase):
+    def test_1(self):
+        self.assertParse('dsc/1.dsc')
+
+    def test_1_ignoreErrors(self):
+        # Valid .dsc ; ignoring errors
+        self.assertParse('dsc/1.dsc', 0)
+
+    def test_2(self):
+        # Missing blank line before signature body
+        self.assertParse('dsc/2.dsc')
+
+    def test_2_ignoreErrors(self):
+        # Invalid .dsc ; ignoring errors
+        self.assertParse('dsc/2.dsc', 0)
+
+    def test_3(self):
+        # Missing blank line after signature header
+        self.assertParse('dsc/3.dsc')
+
+    def test_4(self):
+        # No blank lines at all
+        self.assertParse('dsc/4.dsc')
+
+    def test_5(self):
+        # Extra blank line before signature body
+        self.assertParse('dsc/5.dsc')
+
+    def test_6(self):
+        # Extra blank line after signature header
+        self.assertParse('dsc/6.dsc')
+
+class ParseChangesTestCase(ParseChangesTestCase):
+    def test_1(self):
+        # Empty changes
+        self.assertFails('changes/1.changes', line=5)
+
+    def test_2(self):
+        changes = self.assertParse('changes/2.changes', 0)
+
+        binaries = changes['binary']
+
+        self.assert_('krb5-ftpd' in binaries.split())
+
+    def test_3(self):
+        for filename in ('valid', 'bogus-pre', 'bogus-post'):
+            for strict_whitespace in (0, 1):
+                changes = self.assertParse(
+                    'changes/%s.changes' % filename,
+                    strict_whitespace,
+                )
+                self.failIf(changes.get('you'))
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/test_process_gpgv_output.py b/tests/test_process_gpgv_output.py
new file mode 100755 (executable)
index 0000000..ea1fb33
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+from base_test import DakTestCase
+
+import unittest
+
+from daklib.utils import process_gpgv_output
+
+class ProcessGPGVOutputTestCase(DakTestCase):
+    def assertParse(self, input, output):
+        self.assertEqual(process_gpgv_output(input)[0], output)
+
+    def assertNotParse(self, input):
+        ret = process_gpgv_output(input)
+        self.assertNotEqual(len(ret[1]), 0)
+
+    ##
+
+    def testEmpty(self):
+        self.assertParse('', {})
+
+    def testBroken(self):
+        self.assertNotParse('foo')
+        self.assertNotParse('  foo  ')
+        self.assertNotParse('[PREFIXPG:] KEY VAL1 VAL2 VAL3')
+
+    def testSimple(self):
+        self.assertParse(
+            '[GNUPG:] KEY VAL1 VAL2 VAL3',
+            {'KEY': ['VAL1', 'VAL2', 'VAL3']},
+        )
+
+    def testNoKeys(self):
+        self.assertParse('[GNUPG:] KEY', {'KEY': []})
+
+    def testDuplicate(self):
+        self.assertNotParse('[GNUPG:] TEST_KEY\n[GNUPG:] TEST_KEY')
+        self.assertNotParse('[GNUPG:] KEY VAL1\n[GNUPG:] KEY VAL2')
+
+    def testDuplicateSpecial(self):
+        # NODATA and friends are special
+        for special in ('NODATA', 'SIGEXPIRED', 'KEYEXPIRED'):
+            self.assertParse(
+                '[GNUPG:] %s\n[GNUPG:] %s' % (special, special),
+                {special: []},
+            )
+
+if __name__ == '__main__':
+    unittest.main()
index 766e73e49070a86fe798498aee38d9d9d29669dd..bde17275acd2c2509a3107254cbfc977880abaad 100755 (executable)
@@ -1,13 +1,10 @@
 #!/usr/bin/env python
 
-import unittest
-
-import os, sys
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from base_test import DakTestCase
 
 from daklib import regexes
 
-class re_single_line_field(unittest.TestCase):
+class re_single_line_field(DakTestCase):
     MATCH = regexes.re_single_line_field.match
 
     def testSimple(self):
@@ -32,31 +29,51 @@ class re_single_line_field(unittest.TestCase):
         self.assertEqual(self.MATCH('Foo::bar').groups(), ('Foo', ':bar'))
         self.assertEqual(self.MATCH('Foo: :bar').groups(), ('Foo', ':bar'))
 
-class re_parse_lintian(unittest.TestCase):
+class re_parse_lintian(DakTestCase):
     MATCH = regexes.re_parse_lintian.match
 
     def testBinary(self):
         self.assertEqual(
-            self.MATCH('W: pkgname: some-tag path/to/file').groups(),
-            ('W', 'pkgname', 'some-tag', 'path/to/file')
+            self.MATCH('W: pkgname: some-tag path/to/file').groupdict(),
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'some-tag',
+                'description': 'path/to/file',
+            }
         )
 
     def testBinaryNoDescription(self):
         self.assertEqual(
-            self.MATCH('W: pkgname: some-tag').groups(),
-            ('W', 'pkgname', 'some-tag', '')
+            self.MATCH('W: pkgname: some-tag').groupdict(),
+            {
+                'level': 'W',
+                'package': 'pkgname',
+                'tag': 'some-tag',
+                'description': '',
+            }
         )
 
     def testSource(self):
         self.assertEqual(
-            self.MATCH('W: pkgname source: some-tag').groups(),
-            ('W', 'pkgname source', 'some-tag', '')
+            self.MATCH('W: pkgname source: some-tag').groupdict(),
+            {
+                'level': 'W',
+                'package': 'pkgname source',
+                'tag': 'some-tag',
+                'description': '',
+            }
         )
 
     def testSourceNoDescription(self):
         self.assertEqual(
-            self.MATCH('W: pkgname source: some-tag path/to/file').groups(),
-            ('W', 'pkgname source', 'some-tag', 'path/to/file')
+            self.MATCH('W: pkgname source: some-tag path/to/file').groupdict(),
+            {
+                'level': 'W',
+                'package': 'pkgname source',
+                'tag': 'some-tag',
+                'description': 'path/to/file',
+            }
         )
 
 if __name__ == '__main__':
index 4ecaf8b7fcc83925238f2473ed7961714158eee2..fa6f3b386c34aa3706d62b359f2755dc31ca70c1 100755 (executable)
@@ -1,17 +1,13 @@
 #!/usr/bin/env python
 
-import unittest
-
-import os, sys
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-from collections import defaultdict
+from base_test import DakTestCase
 
 from daklib import srcformats
+from collections import defaultdict
 from daklib.formats import parse_format
 from daklib.dak_exceptions import UnknownFormatError
 
-class SourceFormatTestCase(unittest.TestCase):
+class SourceFormatTestCase(DakTestCase):
     def get_rejects(self, has_vars):
         has = defaultdict(lambda: 0)
         has.update(has_vars)
@@ -104,7 +100,7 @@ class FormatTreeQuiltTestCase(SourceFormatTestCase):
             'native_tar': 1,
         })
 
-class FormatFromStringTestCase(unittest.TestCase):
+class FormatFromStringTestCase(DakTestCase):
     def assertFormat(self, txt, klass):
         self.assertEqual(srcformats.get_format_from_string(txt), klass)