comparison 2.00/test-svn.py @ 21:ec6f1a132109

A pretty usable version Test groups and testconfs in non-ZIP archives or ZIP archives with comments are not yet supported.
author Oleg Oshmyan <chortos@inbox.lv>
date Fri, 06 Aug 2010 15:39:29 +0000
parents a33653cdad57
children f07b7a431ea6
comparison
equal deleted inserted replaced
20:5bfa23cd638d 21:ec6f1a132109
1 #!/usr/bin/python 1 #! /usr/bin/env python
2 # Copyright (c) 2009-2010 Chortos-2 <chortos@inbox.lv> 2 # Copyright (c) 2009-2010 Chortos-2 <chortos@inbox.lv>
3 3
4 from __future__ import division, with_statement 4 from __future__ import division, with_statement
5 import optparse, sys, compat 5 import optparse, sys, compat
6 from compat import say 6
7 def import_error(e):
8 say('Error: your installation of test.py is incomplete;', str(e).lower() + '.', file=sys.stderr)
9 sys.exit(3)
10
11 from compat import *
7 12
8 # $Rev$ 13 # $Rev$
9 version = '2.00.0 (SVN r$$REV$$)' 14 version = '2.00.0 (SVN r$$REV$$)'
10 parser = optparse.OptionParser(version='test.py '+version, epilog='Python 2.5 or newer is required, unless you have a custom build of Python.') 15 parser = optparse.OptionParser(version='test.py '+version, epilog='Python 2.5 or newer is required, unless you have a custom build of Python.')
11 parser.add_option('-u', '--update', dest='update', action='store_true', default=False, help='check for an updated version of test.py') 16 parser.add_option('-u', '--update', dest='update', action='store_true', default=False, help='check for an updated version of test.py')
12 parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='create a copy of the input/output files of the last test case for manual testing and exit') 17 parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='create a copy of the input/output files of the last test case for manual testing and exit')
13 parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed after finishing testing') 18 parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed after finishing testing')
19 parser.add_option('-s', '--save-io', dest='erase', action='store_false', default=True, help='do not delete the copies of input/output files after the last test case; create copies of input files and store output in files even if the solution uses standard I/O; delete the stored input/output files if the solution uses standard I/O and the -c/--cleanup option is specified')
20 parser.add_option('-t', '--detect-time', dest='autotime', action='store_true', default=False, help='spend a second detecting the most precise time measurement function')
21 parser.add_option('--no-time-limits', dest='no_maxtime', action='store_true', default=False, help='disable all time limits')
14 22
15 options, args = parser.parse_args() 23 options, args = parser.parse_args()
16 parser.destroy() 24 parser.destroy()
17 del parser 25 del parser
18 26
47 sys.stdout.flush() 55 sys.stdout.flush()
48 urllib.urlretrieve('http://chortos.selfip.net/~astiob/test.py/test.py', sys.argv[0]) 56 urllib.urlretrieve('http://chortos.selfip.net/~astiob/test.py/test.py', sys.argv[0])
49 say('Downloaded and installed. Now you are using test.py ' + latesttext + '.') 57 say('Downloaded and installed. Now you are using test.py ' + latesttext + '.')
50 sys.exit() 58 sys.exit()
51 59
52 def import_error(e): 60 import config, itertools, os, sys, time
53 say('Your installation of test.py is incomplete:', str(e).lower() + '.', file=sys.stderr)
54 sys.exit(3)
55 61
56 import os, config 62 if options.autotime:
57 63 c = time.clock()
58 # Do this check here so that if we have to warn them, we do it as early as possible 64 time.sleep(1)
59 if options.pause and not hasattr(config, 'pause'): 65 c = time.clock() - c
60 try: 66 if int(c + .5) == 1:
61 # If we have getch, we don't need config.pause 67 clock = time.clock
62 import msvcrt 68 else:
63 msvcrt.getch.__call__ 69 clock = time.time
64 except Exception: 70 elif sys.platform == 'win32':
65 if os.name == 'posix': 71 clock = time.clock
66 config.pause = 'read -s -n 1' 72 else:
67 say('Warning: configuration variable pause is not defined; it was devised automatically but the choice might be incorrect, so test.py might exit immediately after the testing is completed.') 73 clock = time.time
68 sys.stdout.flush()
69 elif os.name == 'nt':
70 config.pause = 'pause'
71 else:
72 sys.exit('Error: configuration variable pause is not defined and cannot be devised automatically.')
73 74
74 try: 75 try:
75 from problem import * 76 globalconf = config.load_global()
76 except ImportError as e:
77 import_error(e)
78 77
79 # Support single-problem configurations 78 # Do this check here so that if we have to warn them, we do it as early as possible
80 try: 79 if options.pause and not hasattr(globalconf, 'pause'):
81 shouldprintnames = len(config.tasknames) > 1 80 try:
82 except Exception: 81 # If we have getch, we don't need config.pause
83 shouldprintnames = True 82 import msvcrt
83 msvcrt.getch.__call__
84 except Exception:
85 if os.name == 'posix':
86 globalconf.pause = 'read -s -n 1'
87 say('Warning: configuration variable pause is not defined; it was devised automatically but the choice might be incorrect, so test.py might exit immediately after the testing is completed.')
88 sys.stdout.flush()
89 elif os.name == 'nt':
90 globalconf.pause = 'pause'
91 else:
92 sys.exit('Error: configuration variable pause is not defined and cannot be devised automatically.')
84 93
85 ntasks = 0 94 try:
86 nfulltasks = 0 95 from problem import *
87 maxscore = 0 96 except ImportError:
88 realscore = 0 97 import_error(sys.exc_info()[1])
89 98
90 for taskname in config.tasknames: 99 # Support single-problem configurations
91 problem = Problem(taskname) 100 if globalconf.tasknames is None:
92 101 shouldprintnames = False
93 if ntasks: say() 102 globalconf.multiproblem = False
94 if shouldprintnames: say(taskname) 103 globalconf.tasknames = os.path.curdir,
95 104 else:
105 globalconf.multiproblem = True
106 try:
107 shouldprintnames = len(globalconf.tasknames) > 1
108 except Exception:
109 # Try to retrieve the first two problem names and cache them on success
110 globalconf.tasknames = iter(globalconf.tasknames)
111 try:
112 try:
113 first = next(globalconf.tasknames)
114 except NameError:
115 # Python 2.5 lacks the next() built-in
116 first = globalconf.tasknames.next()
117 except StopIteration:
118 globalconf.tasknames = ()
119 shouldprintnames = False
120 else:
121 try:
122 try:
123 second = next(globalconf.tasknames)
124 except NameError:
125 second = globalconf.tasknames.next()
126 except StopIteration:
127 globalconf.tasknames = first,
128 shouldprintnames = False
129 else:
130 globalconf.tasknames = itertools.chain((first, second), globalconf.tasknames)
131 shouldprintnames = True
132
133 ntasks = 0
134 nfulltasks = 0
135 maxscore = 0
136 realscore = 0
137
138 for taskname in globalconf.tasknames:
139 problem = Problem(taskname)
140
141 if ntasks: say()
142 if shouldprintnames: say(taskname)
143
144 if options.copyonly:
145 problem.copytestdata()
146 else:
147 real, max = problem.test()
148
149 ntasks += 1
150 nfulltasks += (real == max)
151 realscore += real
152 maxscore += max
153
96 if options.copyonly: 154 if options.copyonly:
97 problem.copytestdata() 155 sys.exit()
98 else:
99 real, max = problem.test()
100
101 ntasks += 1
102 nfulltasks += (real == max)
103 realscore += real
104 maxscore += max
105 156
106 if options.copyonly: 157 if ntasks != 1:
107 sys.exit() 158 say()
108 159 say('Grand grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))
109 if ntasks != 1: 160 except KeyboardInterrupt:
110 say() 161 sys.exit('Exiting due to a keyboard interrupt.')
111 say('Grand grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))
112 162
113 if options.pause: 163 if options.pause:
114 say('Press any key to exit...', end='') 164 say('Press any key to exit...')
115 sys.stdout.flush() 165 sys.stdout.flush()
116 166
117 try: 167 try:
118 import msvcrt 168 import msvcrt
119 msvcrt.getch() 169 msvcrt.getch()
120 except Exception: 170 except Exception:
121 os.system(config.pause + ' >' + os.devnull) 171 os.system(globalconf.pause + ' >' + os.devnull)