annotate upreckon/testcases.py @ 205:166a23999bf7

Added confvar okexitcodemask; changed the validator protocol Callable validators now return three-tuples (number granted, bool correct, str comment) instead of two-tuples (number granted, str comment). They are still allowed to return single numbers. Callable validators must now explicitly raise upreckon.exceptions.WrongAnswer if they want the verdict to be Wrong Answer rather than Partly Correct. okexitcodemask specifies a bitmask ANDed with the exit code of the external validator to get a boolean flag showing whether the answer is to be marked as 'OK' rather than 'partly correct'. The bits covered by the bitmask are reset to zeroes before devising the number of points granted from the resulting number.
author Oleg Oshmyan <chortos@inbox.lv>
date Wed, 17 Aug 2011 20:44:54 +0300
parents 00c80bba7f13
children 4edb6ef5a676
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
77
69eadc60f4e2 Memory limit is now applied to the RSS when os.wait4 is available
Oleg Oshmyan <chortos@inbox.lv>
parents: 76
diff changeset
1 # Copyright (c) 2010-2011 Chortos-2 <chortos@inbox.lv>
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
2
43
81f58c938ec5 Fixed the -s option
Oleg Oshmyan <chortos@inbox.lv>
parents: 41
diff changeset
3 # TODO: copy the ansfile if not options.erase even if no validator is used
81f58c938ec5 Fixed the -s option
Oleg Oshmyan <chortos@inbox.lv>
parents: 41
diff changeset
4
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
5 from __future__ import division, with_statement
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
6
146
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
7 from .compat import *
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
8 from .exceptions import *
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
9 from . import files, config
91
c62c9bfd614a Removed import_error
Oleg Oshmyan <chortos@inbox.lv>
parents: 90
diff changeset
10 from __main__ import options
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
11
146
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
12 import re, sys, tempfile
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
13 from subprocess import Popen, PIPE, STDOUT
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
14
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
15 import os
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
16 devnull = open(os.path.devnull, 'w+b')
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
17
108
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
18 class DummySignalIgnorer(object):
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
19 def __enter__(self): pass
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
20 def __exit__(self, exc_type, exc_value, traceback): pass
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
21 signal_ignorer = DummySignalIgnorer()
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
22
146
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
23 try:
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
24 from .win32 import *
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
25 except Exception:
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
26 from .unix import *
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
27
146
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
28 __all__ = ('TestCase', 'SkippedTestCase', 'ValidatedTestCase', 'BatchTestCase',
d5b6708c1955 Distutils support, reorganization and cleaning up
Oleg Oshmyan <chortos@inbox.lv>
parents: 136
diff changeset
29 'OutputOnlyTestCase')
136
ed4035661b85 Added a C implementation of the unix module (called _unix)
Oleg Oshmyan <chortos@inbox.lv>
parents: 134
diff changeset
30
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
31
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
32
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
33 # Helper context managers
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
34
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
35 class CopyDeleting(object):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
36 __slots__ = 'case', 'file', 'name'
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
37
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
38 def __init__(self, case, file, name):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
39 self.case = case
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
40 self.file = file
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
41 self.name = name
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
42
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
43 def __enter__(self):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
44 if self.name:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
45 try:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
46 self.file.copy(self.name)
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
47 except:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
48 try:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
49 self.__exit__(None, None, None)
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
50 except:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
51 pass
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
52 raise
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
53
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
54 def __exit__(self, exc_type, exc_val, exc_tb):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
55 if self.name:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
56 self.case.files_to_delete.append(self.name)
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
57
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
58
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
59 class Copying(object):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
60 __slots__ = 'file', 'name'
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
61
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
62 def __init__(self, file, name):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
63 self.file = file
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
64 self.name = name
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
65
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
66 def __enter__(self):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
67 if self.name:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
68 self.file.copy(self.name)
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
69
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
70 def __exit__(self, exc_type, exc_val, exc_tb):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
71 pass
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
72
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
73
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
74
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
75 # Test case types
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
76
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
77 class TestCase(object):
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
78 __slots__ = ('problem', 'id', 'isdummy', 'infile', 'outfile', 'points',
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
79 'process', 'time_started', 'time_stopped',
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
80 'realinname', 'realoutname', 'maxcputime', 'maxwalltime',
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
81 'maxmemory', 'has_called_back', 'files_to_delete',
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
82 'cpu_time_limit_string', 'wall_time_limit_string',
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
83 'time_limit_string')
106
aa0378ea1f93 Replaced constant properties with regular attributes
Oleg Oshmyan <chortos@inbox.lv>
parents: 105
diff changeset
84 has_ansfile = has_iofiles = False
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
85 needs_realinname = True
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
86
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
87 if ABCMeta:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
88 __metaclass__ = ABCMeta
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
89
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
90 def __init__(case, prob, id, isdummy, points):
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
91 case.problem = prob
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
92 case.id = id
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
93 case.isdummy = isdummy
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
94 case.points = points
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
95 case.maxcputime = case.problem.config.maxcputime
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
96 case.maxwalltime = case.problem.config.maxwalltime
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
97 case.maxmemory = case.problem.config.maxmemory
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
98 if case.maxcputime:
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
99 case.cpu_time_limit_string = '/%.3f' % case.maxcputime
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
100 else:
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
101 case.cpu_time_limit_string = ''
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
102 if case.maxwalltime:
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
103 case.wall_time_limit_string = '/%.3f' % case.maxwalltime
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
104 else:
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
105 case.wall_time_limit_string = ''
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
106 if not isdummy:
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
107 if case.needs_realinname:
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
108 case.realinname = case.problem.config.testcaseinname
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
109 case.realoutname = case.problem.config.testcaseoutname
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
110 else:
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
111 if case.needs_realinname:
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
112 case.realinname = case.problem.config.dummyinname
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
113 case.realoutname = case.problem.config.dummyoutname
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
114
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
115 @abstractmethod
90
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
116 def test(case):
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
117 raise NotImplementedError
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
118
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
119 def __call__(case, callback):
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
120 case.has_called_back = False
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
121 case.files_to_delete = []
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
122 case.time_limit_string = case.wall_time_limit_string
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
123 try:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
124 return case.test(callback)
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
125 finally:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
126 now = clock()
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
127 if getattr(case, 'time_started', None) is None:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
128 case.time_started = case.time_stopped = now
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
129 elif getattr(case, 'time_stopped', None) is None:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
130 case.time_stopped = now
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
131 if not case.has_called_back:
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
132 callback()
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
133 case.cleanup()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
134
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
135 def cleanup(case):
136
ed4035661b85 Added a C implementation of the unix module (called _unix)
Oleg Oshmyan <chortos@inbox.lv>
parents: 134
diff changeset
136 # Note that native extensions clean up on their own
ed4035661b85 Added a C implementation of the unix module (called _unix)
Oleg Oshmyan <chortos@inbox.lv>
parents: 134
diff changeset
137 # and never let this condition be satisfied
82
06356af50bf9 Finished testcases reorganization and CPU time limit implementation
Oleg Oshmyan <chortos@inbox.lv>
parents: 81
diff changeset
138 if getattr(case, 'process', None) and case.process.returncode is None:
134
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
139 kill(case.process)
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
140 for name in case.files_to_delete:
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
141 try:
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
142 os.remove(name)
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
143 except OSError:
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
144 # It can't be helped
e84f33a60a5c Moved process killing logic into platform-specific modules
Oleg Oshmyan <chortos@inbox.lv>
parents: 130
diff changeset
145 pass
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
146
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
147 def open_infile(case):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
148 try:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
149 case.infile = files.File('/'.join((case.problem.name, case.realinname.replace('$', case.id))))
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
150 except IOError:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
151 e = sys.exc_info()[1]
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
152 raise CannotReadInputFile(e)
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
153
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
154 def open_outfile(case):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
155 try:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
156 case.outfile = files.File('/'.join((case.problem.name, case.realoutname.replace('$', case.id))))
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
157 except IOError:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
158 e = sys.exc_info()[1]
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
159 raise CannotReadAnswerFile(e)
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
160
16
f2279b7602d3 Initial 2.00 commit
Oleg Oshmyan <chortos@inbox.lv>
parents:
diff changeset
161
90
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
162 class SkippedTestCase(TestCase):
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
163 __slots__ = ()
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
164
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
165 def test(case, callback):
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
166 raise TestCaseSkipped
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
167
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
168
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
169 class ValidatedTestCase(TestCase):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
170 __slots__ = 'validator'
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
171
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
172 def __init__(case, *args):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
173 TestCase.__init__(case, *args)
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
174 if not case.problem.config.tester:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
175 case.validator = None
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
176 else:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
177 case.validator = case.problem.config.tester
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
178
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
179 def validate(case, output):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
180 if not case.validator:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
181 # Compare the output with the reference output
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
182 buffer = refbuffer = crlfhalf = refcrlfhalf = ''.encode()
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
183 crlf = '\r\n'.encode('ascii')
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
184 case.open_outfile()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
185 with case.outfile.open() as refoutput:
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
186 while True:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
187 data = output.read(4096 - len(buffer))
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
188 refdata = refoutput.read(4096 - len(refbuffer))
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
189 if not case.problem.config.binary:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
190 data, refdata = crlfhalf + data, refcrlfhalf + refdata
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
191 size, refsize = len(data), len(refdata)
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
192 if data and data != crlfhalf and data[-1] == crlf[0]:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
193 size -= 1
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
194 crlfhalf = data[-1:]
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
195 else:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
196 crlfhalf = ''.encode()
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
197 if refdata and refdata != refcrlfhalf and refdata[-1] == crlf[0]:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
198 refsize -= 1
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
199 refcrlfhalf = refdata[-1:]
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
200 else:
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
201 refcrlfhalf = ''.encode()
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
202 data = data[:size].replace(crlf, crlf[1:])
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
203 data = data.replace(crlf[:1], crlf[1:])
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
204 refdata = refdata[:refsize].replace(crlf, crlf[1:])
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
205 refdata = refdata.replace(crlf[:1], crlf[1:])
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
206 buffer += data
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
207 refbuffer += refdata
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
208 if not (buffer or refbuffer or crlfhalf or refcrlfhalf):
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
209 break
180
760d38ee86d6 Fixed hanging in the built-in output validator when output lengths differ
Oleg Oshmyan <chortos@inbox.lv>
parents: 176
diff changeset
210 elif not buffer and not crlfhalf or not refbuffer and not refcrlfhalf:
760d38ee86d6 Fixed hanging in the built-in output validator when output lengths differ
Oleg Oshmyan <chortos@inbox.lv>
parents: 176
diff changeset
211 raise WrongAnswer
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
212 size = min(len(buffer), len(refbuffer))
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
213 if buffer[:size] != refbuffer[:size]:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
214 raise WrongAnswer
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
215 buffer, refbuffer = buffer[size:], refbuffer[size:]
24
c23d81f4a1a3 Score returned by TestCase.__call__() is now normalized to 0..1
Oleg Oshmyan <chortos@inbox.lv>
parents: 23
diff changeset
216 return 1
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
217 elif callable(case.validator):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
218 return case.validator(output)
204
00c80bba7f13 Removed some long-unnoticed trailing whitespace
Oleg Oshmyan <chortos@inbox.lv>
parents: 200
diff changeset
219 else:
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
220 # Call the validator program
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
221 output.close()
23
c1f52b5d80d6 Compatibility and bug fixes
Oleg Oshmyan <chortos@inbox.lv>
parents: 22
diff changeset
222 if case.problem.config.ansname:
c1f52b5d80d6 Compatibility and bug fixes
Oleg Oshmyan <chortos@inbox.lv>
parents: 22
diff changeset
223 case.open_outfile()
c1f52b5d80d6 Compatibility and bug fixes
Oleg Oshmyan <chortos@inbox.lv>
parents: 22
diff changeset
224 case.outfile.copy(case.problem.config.ansname)
25
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
225 try:
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
226 case.process = Popen(case.validator, stdin=devnull, stdout=PIPE, stderr=STDOUT, universal_newlines=True, bufsize=-1)
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
227 except OSError:
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
228 raise CannotStartValidator(sys.exc_info()[1])
108
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
229 with signal_ignorer:
218b8c28549c Fixed a crash due to SIGCHLD interrupting validator output pipe reads
Oleg Oshmyan <chortos@inbox.lv>
parents: 106
diff changeset
230 comment = case.process.communicate()[0].strip()
26
5bbb68833868 Output text improvements
Oleg Oshmyan <chortos@inbox.lv>
parents: 25
diff changeset
231 match = re.match(r'(?i)(ok|(?:correct|wrong)(?:(?:\s|_)*answer)?)(?:$|\s+|[.,!:]+\s*)', comment)
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
232 if match:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
233 comment = comment[match.end():]
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
234 if not case.problem.config.maxexitcode:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
235 if case.process.returncode:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
236 raise WrongAnswer(comment)
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
237 else:
205
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
238 return 1, True, comment
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
239 else:
205
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
240 if case.problem.config.okexitcodeflag:
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
241 correct = bool(case.process.returncode & case.problem.config.okexitcodeflag)
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
242 case.process.returncode &= ~case.problem.config.okexitcodeflag
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
243 else:
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
244 correct = case.process.returncode >= case.problem.config.maxexitcode
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
245 if not correct and not case.process.returncode:
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
246 raise WrongAnswer(comment)
166a23999bf7 Added confvar okexitcodemask; changed the validator protocol
Oleg Oshmyan <chortos@inbox.lv>
parents: 204
diff changeset
247 return case.process.returncode / case.problem.config.maxexitcode, correct, comment
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
248
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
249
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
250 class BatchTestCase(ValidatedTestCase):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
251 __slots__ = ()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
252
90
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
253 @property
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
254 def has_iofiles(case):
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
255 return (not case.problem.config.stdio or
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
256 case.validator and not callable(case.validator))
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
257
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
258 @property
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
259 def has_ansfile(case):
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
260 return case.validator and not callable(case.validator)
1fb319ec33af Skimming mode added (-k/--skim option)
Oleg Oshmyan <chortos@inbox.lv>
parents: 89
diff changeset
261
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
262 def test(case, callback):
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
263 case.open_infile()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
264 if case.problem.config.stdio:
54
1914ae9cfdce Bug fixes
Oleg Oshmyan <chortos@inbox.lv>
parents: 50
diff changeset
265 if options.erase and not case.validator or not case.problem.config.inname:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
266 # TODO: re-use the same file name if possible
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
267 # FIXME: 2.5 lacks the delete parameter
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
268 with tempfile.NamedTemporaryFile(delete=False) as f:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
269 inputdatafname = f.name
25
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
270 contextmgr = CopyDeleting(case, case.infile, inputdatafname)
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
271 else:
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
272 inputdatafname = case.problem.config.inname
25
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
273 contextmgr = Copying(case.infile, inputdatafname)
b500e117080e Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents: 24
diff changeset
274 with contextmgr:
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
275 with tempfile.TemporaryFile('w+b') if options.erase and (not case.validator or callable(case.validator)) else open(case.problem.config.outname, 'w+b') as outfile:
163
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
276 with open(inputdatafname) as infile:
130
652028850ea4 Removed useless arguments to call() from testcases.BatchTestCase.test()
Oleg Oshmyan <chortos@inbox.lv>
parents: 128
diff changeset
277 call(case.problem.config.path, case=case, stdin=infile, stdout=outfile, stderr=devnull)
200
fa81289ee407 force_zero_exitcode is now a problem-specific configuration variable
Oleg Oshmyan <chortos@inbox.lv>
parents: 180
diff changeset
278 if case.problem.config.force_zero_exitcode and case.process.returncode or case.process.returncode < 0:
163
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
279 raise NonZeroExitCode(case.process.returncode)
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
280 case.has_called_back = True
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
281 callback()
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
282 outfile.seek(0)
8198aa2ed20d Some broken output validators on Win32 no longer get access-denied errors
Oleg Oshmyan <chortos@inbox.lv>
parents: 146
diff changeset
283 return case.validate(outfile)
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
284 else:
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
285 case.infile.copy(case.problem.config.inname)
176
88e1e6786f67 Fixed crashing on stdio=False with _unix
Oleg Oshmyan <chortos@inbox.lv>
parents: 174
diff changeset
286 call(case.problem.config.path, case=case, stdin=devnull, stdout=devnull, stderr=devnull)
200
fa81289ee407 force_zero_exitcode is now a problem-specific configuration variable
Oleg Oshmyan <chortos@inbox.lv>
parents: 180
diff changeset
287 if case.problem.config.force_zero_exitcode and case.process.returncode or case.process.returncode < 0:
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
288 raise NonZeroExitCode(case.process.returncode)
103
4e6f231f055f Fixed race condition resulting in calling back twice from TestCase.test
Oleg Oshmyan <chortos@inbox.lv>
parents: 99
diff changeset
289 case.has_called_back = True
22
f07b7a431ea6 Further 2.00 work
Oleg Oshmyan <chortos@inbox.lv>
parents: 21
diff changeset
290 callback()
105
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
291 try:
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
292 output = open(case.problem.config.outname, 'rb')
105
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
293 except IOError:
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
294 raise CannotReadOutputFile(sys.exc_info()[1])
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
295 with output as output:
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
296 return case.validate(output)
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
297
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
298
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
299 # This is the only test case type not executing any programs to be tested
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
300 class OutputOnlyTestCase(ValidatedTestCase):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
301 __slots__ = ()
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
302 needs_realinname = False
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
303
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
304 def cleanup(case):
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
305 pass
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
306
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
307 def test(case, callback):
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
308 case.time_stopped = case.time_started = 0
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
309 case.has_called_back = True
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
310 callback()
105
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
311 try:
174
e0b2fbd7ebe0 Improved built-in output validator; added conf. var. binary
Oleg Oshmyan <chortos@inbox.lv>
parents: 163
diff changeset
312 output = open(case.problem.config.outname.replace('$', case.id), 'rb')
105
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
313 except IOError:
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
314 raise CannotReadOutputFile(sys.exc_info()[1])
9f922b11c98a Absent output files no longer crash Upreckon
Oleg Oshmyan <chortos@inbox.lv>
parents: 104
diff changeset
315 with output as output:
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
316 return case.validate(output)
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
317
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
318
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
319 class BestOutputTestCase(ValidatedTestCase):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
320 __slots__ = ()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
321
104
8f46e84922f9 Output-only problems are now supported
Oleg Oshmyan <chortos@inbox.lv>
parents: 103
diff changeset
322
21
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
323 # This is the only test case type executing two programs simultaneously
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
324 class ReactiveTestCase(TestCase):
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
325 __slots__ = ()
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
326 # The basic idea is to launch the program to be tested and the grader
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
327 # and to pipe their standard I/O from and to each other,
ec6f1a132109 A pretty usable version
Oleg Oshmyan <chortos@inbox.lv>
parents: 16
diff changeset
328 # and then to capture the grader's exit code and use it
26
5bbb68833868 Output text improvements
Oleg Oshmyan <chortos@inbox.lv>
parents: 25
diff changeset
329 # like the exit code of an output validator is used.