Mercurial > ~astiob > upreckon > hgweb
comparison testcases.py @ 90:1fb319ec33af
Skimming mode added (-k/--skim option)
In skimming mode, as soon as a single test case within a test group
is failed, the remaining test cases in the same group are skipped.
Bug fix and simply a bit of refactoring: TestCase.has_iofiles and
TestCase.has_ansfile are now defined (the meaning should be clear
from the names).
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Mon, 28 Feb 2011 15:32:22 +0000 |
parents | 3ae6cb69e4ef |
children | c62c9bfd614a |
comparison
equal
deleted
inserted
replaced
89:3ae6cb69e4ef | 90:1fb319ec33af |
---|---|
50 | 50 |
51 | 51 |
52 # Exceptions | 52 # Exceptions |
53 | 53 |
54 class TestCaseNotPassed(Exception): __slots__ = () | 54 class TestCaseNotPassed(Exception): __slots__ = () |
55 class TestCaseSkipped(TestCaseNotPassed): __slots__ = () | |
55 class TimeLimitExceeded(TestCaseNotPassed): __slots__ = () | 56 class TimeLimitExceeded(TestCaseNotPassed): __slots__ = () |
56 class CPUTimeLimitExceeded(TimeLimitExceeded): __slots__ = () | 57 class CPUTimeLimitExceeded(TimeLimitExceeded): __slots__ = () |
57 class WallTimeLimitExceeded(TimeLimitExceeded): __slots__ = () | 58 class WallTimeLimitExceeded(TimeLimitExceeded): __slots__ = () |
58 class MemoryLimitExceeded(TestCaseNotPassed): __slots__ = () | 59 class MemoryLimitExceeded(TestCaseNotPassed): __slots__ = () |
59 class CanceledByUser(TestCaseNotPassed): __slots__ = () | 60 class CanceledByUser(TestCaseNotPassed): __slots__ = () |
158 else: | 159 else: |
159 case.realinname = case.problem.config.dummyinname | 160 case.realinname = case.problem.config.dummyinname |
160 case.realoutname = case.problem.config.dummyoutname | 161 case.realoutname = case.problem.config.dummyoutname |
161 | 162 |
162 @abstractmethod | 163 @abstractmethod |
163 def test(case): raise NotImplementedError | 164 def test(case): |
165 raise NotImplementedError | |
164 | 166 |
165 def __call__(case, callback): | 167 def __call__(case, callback): |
166 case.has_called_back = False | 168 case.has_called_back = False |
167 case.files_to_delete = [] | 169 case.files_to_delete = [] |
168 case.time_limit_string = case.wall_time_limit_string | 170 case.time_limit_string = case.wall_time_limit_string |
175 elif getattr(case, 'time_stopped', None) is None: | 177 elif getattr(case, 'time_stopped', None) is None: |
176 case.time_stopped = now | 178 case.time_stopped = now |
177 if not case.has_called_back: | 179 if not case.has_called_back: |
178 callback() | 180 callback() |
179 case.cleanup() | 181 case.cleanup() |
182 | |
183 @property | |
184 def has_iofiles(case): | |
185 return False | |
186 | |
187 @property | |
188 def has_ansfile(case): | |
189 return False | |
180 | 190 |
181 def cleanup(case): | 191 def cleanup(case): |
182 #if getattr(case, 'infile', None): | 192 #if getattr(case, 'infile', None): |
183 # case.infile.close() | 193 # case.infile.close() |
184 #if getattr(case, 'outfile', None): | 194 #if getattr(case, 'outfile', None): |
227 except IOError: | 237 except IOError: |
228 e = sys.exc_info()[1] | 238 e = sys.exc_info()[1] |
229 raise CannotReadAnswerFile(e) | 239 raise CannotReadAnswerFile(e) |
230 | 240 |
231 | 241 |
242 class SkippedTestCase(TestCase): | |
243 __slots__ = () | |
244 | |
245 def test(case, callback): | |
246 raise TestCaseSkipped | |
247 | |
248 | |
232 class ValidatedTestCase(TestCase): | 249 class ValidatedTestCase(TestCase): |
233 __slots__ = 'validator' | 250 __slots__ = 'validator' |
234 | 251 |
235 def __init__(case, *args): | 252 def __init__(case, *args): |
236 TestCase.__init__(case, *args) | 253 TestCase.__init__(case, *args) |
276 | 293 |
277 | 294 |
278 class BatchTestCase(ValidatedTestCase): | 295 class BatchTestCase(ValidatedTestCase): |
279 __slots__ = () | 296 __slots__ = () |
280 | 297 |
298 @property | |
299 def has_iofiles(case): | |
300 return (not case.problem.config.stdio or | |
301 case.validator and not callable(case.validator)) | |
302 | |
303 @property | |
304 def has_ansfile(case): | |
305 return case.validator and not callable(case.validator) | |
306 | |
281 def test(case, callback): | 307 def test(case, callback): |
282 case.open_infile() | 308 case.open_infile() |
283 case.time_started = None | |
284 if case.problem.config.stdio: | 309 if case.problem.config.stdio: |
285 if options.erase and not case.validator or not case.problem.config.inname: | 310 if options.erase and not case.validator or not case.problem.config.inname: |
286 # TODO: re-use the same file name if possible | 311 # TODO: re-use the same file name if possible |
287 # FIXME: 2.5 lacks the delete parameter | 312 # FIXME: 2.5 lacks the delete parameter |
288 with tempfile.NamedTemporaryFile(delete=False) as f: | 313 with tempfile.NamedTemporaryFile(delete=False) as f: |
412 yield problem.test_context_end | 437 yield problem.test_context_end |
413 for k, group in enumerate(prob.config.tests): | 438 for k, group in enumerate(prob.config.tests): |
414 if not group: | 439 if not group: |
415 continue | 440 continue |
416 yield problem.TestGroup(prob.config.groupweight.get(k, prob.config.groupweight.get(None))) | 441 yield problem.TestGroup(prob.config.groupweight.get(k, prob.config.groupweight.get(None))) |
442 case_type = _types[prob.config.kind] | |
417 for j, i in enumerate(group): | 443 for j, i in enumerate(group): |
418 s = str(i).zfill(prob.config.padtests) | 444 s = str(i).zfill(prob.config.padtests) |
419 yield _types[prob.config.kind](prob, s, False, getpoints(i, j, k)) | 445 if not (yield case_type(prob, s, False, getpoints(i, j, k))): |
446 if options.skim: | |
447 case_type = SkippedTestCase | |
448 else: | |
449 yield | |
420 yield problem.test_context_end | 450 yield problem.test_context_end |
421 else: | 451 else: |
422 for i in prob.config.tests: | 452 for i in prob.config.tests: |
423 s = str(i).zfill(prob.config.padtests) | 453 s = str(i).zfill(prob.config.padtests) |
424 prob.cache.padoutput = max(prob.cache.padoutput, len(s)) | 454 prob.cache.padoutput = max(prob.cache.padoutput, len(s)) |