comparison test.py @ 2:bddcc05aba59

Finished path portability improvements
author Oleg Oshmyan <chortos@inbox.lv>
date Fri, 22 Jan 2010 19:48:24 +0000
parents 43ec211e2c59
children cd4304ff1d1b
comparison
equal deleted inserted replaced
1:43ec211e2c59 2:bddcc05aba59
1 #! /usr/bin/python 1 #! /usr/bin/python
2 # Copyright (c) 2009 Chortos-2 <chortos@inbox.lv> 2 # Copyright (c) 2009 Chortos-2 <chortos@inbox.lv>
3 3
4 import os, sys, shutil, time, subprocess, filecmp, optparse, signal, tempfile, tarfile, zipfile 4 import os, sys, shutil, time, subprocess, filecmp, optparse, signal, tempfile, tarfile, zipfile
5 5
6 parser = optparse.OptionParser(version='test.py 1.20.0', usage='usage: %prog [options] [problem names] [[path/to/]solution-app] [test case numbers]\n\nTest case numbers can be specified in plain text or as a Python expression\nif there is only one positional argument.\n\nOnly problem names listed in testconf.py are recognized.') 6 parser = optparse.OptionParser(version='test.py 1.21.0 (SVN)', usage='usage: %prog [options] [problem names] [[path' + os.path.sep + 'to' + os.path.sep + ']solution-app] [test case numbers]\n\nTest case numbers can be specified in plain text or as a Python expression\nif there is only one positional argument.\n\nOnly problem names listed in testconf.py are recognized.')
7 parser.add_option('-e', '--exclude', dest='exclude', action='append', help='test case number(s) to exclude, as a Python expression; multiple -e options can be supplied') 7 parser.add_option('-e', '--exclude', dest='exclude', action='append', help='test case number(s) to exclude, as a Python expression; multiple -e options can be supplied')
8 parser.add_option('-c', '--cleanup', dest='clean', action='store_true', default=False, help='delete the copies of input/output files and exit') 8 parser.add_option('-c', '--cleanup', dest='clean', action='store_true', default=False, help='delete the copies of input/output files and exit')
9 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') 9 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')
10 parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='only create a copy of the input/output files of the last test case for manual testing; to delete them, use options -cs') 10 parser.add_option('-m', '--copy-io', dest='copyonly', action='store_true', default=False, help='only create a copy of the input/output files of the last test case for manual testing; to delete them, use options -cs')
11 parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed when finished testing') 11 parser.add_option('-x', '--auto-exit', dest='pause', action='store_false', default=True, help='do not wait for a key to be pressed when finished testing')
17 del parser 17 del parser
18 18
19 globals1 = set(globals()) 19 globals1 = set(globals())
20 20
21 # Initialize some configuration variables with default values 21 # Initialize some configuration variables with default values
22 tasknames = (os.curdir,) 22 tasknames = (os.path.curdir,)
23 maxtime = 0 23 maxtime = 0
24 tests = () 24 tests = ()
25 dummies = () 25 dummies = ()
26 testsexcluded = () 26 testsexcluded = ()
27 padwithzeroestolength = 0 27 padwithzeroestolength = 0
86 try: 86 try:
87 execfile('testconf.py') 87 execfile('testconf.py')
88 except IOError, error: 88 except IOError, error:
89 exc_info = sys.exc_info()[2] 89 exc_info = sys.exc_info()[2]
90 try: 90 try:
91 execfile('tests/testconf.py') 91 execfile(os.path.join('tests', 'testconf.py'))
92 except IOError: 92 except IOError:
93 if not exectestconf_helper('testconf.py'): 93 if not exectestconf_helper('testconf.py'):
94 raise IOError, (error.errno, 'The configuration file is missing', error.filename), exc_info 94 raise IOError, (error.errno, 'The configuration file is missing', error.filename), exc_info
95 del exc_info 95 del exc_info
96 96
113 113
114 scoresumoveralltasks = 0 114 scoresumoveralltasks = 0
115 scoremaxoveralltasks = 0 115 scoremaxoveralltasks = 0
116 ntasks = 0 116 ntasks = 0
117 nfulltasks = 0 117 nfulltasks = 0
118 cwd = '' # At any time this is either '' or taskname + '/' 118 cwd = '' # At any time this is either '' or taskname
119 119
120 if options.autotime: 120 if options.autotime:
121 c = time.clock() 121 c = time.clock()
122 time.sleep(1) 122 time.sleep(1)
123 c = time.clock() - c 123 c = time.clock() - c
183 except KeyError: 183 except KeyError:
184 f.close() 184 f.close()
185 return False 185 return False
186 186
187 def existstestcase(name): 187 def existstestcase(name):
188 if os.path.isfile('tests/' + taskname + '/' + name) or os.path.isfile('tests/' + name): 188 if os.path.isfile(os.path.join('tests', taskname, name)) or os.path.isfile(os.path.join('tests', name)):
189 return True 189 return True
190 if cwd and (os.path.isfile(oldcwd + '/tests/' + cwd + name) or os.path.isfile(oldcwd + '/tests/' + name)): 190 if cwd and (os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name)) or os.path.isfile(os.path.join(oldcwd, 'tests', name))):
191 return True 191 return True
192 if existstestcase_helper(taskname + '/' + name) or existstestcase_helper(name): 192 if existstestcase_helper(os.path.join(taskname, name)) or existstestcase_helper(name):
193 return True 193 return True
194 if cwd: 194 if cwd:
195 os.chdir(oldcwd) 195 os.chdir(oldcwd)
196 if existstestcase_helper(cwd + name) or existstestcase_helper(name): 196 if existstestcase_helper(os.path.join(cwd, name)) or existstestcase_helper(name):
197 os.chdir(cwd) 197 os.chdir(cwd)
198 return True 198 return True
199 os.chdir(cwd) 199 os.chdir(cwd)
200 return False 200 return False
201 201
244 except KeyError: 244 except KeyError:
245 f.close() 245 f.close()
246 return None 246 return None
247 247
248 def opentestcase(name): 248 def opentestcase(name):
249 if os.path.isfile('tests/' + taskname + '/' + name): 249 if os.path.isfile(os.path.join('tests', taskname, name)):
250 return open('tests/' + taskname + '/' + name, 'rU') 250 return open(os.path.join('tests', taskname, name), 'rU')
251 elif os.path.isfile('tests/' + name): 251 elif os.path.isfile(os.path.join('tests', name)):
252 return open('tests/' + name, 'rU') 252 return open(os.path.join('tests', name), 'rU')
253 f = opentestcase_helper(taskname + '/' + name) 253 f = opentestcase_helper(os.path.join(taskname, name))
254 if not f: 254 if not f:
255 f = opentestcase_helper(name) 255 f = opentestcase_helper(name)
256 if f: 256 if f:
257 return f 257 return f
258 if cwd: 258 if cwd:
259 if os.path.isfile(oldcwd + '/tests/' + cwd + name): 259 if os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name):
260 return open(oldcwd + '/tests/' + cwd + name, 'rU') 260 return open(os.path.join(oldcwd, 'tests', cwd, name), 'rU')
261 elif os.path.isfile(oldcwd + '/tests/' + name): 261 elif os.path.isfile(os.path.join(oldcwd, 'tests', name)):
262 return open(oldcwd + '/tests/' + name, 'rU') 262 return open(os.path.join(oldcwd, 'tests', name), 'rU')
263 os.chdir(oldcwd) 263 os.chdir(oldcwd)
264 f = opentestcase_helper(cwd + name) 264 f = opentestcase_helper(os.path.join(cwd, name))
265 if not f: 265 if not f:
266 f = opentestcase_helper(name) 266 f = opentestcase_helper(name)
267 os.chdir(cwd) 267 os.chdir(cwd)
268 if f: 268 if f:
269 return f 269 return f
279 f.close() 279 f.close()
280 return True 280 return True
281 except KeyError: 281 except KeyError:
282 f.close() 282 f.close()
283 if os.path.isfile('tests.zip'): 283 if os.path.isfile('tests.zip'):
284 if not target.startswith('/'): 284 if not os.path.isabs(target):
285 f = zipfile.ZipFile('tests.zip') 285 f = zipfile.ZipFile('tests.zip')
286 m = f.getinfo(name) 286 m = f.getinfo(name)
287 try: 287 try:
288 m.filename = target 288 m.filename = target
289 f.extract(m) 289 f.extract(m)
291 return True 291 return True
292 except KeyError: 292 except KeyError:
293 f.close() 293 f.close()
294 else: 294 else:
295 oldcwd = os.getcwdu() 295 oldcwd = os.getcwdu()
296 os.chdir('/') 296 os.chdir('/') # FIXME: portability?
297 f = zipfile.ZipFile(oldcwd + '/tests.zip') 297 f = zipfile.ZipFile(os.path.join(oldcwd, 'tests.zip'))
298 try: 298 try:
299 m = f.getinfo(name) 299 m = f.getinfo(name)
300 m.filename = target[1:] 300 m.filename = target[1:]
301 f.extract(m) 301 f.extract(m)
302 f.close() 302 f.close()
346 except KeyError: 346 except KeyError:
347 f.close() 347 f.close()
348 return False 348 return False
349 349
350 def copytestcase(name, target): 350 def copytestcase(name, target):
351 if os.path.isfile('tests/' + taskname + '/' + name): 351 if os.path.isfile(os.path.join('tests', taskname, name)):
352 shutil.copyfile('tests/' + taskname + '/' + name, target) 352 shutil.copyfile(os.path.join('tests', taskname, name), target)
353 return 353 return
354 elif os.path.isfile('tests/' + name): 354 elif os.path.isfile(os.path.join('tests', name)):
355 shutil.copyfile('tests/' + name, target) 355 shutil.copyfile(os.path.join('tests', name), target)
356 return 356 return
357 if copytestcase_helper(taskname + '/' + name, target) or copytestcase_helper(name, target): 357 if copytestcase_helper(os.path.join(taskname, name), target) or copytestcase_helper(name, target):
358 return 358 return
359 if cwd: 359 if cwd:
360 if os.path.isfile(oldcwd + '/tests/' + cwd + name): 360 if os.path.isfile(os.path.join(oldcwd, 'tests', cwd, name)):
361 shutil.copyfile(oldcwd + '/tests/' + cwd + name, target) 361 shutil.copyfile(os.path.join(oldcwd, 'tests', cwd, name), target)
362 return 362 return
363 elif os.path.isfile(oldcwd + '/tests/' + name): 363 elif os.path.isfile(os.path.join(oldcwd, 'tests', name)):
364 shutil.copyfile(oldcwd + '/tests/' + name, target) 364 shutil.copyfile(os.path.join(oldcwd, 'tests', name), target)
365 return 365 return
366 os.chdir(oldcwd) 366 os.chdir(oldcwd)
367 if copytestcase_helper(cwd + name, target) or copytestcase_helper(name, target): 367 if copytestcase_helper(os.path.join(cwd, name), target) or copytestcase_helper(name, target):
368 os.chdir(cwd) 368 os.chdir(cwd)
369 return 369 return
370 os.chdir(cwd) 370 os.chdir(cwd)
371 raise KeyError, 'The test-case-defining file \'' + name + '\' cannot be found' 371 raise KeyError, 'The test-case-defining file \'' + name + '\' cannot be found'
372 372
375 global cwd 375 global cwd
376 cwd = '' 376 cwd = ''
377 if os.path.isdir(taskname): 377 if os.path.isdir(taskname):
378 os.chdir(taskname) 378 os.chdir(taskname)
379 if taskname != : 379 if taskname != :
380 cwd = taskname + '/' 380 cwd = taskname
381 try: 381 try:
382 execfile('testconf.py', globals()) 382 execfile('testconf.py', globals())
383 return 383 return
384 except IOError: 384 except IOError:
385 pass 385 pass
386 if not cwd: 386 if not cwd:
387 if os.path.isfile('tests/' + taskname + '/testconf.py'): 387 if os.path.isfile(os.path.join('tests', taskname, 'testconf.py')):
388 execfile('tests/' + taskname + '/testconf.py', globals()) 388 execfile(os.path.join('tests', taskname, 'testconf.py'), globals())
389 return 389 return
390 if os.path.isfile('tests/testconf.py'): 390 if os.path.isfile(os.path.join('tests', 'testconf.py')):
391 execfile('tests/testconf.py', globals()) 391 execfile(os.path.join('tests', 'testconf.py'), globals())
392 return 392 return
393 if exectestconf_helper(taskname + '/testconf.py') or exectestconf_helper('testconf.py'): 393 if exectestconf_helper(os.path.join(taskname, 'testconf.py')) or exectestconf_helper('testconf.py'):
394 return 394 return
395 if cwd: 395 if cwd:
396 os.chdir(oldcwd) 396 os.chdir(oldcwd)
397 if os.path.isfile('tests/' + cwd + 'testconf.py'): 397 if os.path.isfile(os.path.join('tests', cwd, 'testconf.py')):
398 execfile('tests/' + cwd + 'testconf.py', globals()) 398 execfile(os.path.join('tests', cwd, 'testconf.py'), globals())
399 os.chdir(cwd) 399 os.chdir(cwd)
400 return 400 return
401 if os.path.isfile('tests/testconf.py'): 401 if os.path.isfile(os.path.join('tests', 'testconf.py')):
402 execfile('tests/testconf.py', globals()) 402 execfile(os.path.join('tests', 'testconf.py'), globals())
403 os.chdir(cwd) 403 os.chdir(cwd)
404 return 404 return
405 if exectestconf_helper(cwd + 'testconf.py') or exectestconf_helper('testconf.py'): 405 if exectestconf_helper(os.path.join(cwd, 'testconf.py')) or exectestconf_helper('testconf.py'):
406 os.chdir(cwd) 406 os.chdir(cwd)
407 return 407 return
408 if os.path.isfile('testconf.py'): 408 if os.path.isfile('testconf.py'):
409 execfile('testconf.py', globals()) 409 execfile('testconf.py', globals())
410 os.chdir(cwd) 410 os.chdir(cwd)
427 427
428 try: 428 try:
429 if len(tasknames) > 1: 429 if len(tasknames) > 1:
430 print taskname 430 print taskname
431 except Exception: 431 except Exception:
432 if taskname != os.curdir or ntasks: 432 if taskname != os.path.curdir or ntasks:
433 print taskname 433 print taskname
434 434
435 try: del inname 435 try: del inname
436 except NameError: pass 436 except NameError: pass
437 try: del outname 437 try: del outname
438 except NameError: pass 438 except NameError: pass
439 try: del ansname 439 try: del ansname
440 except NameError: pass 440 except NameError: pass
441 441
442 if not namedefined and taskname != os.curdir: 442 if not namedefined and taskname != os.path.curdir:
443 name = os.path + os.sep + taskname 443 name = os.path.join(os.path.curdir, taskname)
444 for k in shared: 444 for k in shared:
445 g[k] = shared[k] 445 g[k] = shared[k]
446 446
447 oldcwd = os.getcwdu() 447 oldcwd = os.getcwdu()
448 chdir_and_exec_testconf() 448 chdir_and_exec_testconf()
601 except TypeError: 601 except TypeError:
602 testsexcluded.append(v) 602 testsexcluded.append(v)
603 603
604 # Windows doesn't like paths beginning with .\ and not ending with an extension 604 # Windows doesn't like paths beginning with .\ and not ending with an extension
605 name = os.path.normcase(name) 605 name = os.path.normcase(name)
606 if name.startswith('.\\'): 606 if os.name == 'nt' and name.startswith('.\\'):
607 name = name[2:] 607 name = name[2:]
608 608
609 newpointmap = {} 609 newpointmap = {}
610 610
611 for i in pointmap: 611 for i in pointmap: