Sat, 04 Nov 2006 10:34:06 -0500
[svn] Deal with a bunch of low-hanging fruit:
* Correctly cope with mimetype oddities I found on Fedora.
* I'm not doing anything with shar files yet, so take out that hook.
* Better error handling and reporting throughout, including a meaningful
exit code.
* Remove unused cruft from the BaseExtractor.run method.
* When reporting the "basename" for the archive, make sure it doesn't
include any preceding path.
* If the archive contains one directory whose name doesn't match the
archive basename, rename it after extraction.
- Although I just realized this probably does the wrong thing if there's
just one file in the archive.
1 | 1 | #!/usr/bin/env python |
2 | # | |
3 | # compare.py -- High-level tests for x. | |
4 | # Copyright (c) 2006 Brett Smith <brettcsmith@brettcsmith.org>. | |
5 | # | |
6 | # This program is free software; you can redistribute it and/or modify it | |
7 | # under the terms of the GNU General Public License as published by the | |
8 | # Free Software Foundation; either version 2 of the License, or (at your | |
9 | # option) any later version. | |
10 | # | |
11 | # This program is distributed in the hope that it will be useful, but | |
12 | # WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |
14 | # Public License for more details. | |
15 | # | |
16 | # You should have received a copy of the GNU General Public License along | |
17 | # with this program; if not, write to the Free Software Foundation, Inc., | |
18 | # 51 Franklin Street, 5th Floor, Boston, MA, 02111. | |
19 | ||
20 | import os | |
21 | import subprocess | |
22 | import sys | |
23 | ||
24 | from sets import Set as set | |
25 | ||
26 | TESTSCRIPT_NAME = 'testscript.sh' | |
27 | SCRIPT_PROLOGUE = """#!/bin/sh | |
28 | set -e | |
29 | """ | |
30 | ||
31 | tests = {'test-1.23.tar': ['tar -xf test-1.23.tar'], | |
32 | 'test-1.23.tar.gz': ['tar -xzf test-1.23.tar.gz'], | |
33 | 'test-1.23.tar.bz2': ['mkdir test-1.23', | |
34 | 'cd test-1.23', | |
35 | 'tar -jxf ../test-1.23.tar.bz2'], | |
36 | 'test-1.23.zip': ['mkdir test-1.23', | |
37 | 'cd test-1.23', | |
38 | 'unzip -q ../test-1.23.zip'], | |
39 | 'test-1.23.cpio': ['cpio -i --make-directories \ | |
40 | <test-1.23.cpio 2>/dev/null'], | |
41 | 'test-1.23_all.deb': ['TD=$PWD', | |
42 | 'mkdir test-1.23', | |
43 | 'cd /tmp', | |
44 | 'ar x $TD/test-1.23_all.deb data.tar.gz', | |
45 | 'cd $TD/test-1.23', | |
46 | 'tar -zxf /tmp/data.tar.gz', | |
47 | 'rm /tmp/data.tar.gz']} | |
48 | ||
49 | if os.path.exists('scripts/x') and os.path.exists('tests'): | |
50 | os.chdir('tests') | |
51 | elif os.path.exists('../scripts/x') and os.path.exists('../tests'): | |
52 | pass | |
53 | else: | |
54 | print "ERROR: Can't run tests in this directory!" | |
55 | sys.exit(2) | |
56 | ||
57 | class ExtractorTestError(Exception): | |
58 | pass | |
59 | ||
60 | ||
61 | class ExtractorTest(object): | |
62 | def __init__(self, archive_filename, commands): | |
63 | self.archive_filename = archive_filename | |
64 | self.shell_commands = commands | |
65 | ||
66 | def get_results(self, commands): | |
67 | status = subprocess.call(commands) | |
68 | if status != 0: | |
69 | return None | |
70 | process = subprocess.Popen(['find'], stdout=subprocess.PIPE) | |
71 | process.wait() | |
72 | output = process.stdout.read(-1) | |
73 | process.stdout.close() | |
74 | return set(output.split('\n')) | |
75 | ||
76 | def get_shell_results(self): | |
77 | script = open(TESTSCRIPT_NAME, 'w') | |
78 | script.write("%s%s\n" % (SCRIPT_PROLOGUE, | |
79 | '\n'.join(self.shell_commands))) | |
80 | script.close() | |
81 | subprocess.call(['chmod', 'u+w', TESTSCRIPT_NAME]) | |
82 | return self.get_results(['sh', TESTSCRIPT_NAME]) | |
83 | ||
84 | def get_extractor_results(self): | |
85 | return self.get_results(['../scripts/x', self.archive_filename]) | |
86 | ||
87 | def clean(self): | |
88 | status = subprocess.call(['find', '-mindepth', '1', '-maxdepth', '1', | |
89 | '-type', 'd', | |
90 | '!', '-name', 'CVS', '!', '-name', '.svn', | |
91 | '-exec', 'rm', '-rf', '{}', ';']) | |
92 | if status != 0: | |
93 | raise ExtractorTestError("cleanup exited with status code %s" % | |
94 | (status,)) | |
95 | ||
96 | def run(self): | |
97 | self.clean() | |
98 | expected = self.get_shell_results() | |
99 | self.clean() | |
100 | actual = self.get_extractor_results() | |
101 | self.clean() | |
102 | if expected is None: | |
103 | raise ExtractorTestError("could not get baseline results") | |
104 | elif actual is None: | |
105 | raise ExtractorTestError("could not get extractor results") | |
106 | elif expected != actual: | |
107 | print "FAILED:", self.archive_filename | |
108 | print "Only in baseline results:" | |
109 | print '\n'.join(expected.difference(actual)) | |
110 | print "Only in actual results:" | |
111 | print '\n'.join(actual.difference(expected)) | |
112 | return False | |
113 | else: | |
114 | print "Passed:", self.archive_filename | |
115 | return True | |
116 | ||
117 | ||
118 | successes = 0 | |
119 | failures = 0 | |
120 | testnames = tests.keys() | |
121 | testnames.sort() | |
122 | for testname in testnames: | |
123 | test = ExtractorTest(testname, tests[testname]) | |
124 | if test.run(): | |
125 | successes += 1 | |
126 | else: | |
127 | failures += 1 | |
128 | print "Totals: %s successes, %s failures" % (successes, failures) | |
129 |