view upreckon-vcs @ 123:90c002c960cb

Fixed CPU time display on UNIX Previously, the total CPU time spent by the testee on all test cases up to and including the current one was displayed.
author Oleg Oshmyan <chortos@inbox.lv>
date Sun, 24 Apr 2011 19:28:40 +0100
parents 796eb7667fb0
children 517dd43f06f8
line wrap: on
line source

#! /usr/bin/env python
# Copyright (c) 2009-2011 Chortos-2 <chortos@inbox.lv>

from __future__ import division, with_statement
import optparse, sys, compat

from compat import *

version = '2.01.0 ($$REV$$)'
parser = optparse.OptionParser(version='Upreckon '+version, epilog='Python 2.5 or newer is required.')
parser.add_option('-1', dest='legacy', action='store_true', default=False, help='handle configuration files in a way more compatible with test.py 1.x')
parser.add_option('-u', '--update', dest='update', action='store_true', default=False, help='update the installed Upreckon to the latest publicly available version')
parser.add_option('-p', '--problem', dest='problems', metavar='PROBLEM', action='append', help='test only the PROBLEM (this option can be specified more than once with different problem names, all of which will be tested)')
parser.add_option('--list-problems', action='store_true', default=False, help='just list all problem names')
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')
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')
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')
parser.add_option('-t', '--detect-time', dest='autotime', action='store_true', default=False, help='spend a second detecting the most precise time measurement function')
parser.add_option('-k', '--skim', action='store_true', default=False, help='skip test groups as soon as one test case is failed')
parser.add_option('--no-time-limits', dest='no_maxtime', action='store_true', default=False, help='disable all time limits')

options, args = parser.parse_args()
parser.destroy()
del parser

if options.update:
	try:
		urllib, urlread = compat.import_urllib()
	except ImportError:
		sys.exit('Error: the urllib Python module is missing. Without it, an automatic update is impossible.')
	
	latesttext = urlread('http://chortos.selfip.net/~astiob/test.py/version.txt')
	latest = latesttext.split('.')
	installed = version.split('.')
	update = None
	
	if latest[0] > installed[0]:
		update = 'major'
	elif latest[0] == installed[0]:
		if latest[1] > installed[1]:
			update = 'feature'
		elif latest[1] == installed[1]:
			if latest[2] > installed[2]:
				update = 'bug-fixing'
			elif latest[2] == installed[2]:
				say('You are using the latest publicly available version of Upreckon (%s).' % latesttext)
				sys.exit()
	
	if not update:
		say('Your copy of Upreckon is newer (%s) than the publicly available version (%s).' % (version, latesttext))
		sys.exit()
	
	say('A %s update to Upreckon is available (%s). Downloading...' % (update, latesttext))
	sys.stdout.flush()
	# FIXME: need to update all files!
	urllib.urlretrieve('http://chortos.selfip.net/~astiob/test.py/test.py', sys.argv[0])
	say('Downloaded and installed. Now you are using Upreckon %s.' % latesttext)
	sys.exit()

import config, itertools, os, subprocess, sys, time

if options.legacy:
	compat.pseudobuiltins += 'xrange',

if options.list_problems:
	options.pause = False

import testcases

try:
	from testcases import pause
except ImportError:
	pause = None

try:
	globalconf = config.load_global()
	
	# Do this check here so that if we have to warn them, we do it as early as possible
	if options.pause and not pause and not hasattr(globalconf, 'pause'):
		if os.name == 'posix':
			globalconf.pause = 'read -s -n 1'
			say('Warning: configuration variable pause is not defined; it was devised automatically but the choice might be incorrect, so Upreckon might exit immediately after the testing is completed.', file=sys.stderr)
			sys.stderr.flush()
		elif os.name == 'nt':
			globalconf.pause = 'pause'
		else:
			sys.exit('Error: configuration variable pause is not defined and cannot be devised automatically.')
	
	from problem import *
	
	# Support single-problem configurations
	if globalconf.problems is None:
		shouldprintnames = False
		globalconf.multiproblem = False
		globalconf.problems = os.path.curdir,
	else:
		globalconf.multiproblem = True
		shouldprintnames = True
	
	if options.list_problems:
		for taskname in globalconf.problems:
			say(taskname)
		sys.exit()
	
	ntasks = 0
	nfulltasks = 0
	maxscore = 0
	realscore = 0
	
	for taskname in (globalconf.problems if not options.problems else options.problems):
		problem = Problem(taskname)
		
		if ntasks and not options.copyonly: say()
		if shouldprintnames: say(taskname)
		
		if options.copyonly:
			problem.copytestdata()
		else:
			real, max = problem.test()
		
		ntasks += 1
		nfulltasks += real == max
		realscore += real
		maxscore += max
	
	if options.copyonly:
		sys.exit()
	
	if ntasks != 1:
		say()
		say('Grand total: %g/%g weighted points; %d/%d problems solved fully' % (realscore, maxscore, nfulltasks, ntasks))
except KeyboardInterrupt:
	sys.exit('Exiting due to a keyboard interrupt.')

if options.pause:
	say('Press any key to exit...')
	sys.stdout.flush()
	
	if pause:
		pause()
	elif callable(globalconf.pause):
		globalconf.pause()
	else:
		with open(os.devnull, 'w') as devnull:
			subprocess.call(globalconf.pause, shell=True, stdout=devnull, stderr=subprocess.STDOUT)