File: regress.py.in

package info (click to toggle)
simulavr 0.1.2.2-6.2
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 2,760 kB
  • ctags: 3,179
  • sloc: ansic: 19,986; sh: 3,623; python: 3,528; makefile: 406; asm: 308; yacc: 145; lex: 48
file content (265 lines) | stat: -rw-r--r-- 7,244 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#! /usr/bin/env python
###############################################################################
#
# simulavr - A simulator for the Atmel AVR family of microcontrollers.
# Copyright (C) 2001, 2002  Theodore A. Roth
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
###############################################################################
#
# $Id: regress.py.in,v 1.9 2003/03/25 20:09:37 troth Exp $
#

# # @configure_input@

import os, sys, fnmatch, glob

# Check the python version
_v = sys.version_info
_ver = (int(_v[0]) << 16) + (int(_v[1]) << 8) + int(_v[2])
if _ver < 0x020101:
	sys.write('You need python >= 2.1.1 to run this program.\n')
	sys.write('Your python version is:\n%s\n' %(sys.version))
	sys.exit(1)

# This should let you run the regress.py.in script directly for testing.
# Remember that configure will replace '@<something>@'.
if '@srcdir@' == '@'+'srcdir'+'@':
	srcdir = '.'
else:
	srcdir = '@srcdir@'

regressdir = os.getcwd()

# Change dir to srcdir so that building in other dir works
os.chdir(srcdir)

# default path to simulator
sim_path = regressdir+'/../src/simulavr'

# Add modules dir to module search path
sys.path.append('modules')

import avr_target, base_test

"""Main regression test driver program.

Test cases are organised into three levels: directories -> modules -> classes.
Directories are the most generic and classes are the most specific.

This program will search the current directory for subdirectories with names
matching 'test_*'. Each matching subdirectory will be searched for python
modules with names matching test_*.py. Each module will be loaded and the
attributes searched for classes with names beginning with 'test_'. Each class
will perform a single test and if the test fails, an exception derived from
base_test.TestFail is raised to indicate that the test has failed.

There can be many matches are each level.

"""

EXIT_STATUS_PASS = 0
EXIT_STATUS_FAIL = 1

def run_tests(target, tdir=None, tmodule=None, tname=None):
	result = EXIT_STATUS_PASS

	num_tests  = 0
	num_passes = 0
	num_fails  = 0

	start_time = os.times()[4]

	if tdir is None:
		test_dirs = glob.glob('test_*')
	else:
		if tdir[:5] != 'test_':
			tdir = 'test_'+tdir
		test_dirs = [tdir]

	for test_dir in test_dirs:
		if tmodule is None:
			try:
				test_modules = os.listdir(test_dir)
			except OSError:
				# problem getting dir listing, go to next dir
				continue
		else:
			if tmodule[:5] != 'test_':
				tmodule = 'test_'+tmodule
			if tmodule[-3:] != '.py':
				tmodule += '.py'
			test_modules = [tmodule]

		print '='*8 + ' running tests in %s directory' % (test_dir)
		# add tests dir to module search patch
		sys.path.append(test_dir)

		# Loop through all files in test dir
		for file in test_modules:
			# skip files which are not test modules (test modules are 'test_*.py')
			if not fnmatch.fnmatch(file, 'test_*.py'):
				continue

			# get test module name by stripping off .py from file name
			test_module_name = file[:-3]
			print '-'*4 + ' loading tests from %s module' %(test_module_name)
			test_module = __import__(test_module_name)

			if tname is None:
				test_names = dir(test_module)
			else:
				if tname[:5] != 'test_':
					tname = 'test_'+tname
				test_names = [tname]

			# Loop through all attributes of test_module
			for test_name in test_names:
				# If attribute is not a test case, skip it.
				if test_name[:5] != 'test_':
					continue

				try:
					# Create an instance of the test case object and run it
					test = apply( getattr(test_module,test_name), (target,) )
					print '%-30s  ->  ' %(test_name),
					test.run()
				except base_test.TestFail, reason:
					print 'FAILED: %s' %(reason)
					num_fails += 1
					# Could also do a sys.exit(1) here is user wishes
					result = EXIT_STATUS_FAIL
				else:
					num_passes += 1
					print 'passed'

				num_tests += 1

				# reset the target after each test
				target.reset()

			test_names = None
		test_modules = None

		# remove test_dir from the module search path
		sys.path.remove(test_dir)

	elapsed = os.times()[4] - start_time

	print 
	print 'Ran %d tests in %.3f seconds [%0.3f tests/second].' % \
		  (num_tests, elapsed, num_tests/elapsed)
	print '  Number of Passing Tests: %d' %(num_passes)
	print '  Number of Failing Tests: %d' %(num_fails)
	print
	
	return result

def usage():
	print >> sys.stderr, """
Usage: regress.py [options] [[test_]dir] [[test_]module[.py]] [[test_]case]
  The 'test_' prefix on all args is optional.
  The '.py' extension on the test_module arg is also optional.

Options:
  -h, --help      : print this message and exit
  -s, --sim=<sim> : path to simulavr executable
      --stall     : stall the regression engine when done
"""
	sys.exit(1)

def run_simulator(prog, port=1212, dev="at90s8515"):
	"""Attempt to start up a simulator and return pid.
	"""

	# Check if prog file exists
	if not os.path.isfile(prog):
		print >> sys.stderr, '%s does not exist' %(prog)
		sys.exit(1)

	pid = os.fork()
	if pid == 0: # child process
		sys.stdout.close()
		sys.stderr.close()

		out = os.open(regressdir+'/sim.out', os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0644)
		os.dup2(out, 1)
		os.close(out)

		err = os.open(regressdir+'/sim.err', os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0644)
		os.dup2(err, 2)
		os.close(err)
		
		os.execlp( prog, prog, '-g', '-G', '-d', dev, '-p', str(port) )
		assert 0, 'error starting program' # should never get here.

	return pid
	
if __name__ == '__main__':
	import getopt, time, socket, signal

	# Parse command line options
	try:
		opts, args = getopt.getopt(sys.argv[1:], "hs:", ["help", "sim=", "stall"])
	except getopt.GetoptError:
		# print help information and exit:
		usage()

	stall = 0

	for o, a in opts:
		if o in ("-h", "--help"):
			usage()
		if o in ("-s", "--sim"):
			sim_path = a
		if o in ("--stall",):
			stall = 1

	if len(args) > 3:
		usage()
		
	sim_pid = run_simulator(sim_path)

	# Open a connection to the target
	tries = 5
	while (tries > 0):
		try:
			target = avr_target.AvrTarget()
		except socket.error:
			print >> sys.stderr, 'Simulator not responding, wait a second and try again'
			tries -= 1
			time.sleep(1)
		else:
			break
	if tries == 0:
		print >> sys.stderr, 'Fatal error: simulator did not start'
		sys.exit(1)

	# run the tests
	try:
		status = apply(run_tests, [target]+args)
	finally:
		# We always want to shut down the simulator
		target.close()

		if stall:
			raw_input('hit enter to quit...')

		# make sure that the simulator has quit
		os.kill(sim_pid, signal.SIGINT)
		os.waitpid(sim_pid, os.WNOHANG)
	
	sys.exit( status )