1 | # -*- coding: utf-8 -*- |
---|
2 | # |
---|
3 | # Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> |
---|
4 | # Copyright (C) 2007-2010 Edgewall Software |
---|
5 | # All rights reserved. |
---|
6 | # |
---|
7 | # This software is licensed as described in the file COPYING, which |
---|
8 | # you should have received as part of this distribution. The terms |
---|
9 | # are also available at http://bitten.edgewall.org/wiki/License. |
---|
10 | |
---|
11 | import os |
---|
12 | import shutil |
---|
13 | import sys |
---|
14 | import tempfile |
---|
15 | import unittest |
---|
16 | |
---|
17 | from bitten.build import CommandLine, FileSet, TimeoutError, BuildError |
---|
18 | |
---|
19 | |
---|
20 | class CommandLineTestCase(unittest.TestCase): |
---|
21 | |
---|
22 | def setUp(self): |
---|
23 | self.basedir = os.path.realpath(tempfile.mkdtemp(suffix='bitten_test')) |
---|
24 | |
---|
25 | def tearDown(self): |
---|
26 | shutil.rmtree(self.basedir) |
---|
27 | |
---|
28 | def _create_file(self, name, content=None): |
---|
29 | filename = os.path.join(self.basedir, name) |
---|
30 | fd = file(filename, 'w') |
---|
31 | if content: |
---|
32 | fd.write(content) |
---|
33 | fd.close() |
---|
34 | return filename |
---|
35 | |
---|
36 | def test_escape_and_quote_args(self): |
---|
37 | # Verify shlex.split() used by many commands to split input -> args |
---|
38 | import shlex |
---|
39 | self.assertEquals(['o\ne', '4 2', '"hi there"'], |
---|
40 | shlex.split('o\\\ne "4 2" \\"hi\\ there\\"')) |
---|
41 | |
---|
42 | def test_single_argument(self): |
---|
43 | cmdline = CommandLine(sys.executable, ['-V']) |
---|
44 | stdout = [] |
---|
45 | stderr = [] |
---|
46 | for out, err in cmdline.execute(timeout=5.0): |
---|
47 | if out is not None: |
---|
48 | stdout.append(out) |
---|
49 | if err is not None: |
---|
50 | stderr.append(err) |
---|
51 | py_version = '.'.join([str(v) for (v) in sys.version_info[:3]] |
---|
52 | ).rstrip('.0') |
---|
53 | |
---|
54 | self.assertEqual(['Python %s' % py_version], stderr) |
---|
55 | self.assertEqual([], stdout) |
---|
56 | self.assertEqual(0, cmdline.returncode) |
---|
57 | |
---|
58 | def test_multiple_arguments(self): |
---|
59 | script_file = self._create_file('test.py', content=""" |
---|
60 | import sys |
---|
61 | for arg in sys.argv[1:]: |
---|
62 | print arg |
---|
63 | """) |
---|
64 | cmdline = CommandLine('python', [script_file, 'foo', 'bar', 'baz']) |
---|
65 | stdout = [] |
---|
66 | stderr = [] |
---|
67 | for out, err in cmdline.execute(timeout=5.0): |
---|
68 | stdout.append(out) |
---|
69 | stderr.append(err) |
---|
70 | self.assertEqual(['foo', 'bar', 'baz'], stdout) |
---|
71 | self.assertEqual([None, None, None], stderr) |
---|
72 | self.assertEqual(0, cmdline.returncode) |
---|
73 | |
---|
74 | def test_output_error_streams(self): |
---|
75 | script_file = self._create_file('test.py', content=""" |
---|
76 | import sys, time |
---|
77 | print>>sys.stdout, 'Hello' |
---|
78 | print>>sys.stdout, 'world!' |
---|
79 | sys.stdout.flush() |
---|
80 | time.sleep(.1) |
---|
81 | print>>sys.stderr, 'Oops' |
---|
82 | sys.stderr.flush() |
---|
83 | """) |
---|
84 | cmdline = CommandLine('python', [script_file]) |
---|
85 | stdout = [] |
---|
86 | stderr = [] |
---|
87 | for out, err in cmdline.execute(timeout=5.0): |
---|
88 | stdout.append(out) |
---|
89 | stderr.append(err) |
---|
90 | py_version = '.'.join([str(v) for (v) in sys.version_info[:3]]) |
---|
91 | self.assertEqual(['Hello', 'world!', None], stdout) |
---|
92 | self.assertEqual(0, cmdline.returncode) |
---|
93 | |
---|
94 | def test_input_stream_as_fileobj(self): |
---|
95 | script_file = self._create_file('test.py', content=""" |
---|
96 | import sys |
---|
97 | data = sys.stdin.read() |
---|
98 | if data == 'abcd': |
---|
99 | print>>sys.stdout, 'Thanks' |
---|
100 | """) |
---|
101 | input_file = self._create_file('input.txt', content='abcd') |
---|
102 | input_fileobj = file(input_file, 'r') |
---|
103 | try: |
---|
104 | cmdline = CommandLine('python', [script_file], input=input_fileobj) |
---|
105 | stdout = [] |
---|
106 | stderr = [] |
---|
107 | for out, err in cmdline.execute(timeout=5.0): |
---|
108 | stdout.append(out) |
---|
109 | stderr.append(err) |
---|
110 | py_version = '.'.join([str(v) for (v) in sys.version_info[:3]]) |
---|
111 | self.assertEqual(['Thanks'], stdout) |
---|
112 | self.assertEqual([None], stderr) |
---|
113 | self.assertEqual(0, cmdline.returncode) |
---|
114 | finally: |
---|
115 | input_fileobj.close() |
---|
116 | |
---|
117 | def test_input_stream_as_string(self): |
---|
118 | script_file = self._create_file('test.py', content=""" |
---|
119 | import sys |
---|
120 | data = sys.stdin.read() |
---|
121 | if data == 'abcd': |
---|
122 | print>>sys.stdout, 'Thanks' |
---|
123 | """) |
---|
124 | cmdline = CommandLine('python', [script_file], input='abcd') |
---|
125 | stdout = [] |
---|
126 | stderr = [] |
---|
127 | for out, err in cmdline.execute(timeout=5.0): |
---|
128 | stdout.append(out) |
---|
129 | stderr.append(err) |
---|
130 | py_version = '.'.join([str(v) for (v) in sys.version_info[:3]]) |
---|
131 | self.assertEqual(['Thanks'], stdout) |
---|
132 | self.assertEqual([None], stderr) |
---|
133 | self.assertEqual(0, cmdline.returncode) |
---|
134 | |
---|
135 | def test_timeout(self): |
---|
136 | script_file = self._create_file('test.py', content=""" |
---|
137 | import time |
---|
138 | time.sleep(2.0) |
---|
139 | print 'Done' |
---|
140 | """) |
---|
141 | cmdline = CommandLine('python', [script_file]) |
---|
142 | iterable = iter(cmdline.execute(timeout=.5)) |
---|
143 | self.assertRaises(TimeoutError, iterable.next) |
---|
144 | |
---|
145 | def test_nonexisting_command(self): |
---|
146 | cmdline = CommandLine('doesnotexist', []) |
---|
147 | iterable = iter(cmdline.execute()) |
---|
148 | try: |
---|
149 | out, err = iterable.next() |
---|
150 | self.fail("Expected BuildError") |
---|
151 | except BuildError, e: |
---|
152 | self.failUnless("Error executing ['doesnotexist']" in str(e)) |
---|
153 | |
---|
154 | class FileSetTestCase(unittest.TestCase): |
---|
155 | |
---|
156 | def setUp(self): |
---|
157 | self.basedir = os.path.realpath(tempfile.mkdtemp(suffix='bitten_test')) |
---|
158 | |
---|
159 | def tearDown(self): |
---|
160 | shutil.rmtree(self.basedir) |
---|
161 | |
---|
162 | # Convenience methods |
---|
163 | |
---|
164 | def _create_dir(self, *path): |
---|
165 | cur = self.basedir |
---|
166 | for part in path: |
---|
167 | cur = os.path.join(cur, part) |
---|
168 | os.mkdir(cur) |
---|
169 | return cur[len(self.basedir) + 1:] |
---|
170 | |
---|
171 | def _create_file(self, *path): |
---|
172 | filename = os.path.join(self.basedir, *path) |
---|
173 | fd = file(filename, 'w') |
---|
174 | fd.close() |
---|
175 | return filename[len(self.basedir) + 1:] |
---|
176 | |
---|
177 | # Test methods |
---|
178 | |
---|
179 | def test_empty(self): |
---|
180 | fileset = FileSet(self.basedir) |
---|
181 | self.assertRaises(StopIteration, iter(fileset).next) |
---|
182 | |
---|
183 | def test_top_level_files(self): |
---|
184 | foo_txt = self._create_file('foo.txt') |
---|
185 | bar_txt = self._create_file('bar.txt') |
---|
186 | fileset = FileSet(self.basedir) |
---|
187 | assert foo_txt in fileset and bar_txt in fileset |
---|
188 | |
---|
189 | def test_files_in_subdir(self): |
---|
190 | self._create_dir('tests') |
---|
191 | foo_txt = self._create_file('tests', 'foo.txt') |
---|
192 | bar_txt = self._create_file('tests', 'bar.txt') |
---|
193 | fileset = FileSet(self.basedir) |
---|
194 | assert foo_txt in fileset and bar_txt in fileset |
---|
195 | |
---|
196 | def test_files_in_subdir_with_include(self): |
---|
197 | self._create_dir('tests') |
---|
198 | foo_txt = self._create_file('tests', 'foo.txt') |
---|
199 | bar_txt = self._create_file('tests', 'bar.txt') |
---|
200 | fileset = FileSet(self.basedir, include='tests/*.txt') |
---|
201 | assert foo_txt in fileset and bar_txt in fileset |
---|
202 | |
---|
203 | def test_files_in_subdir_with_exclude(self): |
---|
204 | self._create_dir('tests') |
---|
205 | foo_txt = self._create_file('tests', 'foo.txt') |
---|
206 | bar_txt = self._create_file('tests', 'bar.txt') |
---|
207 | fileset = FileSet(self.basedir, include='tests/*.txt', exclude='bar.*') |
---|
208 | assert foo_txt in fileset and bar_txt not in fileset |
---|
209 | |
---|
210 | |
---|
211 | def suite(): |
---|
212 | suite = unittest.TestSuite() |
---|
213 | suite.addTest(unittest.makeSuite(CommandLineTestCase, 'test')) |
---|
214 | suite.addTest(unittest.makeSuite(FileSetTestCase, 'test')) |
---|
215 | return suite |
---|
216 | |
---|
217 | if __name__ == '__main__': |
---|
218 | unittest.main(defaultTest='suite') |
---|