OLD | NEW |
1 # Copyright 2014 Dirk Pranke. All rights reserved. | 1 # Copyright 2014 Dirk Pranke. All rights reserved. |
2 # | 2 # |
3 # Licensed under the Apache License, Version 2.0 (the "License"); | 3 # Licensed under the Apache License, Version 2.0 (the "License"); |
4 # you may not use this file except in compliance with the License. | 4 # you may not use this file except in compliance with the License. |
5 # You may obtain a copy of the License at | 5 # You may obtain a copy of the License at |
6 # | 6 # |
7 # http://www.apache.org/licenses/LICENSE-2.0 | 7 # http://www.apache.org/licenses/LICENSE-2.0 |
8 # | 8 # |
9 # Unless required by applicable law or agreed to in writing, software | 9 # Unless required by applicable law or agreed to in writing, software |
10 # distributed under the License is distributed on an "AS IS" BASIS, | 10 # distributed under the License is distributed on an "AS IS" BASIS, |
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 # See the License for the specific language governing permissions and | 12 # See the License for the specific language governing permissions and |
13 # limitations under the License. | 13 # limitations under the License. |
14 | 14 |
| 15 import tempfile |
| 16 |
15 from textwrap import dedent as d | 17 from textwrap import dedent as d |
16 | 18 |
17 | 19 |
18 from typ import Host, Runner, TestCase, TestSet, TestInput | 20 from typ import Host, Runner, TestCase, TestSet, TestInput |
| 21 from typ import WinMultiprocessing, main |
19 | 22 |
20 | 23 |
21 def _setup_process(child, context): # pylint: disable=W0613 | 24 def _setup_process(child, context): # pylint: disable=W0613 |
22 return context | 25 return context |
23 | 26 |
24 | 27 |
25 def _teardown_process(child, context): # pylint: disable=W0613 | 28 def _teardown_process(child, context): # pylint: disable=W0613 |
26 return context | 29 return context |
27 | 30 |
28 | 31 |
29 class RunnerTests(TestCase): | 32 class RunnerTests(TestCase): |
30 def test_context(self): | 33 def test_context(self): |
31 r = Runner() | 34 r = Runner() |
32 r.args.tests = ['typ.tests.runner_test.ContextTests'] | 35 r.args.tests = ['typ.tests.runner_test.ContextTests'] |
33 ret, _, _ = r.run(context={'foo': 'bar'}, setup_fn=_setup_process, | 36 ret, _, _ = r.run(context={'foo': 'bar'}, setup_fn=_setup_process, |
34 teardown_fn=_teardown_process) | 37 teardown_fn=_teardown_process) |
35 self.assertEqual(ret, 0) | 38 self.assertEqual(ret, 0) |
36 | 39 |
37 def test_bad_default(self): | 40 def test_bad_default(self): |
38 r = Runner() | 41 r = Runner() |
39 ret = r.main(foo='bar') | 42 ret = r.main([], foo='bar') |
40 self.assertEqual(ret, 2) | 43 self.assertEqual(ret, 2) |
41 | 44 |
42 def test_good_default(self): | 45 def test_good_default(self): |
43 r = Runner() | 46 r = Runner() |
44 ret = r.main(tests=['typ.tests.runner_test.ContextTests']) | 47 ret = r.main([], tests=['typ.tests.runner_test.ContextTests']) |
45 self.assertEqual(ret, 0) | 48 self.assertEqual(ret, 0) |
46 | 49 |
47 | 50 |
48 class TestSetTests(TestCase): | 51 class TestSetTests(TestCase): |
49 # This class exists to test the failures that can come up if you | 52 # This class exists to test the failures that can come up if you |
50 # create your own test sets and bypass find_tests(); failures that | 53 # create your own test sets and bypass find_tests(); failures that |
51 # would normally be caught there can occur later during test execution. | 54 # would normally be caught there can occur later during test execution. |
52 | 55 |
53 def test_missing_name(self): | 56 def test_missing_name(self): |
54 test_set = TestSet() | 57 test_set = TestSet() |
(...skipping 18 matching lines...) Expand all Loading... |
73 test_set.parallel_tests = [TestInput('load_test.BaseTest.test_x')] | 76 test_set.parallel_tests = [TestInput('load_test.BaseTest.test_x')] |
74 r = Runner() | 77 r = Runner() |
75 ret, _, _ = r.run(test_set) | 78 ret, _, _ = r.run(test_set) |
76 self.assertEqual(ret, 1) | 79 self.assertEqual(ret, 1) |
77 finally: | 80 finally: |
78 h.chdir(orig_wd) | 81 h.chdir(orig_wd) |
79 if tmpdir: | 82 if tmpdir: |
80 h.rmtree(tmpdir) | 83 h.rmtree(tmpdir) |
81 | 84 |
82 | 85 |
| 86 class TestWinMultiprocessing(TestCase): |
| 87 def make_host(self): |
| 88 return Host() |
| 89 |
| 90 def call(self, argv, platform=None, importable=None, **kwargs): |
| 91 h = self.make_host() |
| 92 orig_wd = h.getcwd() |
| 93 tmpdir = None |
| 94 try: |
| 95 tmpdir = h.mkdtemp() |
| 96 h.chdir(tmpdir) |
| 97 h.capture_output() |
| 98 if platform is not None: |
| 99 h.platform = platform |
| 100 r = Runner(h) |
| 101 if importable is not None: |
| 102 r._main_is_importable = lambda: importable |
| 103 ret = r.main(argv, **kwargs) |
| 104 finally: |
| 105 out, err = h.restore_output() |
| 106 h.chdir(orig_wd) |
| 107 if tmpdir: |
| 108 h.rmtree(tmpdir) |
| 109 |
| 110 return ret, out, err |
| 111 |
| 112 def test_bad_value(self): |
| 113 self.assertRaises(ValueError, self.call, [], win_multiprocessing='foo') |
| 114 |
| 115 def test_force(self): |
| 116 h = self.make_host() |
| 117 tmpdir = None |
| 118 orig_wd = h.getcwd() |
| 119 out = err = None |
| 120 out_str = err_str = '' |
| 121 try: |
| 122 tmpdir = h.mkdtemp() |
| 123 h.chdir(tmpdir) |
| 124 out = tempfile.NamedTemporaryFile(delete=False) |
| 125 err = tempfile.NamedTemporaryFile(delete=False) |
| 126 ret = main([], stdout=out, stderr=err, |
| 127 win_multiprocessing=WinMultiprocessing.force) |
| 128 finally: |
| 129 h.chdir(orig_wd) |
| 130 if tmpdir: |
| 131 h.rmtree(tmpdir) |
| 132 if out: |
| 133 out.close() |
| 134 out = open(out.name) |
| 135 out_str = out.read() |
| 136 out.close() |
| 137 h.remove(out.name) |
| 138 if err: |
| 139 err.close() |
| 140 err = open(err.name) |
| 141 err_str = err.read() |
| 142 err.close() |
| 143 h.remove(err.name) |
| 144 |
| 145 self.assertEqual(ret, 1) |
| 146 self.assertEqual(out_str, 'No tests to run.\n') |
| 147 self.assertEqual(err_str, '') |
| 148 |
| 149 def test_ignore(self): |
| 150 h = self.make_host() |
| 151 if h.platform == 'win32': # pragma: win32 |
| 152 self.assertRaises(ValueError, self.call, [], |
| 153 win_multiprocessing=WinMultiprocessing.ignore) |
| 154 else: |
| 155 result = self.call([], platform=None, importable=False, |
| 156 win_multiprocessing=WinMultiprocessing.ignore) |
| 157 ret, out, err = result |
| 158 self.assertEqual(ret, 1) |
| 159 self.assertEqual(out, 'No tests to run.\n') |
| 160 self.assertEqual(err, '') |
| 161 |
| 162 def test_multiple_jobs(self): |
| 163 self.assertRaises(ValueError, self.call, ['-j', '2'], |
| 164 platform='win32', importable=False) |
| 165 |
| 166 def test_normal(self): |
| 167 # This tests that typ itself is importable ... |
| 168 ret, out, err = self.call([]) |
| 169 self.assertEqual(ret, 1) |
| 170 self.assertEqual(out, 'No tests to run.\n') |
| 171 self.assertEqual(err, '') |
| 172 |
| 173 def test_real_unimportable_main(self): |
| 174 h = self.make_host() |
| 175 tmpdir = None |
| 176 orig_wd = h.getcwd() |
| 177 out = err = None |
| 178 out_str = err_str = '' |
| 179 try: |
| 180 tmpdir = h.mkdtemp() |
| 181 h.chdir(tmpdir) |
| 182 out = tempfile.NamedTemporaryFile(delete=False) |
| 183 err = tempfile.NamedTemporaryFile(delete=False) |
| 184 path_above_typ = h.realpath(h.dirname(__file__), '..', '..') |
| 185 env = {'PYTHONPATH': path_above_typ} |
| 186 h.write_text_file('test', d(""" |
| 187 import sys |
| 188 import typ |
| 189 sys.exit(typ.main()) |
| 190 """)) |
| 191 h.stdout = out |
| 192 h.stderr = err |
| 193 ret = h.call_inline([h.python_interpreter, h.join(tmpdir, 'test')], |
| 194 env=env) |
| 195 finally: |
| 196 h.chdir(orig_wd) |
| 197 if tmpdir: |
| 198 h.rmtree(tmpdir) |
| 199 if out: |
| 200 out.close() |
| 201 out = open(out.name) |
| 202 out_str = out.read() |
| 203 out.close() |
| 204 h.remove(out.name) |
| 205 if err: |
| 206 err.close() |
| 207 err = open(err.name) |
| 208 err_str = err.read() |
| 209 err.close() |
| 210 h.remove(err.name) |
| 211 |
| 212 self.assertEqual(ret, 1) |
| 213 self.assertEqual(out_str, '') |
| 214 self.assertIn('ValueError: The __main__ module is not importable', |
| 215 err_str) |
| 216 |
| 217 def test_run_serially(self): |
| 218 ret, out, err = self.call([], importable=False, |
| 219 win_multiprocessing=WinMultiprocessing.spawn) |
| 220 self.assertEqual(ret, 1) |
| 221 self.assertEqual(out, 'No tests to run.\n') |
| 222 self.assertEqual(err, '') |
| 223 |
| 224 def test_single_job(self): |
| 225 ret, out, err = self.call(['-j', '1'], platform='win32', |
| 226 importable=False) |
| 227 self.assertEqual(ret, 1) |
| 228 self.assertEqual(out, 'No tests to run.\n') |
| 229 self.assertEqual(err, '') |
| 230 |
| 231 def test_spawn(self): |
| 232 ret, out, err = self.call([], importable=False, |
| 233 win_multiprocessing=WinMultiprocessing.spawn) |
| 234 self.assertEqual(ret, 1) |
| 235 self.assertEqual(out, 'No tests to run.\n') |
| 236 self.assertEqual(err, '') |
| 237 |
| 238 |
83 class ContextTests(TestCase): | 239 class ContextTests(TestCase): |
84 def test_context(self): | 240 def test_context(self): |
85 # This test is mostly intended to be called by | 241 # This test is mostly intended to be called by |
86 # RunnerTests.test_context, above. It is not interesting on its own. | 242 # RunnerTests.test_context, above. It is not interesting on its own. |
87 if self.context: | 243 if self.context: |
88 self.assertEquals(self.context['foo'], 'bar') | 244 self.assertEquals(self.context['foo'], 'bar') |
OLD | NEW |