xref: /aosp_15_r20/external/libxml2/xstc/xstc.py (revision 7c5688314b92172186c154356a6374bf7684c3ca)
1*7c568831SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*7c568831SAndroid Build Coastguard Worker
3*7c568831SAndroid Build Coastguard Worker#
4*7c568831SAndroid Build Coastguard Worker# This is the MS subset of the W3C test suite for XML Schemas.
5*7c568831SAndroid Build Coastguard Worker# This file is generated from the MS W3c test suite description file.
6*7c568831SAndroid Build Coastguard Worker#
7*7c568831SAndroid Build Coastguard Worker
8*7c568831SAndroid Build Coastguard Workerimport sys, os
9*7c568831SAndroid Build Coastguard Workerimport optparse
10*7c568831SAndroid Build Coastguard Workerimport libxml2
11*7c568831SAndroid Build Coastguard Worker
12*7c568831SAndroid Build Coastguard Workeropa = optparse.OptionParser()
13*7c568831SAndroid Build Coastguard Worker
14*7c568831SAndroid Build Coastguard Workeropa.add_option("-b", "--base", action="store", type="string", dest="baseDir",
15*7c568831SAndroid Build Coastguard Worker			   default="",
16*7c568831SAndroid Build Coastguard Worker			   help="""The base directory; i.e. the parent folder of the
17*7c568831SAndroid Build Coastguard Worker			   "nisttest", "suntest" and "msxsdtest" directories.""")
18*7c568831SAndroid Build Coastguard Worker
19*7c568831SAndroid Build Coastguard Workeropa.add_option("-o", "--out", action="store", type="string", dest="logFile",
20*7c568831SAndroid Build Coastguard Worker			   default="test.log",
21*7c568831SAndroid Build Coastguard Worker			   help="The filepath of the log file to be created")
22*7c568831SAndroid Build Coastguard Worker
23*7c568831SAndroid Build Coastguard Workeropa.add_option("--log", action="store_true", dest="enableLog",
24*7c568831SAndroid Build Coastguard Worker			   default=False,
25*7c568831SAndroid Build Coastguard Worker			   help="Create the log file")
26*7c568831SAndroid Build Coastguard Worker
27*7c568831SAndroid Build Coastguard Workeropa.add_option("--no-test-out", action="store_true", dest="disableTestStdOut",
28*7c568831SAndroid Build Coastguard Worker			   default=False,
29*7c568831SAndroid Build Coastguard Worker			   help="Don't output test results")
30*7c568831SAndroid Build Coastguard Worker
31*7c568831SAndroid Build Coastguard Workeropa.add_option("-s", "--silent", action="store_true", dest="silent", default=False,
32*7c568831SAndroid Build Coastguard Worker			   help="Disables display of all tests")
33*7c568831SAndroid Build Coastguard Worker
34*7c568831SAndroid Build Coastguard Workeropa.add_option("-v", "--verbose", action="store_true", dest="verbose",
35*7c568831SAndroid Build Coastguard Worker			   default=False,
36*7c568831SAndroid Build Coastguard Worker			   help="Displays all tests (only if --silent is not set)")
37*7c568831SAndroid Build Coastguard Worker
38*7c568831SAndroid Build Coastguard Workeropa.add_option("-x", "--max", type="int", dest="maxTestCount",
39*7c568831SAndroid Build Coastguard Worker			   default="-1",
40*7c568831SAndroid Build Coastguard Worker			   help="The maximum number of tests to be run")
41*7c568831SAndroid Build Coastguard Worker
42*7c568831SAndroid Build Coastguard Workeropa.add_option("-t", "--test", type="string", dest="singleTest",
43*7c568831SAndroid Build Coastguard Worker			   default=None,
44*7c568831SAndroid Build Coastguard Worker			   help="Runs the specified test only")
45*7c568831SAndroid Build Coastguard Worker
46*7c568831SAndroid Build Coastguard Workeropa.add_option("--tsw", "--test-starts-with", type="string", dest="testStartsWith",
47*7c568831SAndroid Build Coastguard Worker			   default=None,
48*7c568831SAndroid Build Coastguard Worker			   help="Runs the specified test(s), starting with the given string")
49*7c568831SAndroid Build Coastguard Worker
50*7c568831SAndroid Build Coastguard Workeropa.add_option("--rieo", "--report-internal-errors-only", action="store_true",
51*7c568831SAndroid Build Coastguard Worker			   dest="reportInternalErrOnly", default=False,
52*7c568831SAndroid Build Coastguard Worker			   help="Display erroneous tests of type 'internal' only")
53*7c568831SAndroid Build Coastguard Worker
54*7c568831SAndroid Build Coastguard Workeropa.add_option("--rueo", "--report-unimplemented-errors-only", action="store_true",
55*7c568831SAndroid Build Coastguard Worker			   dest="reportUnimplErrOnly", default=False,
56*7c568831SAndroid Build Coastguard Worker			   help="Display erroneous tests of type 'unimplemented' only")
57*7c568831SAndroid Build Coastguard Worker
58*7c568831SAndroid Build Coastguard Workeropa.add_option("--rmleo", "--report-mem-leak-errors-only", action="store_true",
59*7c568831SAndroid Build Coastguard Worker			   dest="reportMemLeakErrOnly", default=False,
60*7c568831SAndroid Build Coastguard Worker			   help="Display erroneous tests of type 'memory leak' only")
61*7c568831SAndroid Build Coastguard Worker
62*7c568831SAndroid Build Coastguard Workeropa.add_option("-c", "--combines", type="string", dest="combines",
63*7c568831SAndroid Build Coastguard Worker			   default=None,
64*7c568831SAndroid Build Coastguard Worker			   help="Combines to be run (all if omitted)")
65*7c568831SAndroid Build Coastguard Worker
66*7c568831SAndroid Build Coastguard Workeropa.add_option("--csw", "--csw", type="string", dest="combineStartsWith",
67*7c568831SAndroid Build Coastguard Worker			   default=None,
68*7c568831SAndroid Build Coastguard Worker			   help="Combines to be run (all if omitted)")
69*7c568831SAndroid Build Coastguard Worker
70*7c568831SAndroid Build Coastguard Workeropa.add_option("--rc", "--report-combines", action="store_true",
71*7c568831SAndroid Build Coastguard Worker			   dest="reportCombines", default=False,
72*7c568831SAndroid Build Coastguard Worker			   help="Display combine reports")
73*7c568831SAndroid Build Coastguard Worker
74*7c568831SAndroid Build Coastguard Workeropa.add_option("--rec", "--report-err-combines", action="store_true",
75*7c568831SAndroid Build Coastguard Worker			   dest="reportErrCombines", default=False,
76*7c568831SAndroid Build Coastguard Worker			   help="Display erroneous combine reports only")
77*7c568831SAndroid Build Coastguard Worker
78*7c568831SAndroid Build Coastguard Workeropa.add_option("--debug", action="store_true",
79*7c568831SAndroid Build Coastguard Worker			   dest="debugEnabled", default=False,
80*7c568831SAndroid Build Coastguard Worker			   help="Displays debug messages")
81*7c568831SAndroid Build Coastguard Worker
82*7c568831SAndroid Build Coastguard Workeropa.add_option("--info", action="store_true",
83*7c568831SAndroid Build Coastguard Worker			   dest="info", default=False,
84*7c568831SAndroid Build Coastguard Worker			   help="Displays info on the suite only. Does not run any test.")
85*7c568831SAndroid Build Coastguard Workeropa.add_option("--sax", action="store_true",
86*7c568831SAndroid Build Coastguard Worker			   dest="validationSAX", default=False,
87*7c568831SAndroid Build Coastguard Worker			   help="Use SAX2-driven validation.")
88*7c568831SAndroid Build Coastguard Workeropa.add_option("--tn", action="store_true",
89*7c568831SAndroid Build Coastguard Worker			   dest="displayTestName", default=False,
90*7c568831SAndroid Build Coastguard Worker			   help="Display the test name in every case.")
91*7c568831SAndroid Build Coastguard Worker
92*7c568831SAndroid Build Coastguard Worker(options, args) = opa.parse_args()
93*7c568831SAndroid Build Coastguard Worker
94*7c568831SAndroid Build Coastguard Workerif options.combines is not None:
95*7c568831SAndroid Build Coastguard Worker	options.combines = options.combines.split()
96*7c568831SAndroid Build Coastguard Worker
97*7c568831SAndroid Build Coastguard Worker################################################
98*7c568831SAndroid Build Coastguard Worker# The vars below are not intended to be changed.
99*7c568831SAndroid Build Coastguard Worker#
100*7c568831SAndroid Build Coastguard Worker
101*7c568831SAndroid Build Coastguard WorkermsgSchemaNotValidButShould =  "The schema should be valid."
102*7c568831SAndroid Build Coastguard WorkermsgSchemaValidButShouldNot = "The schema should be invalid."
103*7c568831SAndroid Build Coastguard WorkermsgInstanceNotValidButShould = "The instance should be valid."
104*7c568831SAndroid Build Coastguard WorkermsgInstanceValidButShouldNot = "The instance should be invalid."
105*7c568831SAndroid Build Coastguard WorkervendorNIST = "NIST"
106*7c568831SAndroid Build Coastguard WorkervendorNIST_2 = "NIST-2"
107*7c568831SAndroid Build Coastguard WorkervendorSUN  = "SUN"
108*7c568831SAndroid Build Coastguard WorkervendorMS   = "MS"
109*7c568831SAndroid Build Coastguard Worker
110*7c568831SAndroid Build Coastguard Worker###################
111*7c568831SAndroid Build Coastguard Worker# Helper functions.
112*7c568831SAndroid Build Coastguard Worker#
113*7c568831SAndroid Build Coastguard Workervendor = None
114*7c568831SAndroid Build Coastguard Worker
115*7c568831SAndroid Build Coastguard Workerdef handleError(test, msg):
116*7c568831SAndroid Build Coastguard Worker	global options
117*7c568831SAndroid Build Coastguard Worker	if not options.silent:
118*7c568831SAndroid Build Coastguard Worker		test.addLibLog("'%s'   LIB: %s" % (test.name, msg))
119*7c568831SAndroid Build Coastguard Worker	if msg.find("Unimplemented") > -1:
120*7c568831SAndroid Build Coastguard Worker		test.failUnimplemented()
121*7c568831SAndroid Build Coastguard Worker	elif msg.find("Internal") > -1:
122*7c568831SAndroid Build Coastguard Worker		test.failInternal()
123*7c568831SAndroid Build Coastguard Worker
124*7c568831SAndroid Build Coastguard Worker
125*7c568831SAndroid Build Coastguard Workerdef fixFileNames(fileName):
126*7c568831SAndroid Build Coastguard Worker	if (fileName is None) or (fileName == ""):
127*7c568831SAndroid Build Coastguard Worker		return ""
128*7c568831SAndroid Build Coastguard Worker	dirs = fileName.split("/")
129*7c568831SAndroid Build Coastguard Worker	if dirs[1] != "Tests":
130*7c568831SAndroid Build Coastguard Worker		fileName = os.path.join(".", "Tests")
131*7c568831SAndroid Build Coastguard Worker		for dir in dirs[1:]:
132*7c568831SAndroid Build Coastguard Worker			fileName = os.path.join(fileName, dir)
133*7c568831SAndroid Build Coastguard Worker	return fileName
134*7c568831SAndroid Build Coastguard Worker
135*7c568831SAndroid Build Coastguard Workerclass XSTCTestGroup:
136*7c568831SAndroid Build Coastguard Worker	def __init__(self, name, schemaFileName, descr):
137*7c568831SAndroid Build Coastguard Worker		global vendor, vendorNIST_2
138*7c568831SAndroid Build Coastguard Worker		self.name = name
139*7c568831SAndroid Build Coastguard Worker		self.descr = descr
140*7c568831SAndroid Build Coastguard Worker		self.mainSchema = True
141*7c568831SAndroid Build Coastguard Worker		self.schemaFileName = fixFileNames(schemaFileName)
142*7c568831SAndroid Build Coastguard Worker		self.schemaParsed = False
143*7c568831SAndroid Build Coastguard Worker		self.schemaTried = False
144*7c568831SAndroid Build Coastguard Worker
145*7c568831SAndroid Build Coastguard Worker	def setSchema(self, schemaFileName, parsed):
146*7c568831SAndroid Build Coastguard Worker		if not self.mainSchema:
147*7c568831SAndroid Build Coastguard Worker			return
148*7c568831SAndroid Build Coastguard Worker		self.mainSchema = False
149*7c568831SAndroid Build Coastguard Worker		self.schemaParsed = parsed
150*7c568831SAndroid Build Coastguard Worker		self.schemaTried = True
151*7c568831SAndroid Build Coastguard Worker
152*7c568831SAndroid Build Coastguard Workerclass XSTCTestCase:
153*7c568831SAndroid Build Coastguard Worker
154*7c568831SAndroid Build Coastguard Worker		   # <!-- groupName, Name, Accepted, File, Val, Descr
155*7c568831SAndroid Build Coastguard Worker	def __init__(self, isSchema, groupName, name, accepted, file, val, descr):
156*7c568831SAndroid Build Coastguard Worker		global options
157*7c568831SAndroid Build Coastguard Worker		#
158*7c568831SAndroid Build Coastguard Worker		# Constructor.
159*7c568831SAndroid Build Coastguard Worker		#
160*7c568831SAndroid Build Coastguard Worker		self.testRunner = None
161*7c568831SAndroid Build Coastguard Worker		self.isSchema = isSchema
162*7c568831SAndroid Build Coastguard Worker		self.groupName = groupName
163*7c568831SAndroid Build Coastguard Worker		self.name = name
164*7c568831SAndroid Build Coastguard Worker		self.accepted = accepted
165*7c568831SAndroid Build Coastguard Worker		self.fileName = fixFileNames(file)
166*7c568831SAndroid Build Coastguard Worker		self.val = val
167*7c568831SAndroid Build Coastguard Worker		self.descr = descr
168*7c568831SAndroid Build Coastguard Worker		self.failed = False
169*7c568831SAndroid Build Coastguard Worker		self.combineName = None
170*7c568831SAndroid Build Coastguard Worker
171*7c568831SAndroid Build Coastguard Worker		self.log = []
172*7c568831SAndroid Build Coastguard Worker		self.libLog = []
173*7c568831SAndroid Build Coastguard Worker		self.initialMemUsed = 0
174*7c568831SAndroid Build Coastguard Worker		self.memLeak = 0
175*7c568831SAndroid Build Coastguard Worker		self.excepted = False
176*7c568831SAndroid Build Coastguard Worker		self.bad = False
177*7c568831SAndroid Build Coastguard Worker		self.unimplemented = False
178*7c568831SAndroid Build Coastguard Worker		self.internalErr = False
179*7c568831SAndroid Build Coastguard Worker		self.noSchemaErr = False
180*7c568831SAndroid Build Coastguard Worker		self.failed = False
181*7c568831SAndroid Build Coastguard Worker		#
182*7c568831SAndroid Build Coastguard Worker		# Init the log.
183*7c568831SAndroid Build Coastguard Worker		#
184*7c568831SAndroid Build Coastguard Worker		if not options.silent:
185*7c568831SAndroid Build Coastguard Worker			if self.descr is not None:
186*7c568831SAndroid Build Coastguard Worker				self.log.append("'%s'   descr: %s\n" % (self.name, self.descr))
187*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s'   exp validity: %d\n" % (self.name, self.val))
188*7c568831SAndroid Build Coastguard Worker
189*7c568831SAndroid Build Coastguard Worker	def initTest(self, runner):
190*7c568831SAndroid Build Coastguard Worker		global vendorNIST, vendorSUN, vendorMS, vendorNIST_2, options, vendor
191*7c568831SAndroid Build Coastguard Worker		#
192*7c568831SAndroid Build Coastguard Worker		# Get the test-group.
193*7c568831SAndroid Build Coastguard Worker		#
194*7c568831SAndroid Build Coastguard Worker		self.runner = runner
195*7c568831SAndroid Build Coastguard Worker		self.group = runner.getGroup(self.groupName)
196*7c568831SAndroid Build Coastguard Worker		if vendor == vendorMS or vendor == vendorSUN:
197*7c568831SAndroid Build Coastguard Worker			#
198*7c568831SAndroid Build Coastguard Worker			# Use the last given directory for the combine name.
199*7c568831SAndroid Build Coastguard Worker			#
200*7c568831SAndroid Build Coastguard Worker			dirs = self.fileName.split("/")
201*7c568831SAndroid Build Coastguard Worker			self.combineName = dirs[len(dirs) -2]
202*7c568831SAndroid Build Coastguard Worker		elif vendor == vendorNIST:
203*7c568831SAndroid Build Coastguard Worker			#
204*7c568831SAndroid Build Coastguard Worker			# NIST files are named in the following form:
205*7c568831SAndroid Build Coastguard Worker			# "NISTSchema-short-pattern-1.xsd"
206*7c568831SAndroid Build Coastguard Worker			#
207*7c568831SAndroid Build Coastguard Worker			tokens = self.name.split("-")
208*7c568831SAndroid Build Coastguard Worker			self.combineName = tokens[1]
209*7c568831SAndroid Build Coastguard Worker		elif vendor == vendorNIST_2:
210*7c568831SAndroid Build Coastguard Worker			#
211*7c568831SAndroid Build Coastguard Worker			# Group-names have the form: "atomic-normalizedString-length-1"
212*7c568831SAndroid Build Coastguard Worker			#
213*7c568831SAndroid Build Coastguard Worker			tokens = self.groupName.split("-")
214*7c568831SAndroid Build Coastguard Worker			self.combineName = "%s-%s" % (tokens[0], tokens[1])
215*7c568831SAndroid Build Coastguard Worker		else:
216*7c568831SAndroid Build Coastguard Worker			self.combineName = "unknown"
217*7c568831SAndroid Build Coastguard Worker			raise Exception("Could not compute the combine name of a test.")
218*7c568831SAndroid Build Coastguard Worker		if (not options.silent) and (self.group.descr is not None):
219*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s'   group-descr: %s\n" % (self.name, self.group.descr))
220*7c568831SAndroid Build Coastguard Worker
221*7c568831SAndroid Build Coastguard Worker
222*7c568831SAndroid Build Coastguard Worker	def addLibLog(self, msg):
223*7c568831SAndroid Build Coastguard Worker		"""This one is intended to be used by the error handler
224*7c568831SAndroid Build Coastguard Worker		function"""
225*7c568831SAndroid Build Coastguard Worker		global options
226*7c568831SAndroid Build Coastguard Worker		if not options.silent:
227*7c568831SAndroid Build Coastguard Worker			self.libLog.append(msg)
228*7c568831SAndroid Build Coastguard Worker
229*7c568831SAndroid Build Coastguard Worker	def fail(self, msg):
230*7c568831SAndroid Build Coastguard Worker		global options
231*7c568831SAndroid Build Coastguard Worker		self.failed = True
232*7c568831SAndroid Build Coastguard Worker		if not options.silent:
233*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' ( FAILED: %s\n" % (self.name, msg))
234*7c568831SAndroid Build Coastguard Worker
235*7c568831SAndroid Build Coastguard Worker	def failNoSchema(self):
236*7c568831SAndroid Build Coastguard Worker		global options
237*7c568831SAndroid Build Coastguard Worker		self.failed = True
238*7c568831SAndroid Build Coastguard Worker		self.noSchemaErr = True
239*7c568831SAndroid Build Coastguard Worker		if not options.silent:
240*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' X NO-SCHEMA\n" % (self.name))
241*7c568831SAndroid Build Coastguard Worker
242*7c568831SAndroid Build Coastguard Worker	def failInternal(self):
243*7c568831SAndroid Build Coastguard Worker		global options
244*7c568831SAndroid Build Coastguard Worker		self.failed = True
245*7c568831SAndroid Build Coastguard Worker		self.internalErr = True
246*7c568831SAndroid Build Coastguard Worker		if not options.silent:
247*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' * INTERNAL\n" % self.name)
248*7c568831SAndroid Build Coastguard Worker
249*7c568831SAndroid Build Coastguard Worker	def failUnimplemented(self):
250*7c568831SAndroid Build Coastguard Worker		global options
251*7c568831SAndroid Build Coastguard Worker		self.failed = True
252*7c568831SAndroid Build Coastguard Worker		self.unimplemented = True
253*7c568831SAndroid Build Coastguard Worker		if not options.silent:
254*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' ? UNIMPLEMENTED\n" % self.name)
255*7c568831SAndroid Build Coastguard Worker
256*7c568831SAndroid Build Coastguard Worker	def failCritical(self, msg):
257*7c568831SAndroid Build Coastguard Worker		global options
258*7c568831SAndroid Build Coastguard Worker		self.failed = True
259*7c568831SAndroid Build Coastguard Worker		self.bad = True
260*7c568831SAndroid Build Coastguard Worker		if not options.silent:
261*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' ! BAD: %s\n" % (self.name, msg))
262*7c568831SAndroid Build Coastguard Worker
263*7c568831SAndroid Build Coastguard Worker	def failExcept(self, e):
264*7c568831SAndroid Build Coastguard Worker		global options
265*7c568831SAndroid Build Coastguard Worker		self.failed = True
266*7c568831SAndroid Build Coastguard Worker		self.excepted = True
267*7c568831SAndroid Build Coastguard Worker		if not options.silent:
268*7c568831SAndroid Build Coastguard Worker			self.log.append("'%s' # EXCEPTION: %s\n" % (self.name, e.__str__()))
269*7c568831SAndroid Build Coastguard Worker
270*7c568831SAndroid Build Coastguard Worker	def setUp(self):
271*7c568831SAndroid Build Coastguard Worker		#
272*7c568831SAndroid Build Coastguard Worker		# Set up Libxml2.
273*7c568831SAndroid Build Coastguard Worker		#
274*7c568831SAndroid Build Coastguard Worker		self.initialMemUsed = libxml2.debugMemory(1)
275*7c568831SAndroid Build Coastguard Worker		libxml2.initParser()
276*7c568831SAndroid Build Coastguard Worker		libxml2.lineNumbersDefault(1)
277*7c568831SAndroid Build Coastguard Worker		libxml2.registerErrorHandler(handleError, self)
278*7c568831SAndroid Build Coastguard Worker
279*7c568831SAndroid Build Coastguard Worker	def tearDown(self):
280*7c568831SAndroid Build Coastguard Worker		libxml2.schemaCleanupTypes()
281*7c568831SAndroid Build Coastguard Worker		libxml2.cleanupParser()
282*7c568831SAndroid Build Coastguard Worker		self.memLeak = libxml2.debugMemory(1) - self.initialMemUsed
283*7c568831SAndroid Build Coastguard Worker
284*7c568831SAndroid Build Coastguard Worker	def isIOError(self, file, docType):
285*7c568831SAndroid Build Coastguard Worker		err = None
286*7c568831SAndroid Build Coastguard Worker		try:
287*7c568831SAndroid Build Coastguard Worker			err = libxml2.lastError()
288*7c568831SAndroid Build Coastguard Worker		except:
289*7c568831SAndroid Build Coastguard Worker			# Suppress exceptions.
290*7c568831SAndroid Build Coastguard Worker			pass
291*7c568831SAndroid Build Coastguard Worker		if (err is None):
292*7c568831SAndroid Build Coastguard Worker			return False
293*7c568831SAndroid Build Coastguard Worker		if err.domain() == libxml2.XML_FROM_IO:
294*7c568831SAndroid Build Coastguard Worker			self.failCritical("failed to access the %s resource '%s'\n" % (docType, file))
295*7c568831SAndroid Build Coastguard Worker
296*7c568831SAndroid Build Coastguard Worker	def debugMsg(self, msg):
297*7c568831SAndroid Build Coastguard Worker		global options
298*7c568831SAndroid Build Coastguard Worker		if options.debugEnabled:
299*7c568831SAndroid Build Coastguard Worker			sys.stdout.write("'%s'   DEBUG: %s\n" % (self.name, msg))
300*7c568831SAndroid Build Coastguard Worker
301*7c568831SAndroid Build Coastguard Worker	def finalize(self):
302*7c568831SAndroid Build Coastguard Worker		global options
303*7c568831SAndroid Build Coastguard Worker		"""Adds additional info to the log."""
304*7c568831SAndroid Build Coastguard Worker		#
305*7c568831SAndroid Build Coastguard Worker		# Add libxml2 messages.
306*7c568831SAndroid Build Coastguard Worker		#
307*7c568831SAndroid Build Coastguard Worker		if not options.silent:
308*7c568831SAndroid Build Coastguard Worker			self.log.extend(self.libLog)
309*7c568831SAndroid Build Coastguard Worker			#
310*7c568831SAndroid Build Coastguard Worker			# Add memory leaks.
311*7c568831SAndroid Build Coastguard Worker			#
312*7c568831SAndroid Build Coastguard Worker			if self.memLeak != 0:
313*7c568831SAndroid Build Coastguard Worker				self.log.append("%s + memory leak: %d bytes\n" % (self.name, self.memLeak))
314*7c568831SAndroid Build Coastguard Worker
315*7c568831SAndroid Build Coastguard Worker	def run(self):
316*7c568831SAndroid Build Coastguard Worker		"""Runs a test."""
317*7c568831SAndroid Build Coastguard Worker		global options
318*7c568831SAndroid Build Coastguard Worker
319*7c568831SAndroid Build Coastguard Worker		##filePath = os.path.join(options.baseDir, self.fileName)
320*7c568831SAndroid Build Coastguard Worker		# filePath = "%s/%s/%s/%s" % (options.baseDir, self.test_Folder, self.schema_Folder, self.schema_File)
321*7c568831SAndroid Build Coastguard Worker		if options.displayTestName:
322*7c568831SAndroid Build Coastguard Worker			sys.stdout.write("'%s'\n" % self.name)
323*7c568831SAndroid Build Coastguard Worker		try:
324*7c568831SAndroid Build Coastguard Worker			self.validate()
325*7c568831SAndroid Build Coastguard Worker		except (Exception, libxml2.parserError, libxml2.treeError) as e:
326*7c568831SAndroid Build Coastguard Worker			self.failExcept(e)
327*7c568831SAndroid Build Coastguard Worker
328*7c568831SAndroid Build Coastguard Workerdef parseSchema(fileName):
329*7c568831SAndroid Build Coastguard Worker	schema = None
330*7c568831SAndroid Build Coastguard Worker	ctxt = libxml2.schemaNewParserCtxt(fileName)
331*7c568831SAndroid Build Coastguard Worker	try:
332*7c568831SAndroid Build Coastguard Worker		try:
333*7c568831SAndroid Build Coastguard Worker			schema = ctxt.schemaParse()
334*7c568831SAndroid Build Coastguard Worker		except:
335*7c568831SAndroid Build Coastguard Worker			pass
336*7c568831SAndroid Build Coastguard Worker	finally:
337*7c568831SAndroid Build Coastguard Worker		del ctxt
338*7c568831SAndroid Build Coastguard Worker		return schema
339*7c568831SAndroid Build Coastguard Worker
340*7c568831SAndroid Build Coastguard Worker
341*7c568831SAndroid Build Coastguard Workerclass XSTCSchemaTest(XSTCTestCase):
342*7c568831SAndroid Build Coastguard Worker
343*7c568831SAndroid Build Coastguard Worker	def __init__(self, groupName, name, accepted, file, val, descr):
344*7c568831SAndroid Build Coastguard Worker		XSTCTestCase.__init__(self, 1, groupName, name, accepted, file, val, descr)
345*7c568831SAndroid Build Coastguard Worker
346*7c568831SAndroid Build Coastguard Worker	def validate(self):
347*7c568831SAndroid Build Coastguard Worker		global msgSchemaNotValidButShould, msgSchemaValidButShouldNot
348*7c568831SAndroid Build Coastguard Worker		schema = None
349*7c568831SAndroid Build Coastguard Worker		filePath = self.fileName
350*7c568831SAndroid Build Coastguard Worker		# os.path.join(options.baseDir, self.fileName)
351*7c568831SAndroid Build Coastguard Worker		valid = 0
352*7c568831SAndroid Build Coastguard Worker		try:
353*7c568831SAndroid Build Coastguard Worker			#
354*7c568831SAndroid Build Coastguard Worker			# Parse the schema.
355*7c568831SAndroid Build Coastguard Worker			#
356*7c568831SAndroid Build Coastguard Worker			self.debugMsg("loading schema: %s" % filePath)
357*7c568831SAndroid Build Coastguard Worker			schema = parseSchema(filePath)
358*7c568831SAndroid Build Coastguard Worker			self.debugMsg("after loading schema")
359*7c568831SAndroid Build Coastguard Worker			if schema is None:
360*7c568831SAndroid Build Coastguard Worker				self.debugMsg("schema is None")
361*7c568831SAndroid Build Coastguard Worker				self.debugMsg("checking for IO errors...")
362*7c568831SAndroid Build Coastguard Worker				if self.isIOError(filePath, "schema"):
363*7c568831SAndroid Build Coastguard Worker					return
364*7c568831SAndroid Build Coastguard Worker			self.debugMsg("checking schema result")
365*7c568831SAndroid Build Coastguard Worker			if (schema is None and self.val) or (schema is not None and self.val == 0):
366*7c568831SAndroid Build Coastguard Worker				self.debugMsg("schema result is BAD")
367*7c568831SAndroid Build Coastguard Worker				if (schema == None):
368*7c568831SAndroid Build Coastguard Worker					self.fail(msgSchemaNotValidButShould)
369*7c568831SAndroid Build Coastguard Worker				else:
370*7c568831SAndroid Build Coastguard Worker					self.fail(msgSchemaValidButShouldNot)
371*7c568831SAndroid Build Coastguard Worker			else:
372*7c568831SAndroid Build Coastguard Worker				self.debugMsg("schema result is OK")
373*7c568831SAndroid Build Coastguard Worker		finally:
374*7c568831SAndroid Build Coastguard Worker			self.group.setSchema(self.fileName, schema is not None)
375*7c568831SAndroid Build Coastguard Worker			del schema
376*7c568831SAndroid Build Coastguard Worker
377*7c568831SAndroid Build Coastguard Workerclass XSTCInstanceTest(XSTCTestCase):
378*7c568831SAndroid Build Coastguard Worker
379*7c568831SAndroid Build Coastguard Worker	def __init__(self, groupName, name, accepted, file, val, descr):
380*7c568831SAndroid Build Coastguard Worker		XSTCTestCase.__init__(self, 0, groupName, name, accepted, file, val, descr)
381*7c568831SAndroid Build Coastguard Worker
382*7c568831SAndroid Build Coastguard Worker	def validate(self):
383*7c568831SAndroid Build Coastguard Worker		instance = None
384*7c568831SAndroid Build Coastguard Worker		schema = None
385*7c568831SAndroid Build Coastguard Worker		filePath = self.fileName
386*7c568831SAndroid Build Coastguard Worker		# os.path.join(options.baseDir, self.fileName)
387*7c568831SAndroid Build Coastguard Worker
388*7c568831SAndroid Build Coastguard Worker		if not self.group.schemaParsed and self.group.schemaTried:
389*7c568831SAndroid Build Coastguard Worker			self.failNoSchema()
390*7c568831SAndroid Build Coastguard Worker			return
391*7c568831SAndroid Build Coastguard Worker
392*7c568831SAndroid Build Coastguard Worker		self.debugMsg("loading instance: %s" % filePath)
393*7c568831SAndroid Build Coastguard Worker		parserCtxt = libxml2.newParserCtxt()
394*7c568831SAndroid Build Coastguard Worker		if (parserCtxt is None):
395*7c568831SAndroid Build Coastguard Worker			# TODO: Is this one necessary, or will an exception
396*7c568831SAndroid Build Coastguard Worker			# be already raised?
397*7c568831SAndroid Build Coastguard Worker			raise Exception("Could not create the instance parser context.")
398*7c568831SAndroid Build Coastguard Worker		if not options.validationSAX:
399*7c568831SAndroid Build Coastguard Worker			try:
400*7c568831SAndroid Build Coastguard Worker				try:
401*7c568831SAndroid Build Coastguard Worker					instance = parserCtxt.ctxtReadFile(filePath, None, libxml2.XML_PARSE_NOWARNING)
402*7c568831SAndroid Build Coastguard Worker				except:
403*7c568831SAndroid Build Coastguard Worker					# Suppress exceptions.
404*7c568831SAndroid Build Coastguard Worker					pass
405*7c568831SAndroid Build Coastguard Worker			finally:
406*7c568831SAndroid Build Coastguard Worker				del parserCtxt
407*7c568831SAndroid Build Coastguard Worker			self.debugMsg("after loading instance")
408*7c568831SAndroid Build Coastguard Worker			if instance is None:
409*7c568831SAndroid Build Coastguard Worker				self.debugMsg("instance is None")
410*7c568831SAndroid Build Coastguard Worker				self.failCritical("Failed to parse the instance for unknown reasons.")
411*7c568831SAndroid Build Coastguard Worker				return
412*7c568831SAndroid Build Coastguard Worker		try:
413*7c568831SAndroid Build Coastguard Worker			#
414*7c568831SAndroid Build Coastguard Worker			# Validate the instance.
415*7c568831SAndroid Build Coastguard Worker			#
416*7c568831SAndroid Build Coastguard Worker			self.debugMsg("loading schema: %s" % self.group.schemaFileName)
417*7c568831SAndroid Build Coastguard Worker			schema = parseSchema(self.group.schemaFileName)
418*7c568831SAndroid Build Coastguard Worker			try:
419*7c568831SAndroid Build Coastguard Worker				validationCtxt = schema.schemaNewValidCtxt()
420*7c568831SAndroid Build Coastguard Worker				#validationCtxt = libxml2.schemaNewValidCtxt(None)
421*7c568831SAndroid Build Coastguard Worker				if (validationCtxt is None):
422*7c568831SAndroid Build Coastguard Worker					self.failCritical("Could not create the validation context.")
423*7c568831SAndroid Build Coastguard Worker					return
424*7c568831SAndroid Build Coastguard Worker				try:
425*7c568831SAndroid Build Coastguard Worker					self.debugMsg("validating instance")
426*7c568831SAndroid Build Coastguard Worker					if options.validationSAX:
427*7c568831SAndroid Build Coastguard Worker						instance_Err = validationCtxt.schemaValidateFile(filePath, 0)
428*7c568831SAndroid Build Coastguard Worker					else:
429*7c568831SAndroid Build Coastguard Worker						instance_Err = validationCtxt.schemaValidateDoc(instance)
430*7c568831SAndroid Build Coastguard Worker					self.debugMsg("after instance validation")
431*7c568831SAndroid Build Coastguard Worker					self.debugMsg("instance-err: %d" % instance_Err)
432*7c568831SAndroid Build Coastguard Worker					if (instance_Err != 0 and self.val == 1) or (instance_Err == 0 and self.val == 0):
433*7c568831SAndroid Build Coastguard Worker						self.debugMsg("instance result is BAD")
434*7c568831SAndroid Build Coastguard Worker						if (instance_Err != 0):
435*7c568831SAndroid Build Coastguard Worker							self.fail(msgInstanceNotValidButShould)
436*7c568831SAndroid Build Coastguard Worker						else:
437*7c568831SAndroid Build Coastguard Worker							self.fail(msgInstanceValidButShouldNot)
438*7c568831SAndroid Build Coastguard Worker
439*7c568831SAndroid Build Coastguard Worker					else:
440*7c568831SAndroid Build Coastguard Worker								self.debugMsg("instance result is OK")
441*7c568831SAndroid Build Coastguard Worker				finally:
442*7c568831SAndroid Build Coastguard Worker					del validationCtxt
443*7c568831SAndroid Build Coastguard Worker			finally:
444*7c568831SAndroid Build Coastguard Worker				del schema
445*7c568831SAndroid Build Coastguard Worker		finally:
446*7c568831SAndroid Build Coastguard Worker			if instance is not None:
447*7c568831SAndroid Build Coastguard Worker				instance.freeDoc()
448*7c568831SAndroid Build Coastguard Worker
449*7c568831SAndroid Build Coastguard Worker
450*7c568831SAndroid Build Coastguard Worker####################
451*7c568831SAndroid Build Coastguard Worker# Test runner class.
452*7c568831SAndroid Build Coastguard Worker#
453*7c568831SAndroid Build Coastguard Worker
454*7c568831SAndroid Build Coastguard Workerclass XSTCTestRunner:
455*7c568831SAndroid Build Coastguard Worker
456*7c568831SAndroid Build Coastguard Worker	CNT_TOTAL = 0
457*7c568831SAndroid Build Coastguard Worker	CNT_RAN = 1
458*7c568831SAndroid Build Coastguard Worker	CNT_SUCCEEDED = 2
459*7c568831SAndroid Build Coastguard Worker	CNT_FAILED = 3
460*7c568831SAndroid Build Coastguard Worker	CNT_UNIMPLEMENTED = 4
461*7c568831SAndroid Build Coastguard Worker	CNT_INTERNAL = 5
462*7c568831SAndroid Build Coastguard Worker	CNT_BAD = 6
463*7c568831SAndroid Build Coastguard Worker	CNT_EXCEPTED = 7
464*7c568831SAndroid Build Coastguard Worker	CNT_MEMLEAK = 8
465*7c568831SAndroid Build Coastguard Worker	CNT_NOSCHEMA = 9
466*7c568831SAndroid Build Coastguard Worker	CNT_NOTACCEPTED = 10
467*7c568831SAndroid Build Coastguard Worker	CNT_SCHEMA_TEST = 11
468*7c568831SAndroid Build Coastguard Worker
469*7c568831SAndroid Build Coastguard Worker	def __init__(self):
470*7c568831SAndroid Build Coastguard Worker		self.logFile = None
471*7c568831SAndroid Build Coastguard Worker		self.counters = self.createCounters()
472*7c568831SAndroid Build Coastguard Worker		self.testList = []
473*7c568831SAndroid Build Coastguard Worker		self.combinesRan = {}
474*7c568831SAndroid Build Coastguard Worker		self.groups = {}
475*7c568831SAndroid Build Coastguard Worker		self.curGroup = None
476*7c568831SAndroid Build Coastguard Worker
477*7c568831SAndroid Build Coastguard Worker	def createCounters(self):
478*7c568831SAndroid Build Coastguard Worker		counters = {self.CNT_TOTAL:0, self.CNT_RAN:0, self.CNT_SUCCEEDED:0,
479*7c568831SAndroid Build Coastguard Worker		self.CNT_FAILED:0, self.CNT_UNIMPLEMENTED:0, self.CNT_INTERNAL:0, self.CNT_BAD:0,
480*7c568831SAndroid Build Coastguard Worker		self.CNT_EXCEPTED:0, self.CNT_MEMLEAK:0, self.CNT_NOSCHEMA:0, self.CNT_NOTACCEPTED:0,
481*7c568831SAndroid Build Coastguard Worker		self.CNT_SCHEMA_TEST:0}
482*7c568831SAndroid Build Coastguard Worker
483*7c568831SAndroid Build Coastguard Worker		return counters
484*7c568831SAndroid Build Coastguard Worker
485*7c568831SAndroid Build Coastguard Worker	def addTest(self, test):
486*7c568831SAndroid Build Coastguard Worker		self.testList.append(test)
487*7c568831SAndroid Build Coastguard Worker		test.initTest(self)
488*7c568831SAndroid Build Coastguard Worker
489*7c568831SAndroid Build Coastguard Worker	def getGroup(self, groupName):
490*7c568831SAndroid Build Coastguard Worker		return self.groups[groupName]
491*7c568831SAndroid Build Coastguard Worker
492*7c568831SAndroid Build Coastguard Worker	def addGroup(self, group):
493*7c568831SAndroid Build Coastguard Worker		self.groups[group.name] = group
494*7c568831SAndroid Build Coastguard Worker
495*7c568831SAndroid Build Coastguard Worker	def updateCounters(self, test, counters):
496*7c568831SAndroid Build Coastguard Worker		if test.memLeak != 0:
497*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_MEMLEAK] += 1
498*7c568831SAndroid Build Coastguard Worker		if not test.failed:
499*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_SUCCEEDED] +=1
500*7c568831SAndroid Build Coastguard Worker		if test.failed:
501*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_FAILED] += 1
502*7c568831SAndroid Build Coastguard Worker		if test.bad:
503*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_BAD] += 1
504*7c568831SAndroid Build Coastguard Worker		if test.unimplemented:
505*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_UNIMPLEMENTED] += 1
506*7c568831SAndroid Build Coastguard Worker		if test.internalErr:
507*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_INTERNAL] += 1
508*7c568831SAndroid Build Coastguard Worker		if test.noSchemaErr:
509*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_NOSCHEMA] += 1
510*7c568831SAndroid Build Coastguard Worker		if test.excepted:
511*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_EXCEPTED] += 1
512*7c568831SAndroid Build Coastguard Worker		if not test.accepted:
513*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_NOTACCEPTED] += 1
514*7c568831SAndroid Build Coastguard Worker		if test.isSchema:
515*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_SCHEMA_TEST] += 1
516*7c568831SAndroid Build Coastguard Worker		return counters
517*7c568831SAndroid Build Coastguard Worker
518*7c568831SAndroid Build Coastguard Worker	def displayResults(self, out, all, combName, counters):
519*7c568831SAndroid Build Coastguard Worker		out.write("\n")
520*7c568831SAndroid Build Coastguard Worker		if all:
521*7c568831SAndroid Build Coastguard Worker			if options.combines is not None:
522*7c568831SAndroid Build Coastguard Worker				out.write("combine(s): %s\n" % str(options.combines))
523*7c568831SAndroid Build Coastguard Worker		elif combName is not None:
524*7c568831SAndroid Build Coastguard Worker			out.write("combine : %s\n" % combName)
525*7c568831SAndroid Build Coastguard Worker		out.write("  total           : %d\n" % counters[self.CNT_TOTAL])
526*7c568831SAndroid Build Coastguard Worker		if all or options.combines is not None:
527*7c568831SAndroid Build Coastguard Worker			out.write("  ran             : %d\n" % counters[self.CNT_RAN])
528*7c568831SAndroid Build Coastguard Worker			out.write("    (schemata)    : %d\n" % counters[self.CNT_SCHEMA_TEST])
529*7c568831SAndroid Build Coastguard Worker		# out.write("    succeeded       : %d\n" % counters[self.CNT_SUCCEEDED])
530*7c568831SAndroid Build Coastguard Worker		out.write("  not accepted    : %d\n" % counters[self.CNT_NOTACCEPTED])
531*7c568831SAndroid Build Coastguard Worker		if counters[self.CNT_FAILED] > 0:
532*7c568831SAndroid Build Coastguard Worker			out.write("    failed                  : %d\n" % counters[self.CNT_FAILED])
533*7c568831SAndroid Build Coastguard Worker			out.write("     -> internal            : %d\n" % counters[self.CNT_INTERNAL])
534*7c568831SAndroid Build Coastguard Worker			out.write("     -> unimpl.             : %d\n" % counters[self.CNT_UNIMPLEMENTED])
535*7c568831SAndroid Build Coastguard Worker			out.write("     -> skip-invalid-schema : %d\n" % counters[self.CNT_NOSCHEMA])
536*7c568831SAndroid Build Coastguard Worker			out.write("     -> bad                 : %d\n" % counters[self.CNT_BAD])
537*7c568831SAndroid Build Coastguard Worker			out.write("     -> exceptions          : %d\n" % counters[self.CNT_EXCEPTED])
538*7c568831SAndroid Build Coastguard Worker			out.write("    memory leaks            : %d\n" % counters[self.CNT_MEMLEAK])
539*7c568831SAndroid Build Coastguard Worker
540*7c568831SAndroid Build Coastguard Worker	def displayShortResults(self, out, all, combName, counters):
541*7c568831SAndroid Build Coastguard Worker		out.write("Ran %d of %d tests (%d schemata):" % (counters[self.CNT_RAN],
542*7c568831SAndroid Build Coastguard Worker				  counters[self.CNT_TOTAL], counters[self.CNT_SCHEMA_TEST]))
543*7c568831SAndroid Build Coastguard Worker		# out.write("    succeeded       : %d\n" % counters[self.CNT_SUCCEEDED])
544*7c568831SAndroid Build Coastguard Worker		if counters[self.CNT_NOTACCEPTED] > 0:
545*7c568831SAndroid Build Coastguard Worker			out.write(" %d not accepted" % (counters[self.CNT_NOTACCEPTED]))
546*7c568831SAndroid Build Coastguard Worker		if counters[self.CNT_FAILED] > 0 or counters[self.CNT_MEMLEAK] > 0:
547*7c568831SAndroid Build Coastguard Worker			if counters[self.CNT_FAILED] > 0:
548*7c568831SAndroid Build Coastguard Worker				out.write(" %d failed" % (counters[self.CNT_FAILED]))
549*7c568831SAndroid Build Coastguard Worker				out.write(" (")
550*7c568831SAndroid Build Coastguard Worker				if counters[self.CNT_INTERNAL] > 0:
551*7c568831SAndroid Build Coastguard Worker					out.write(" %d internal" % (counters[self.CNT_INTERNAL]))
552*7c568831SAndroid Build Coastguard Worker				if counters[self.CNT_UNIMPLEMENTED] > 0:
553*7c568831SAndroid Build Coastguard Worker					out.write(" %d unimplemented" % (counters[self.CNT_UNIMPLEMENTED]))
554*7c568831SAndroid Build Coastguard Worker				if counters[self.CNT_NOSCHEMA] > 0:
555*7c568831SAndroid Build Coastguard Worker					out.write(" %d skip-invalid-schema" % (counters[self.CNT_NOSCHEMA]))
556*7c568831SAndroid Build Coastguard Worker				if counters[self.CNT_BAD] > 0:
557*7c568831SAndroid Build Coastguard Worker					out.write(" %d bad" % (counters[self.CNT_BAD]))
558*7c568831SAndroid Build Coastguard Worker				if counters[self.CNT_EXCEPTED] > 0:
559*7c568831SAndroid Build Coastguard Worker					out.write(" %d exception" % (counters[self.CNT_EXCEPTED]))
560*7c568831SAndroid Build Coastguard Worker				out.write(" )")
561*7c568831SAndroid Build Coastguard Worker			if counters[self.CNT_MEMLEAK] > 0:
562*7c568831SAndroid Build Coastguard Worker				out.write(" %d leaks" % (counters[self.CNT_MEMLEAK]))
563*7c568831SAndroid Build Coastguard Worker			out.write("\n")
564*7c568831SAndroid Build Coastguard Worker		else:
565*7c568831SAndroid Build Coastguard Worker			out.write(" all passed\n")
566*7c568831SAndroid Build Coastguard Worker
567*7c568831SAndroid Build Coastguard Worker	def reportCombine(self, combName):
568*7c568831SAndroid Build Coastguard Worker		global options
569*7c568831SAndroid Build Coastguard Worker
570*7c568831SAndroid Build Coastguard Worker		counters = self.createCounters()
571*7c568831SAndroid Build Coastguard Worker		#
572*7c568831SAndroid Build Coastguard Worker		# Compute evaluation counters.
573*7c568831SAndroid Build Coastguard Worker		#
574*7c568831SAndroid Build Coastguard Worker		for test in self.combinesRan[combName]:
575*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_TOTAL] += 1
576*7c568831SAndroid Build Coastguard Worker			counters[self.CNT_RAN] += 1
577*7c568831SAndroid Build Coastguard Worker			counters = self.updateCounters(test, counters)
578*7c568831SAndroid Build Coastguard Worker		if options.reportErrCombines and (counters[self.CNT_FAILED] == 0) and (counters[self.CNT_MEMLEAK] == 0):
579*7c568831SAndroid Build Coastguard Worker			pass
580*7c568831SAndroid Build Coastguard Worker		else:
581*7c568831SAndroid Build Coastguard Worker			if options.enableLog:
582*7c568831SAndroid Build Coastguard Worker				self.displayResults(self.logFile, False, combName, counters)
583*7c568831SAndroid Build Coastguard Worker			self.displayResults(sys.stdout, False, combName, counters)
584*7c568831SAndroid Build Coastguard Worker
585*7c568831SAndroid Build Coastguard Worker	def displayTestLog(self, test):
586*7c568831SAndroid Build Coastguard Worker		sys.stdout.writelines(test.log)
587*7c568831SAndroid Build Coastguard Worker		sys.stdout.write("~~~~~~~~~~\n")
588*7c568831SAndroid Build Coastguard Worker
589*7c568831SAndroid Build Coastguard Worker	def reportTest(self, test):
590*7c568831SAndroid Build Coastguard Worker		global options
591*7c568831SAndroid Build Coastguard Worker
592*7c568831SAndroid Build Coastguard Worker		error = test.failed or test.memLeak != 0
593*7c568831SAndroid Build Coastguard Worker		#
594*7c568831SAndroid Build Coastguard Worker		# Only erroneous tests will be written to the log,
595*7c568831SAndroid Build Coastguard Worker		# except @verbose is switched on.
596*7c568831SAndroid Build Coastguard Worker		#
597*7c568831SAndroid Build Coastguard Worker		if options.enableLog and (options.verbose or error):
598*7c568831SAndroid Build Coastguard Worker			self.logFile.writelines(test.log)
599*7c568831SAndroid Build Coastguard Worker			self.logFile.write("~~~~~~~~~~\n")
600*7c568831SAndroid Build Coastguard Worker		#
601*7c568831SAndroid Build Coastguard Worker		# if not @silent, only erroneous tests will be
602*7c568831SAndroid Build Coastguard Worker		# written to stdout, except @verbose is switched on.
603*7c568831SAndroid Build Coastguard Worker		#
604*7c568831SAndroid Build Coastguard Worker		if not options.silent:
605*7c568831SAndroid Build Coastguard Worker			if options.reportInternalErrOnly and test.internalErr:
606*7c568831SAndroid Build Coastguard Worker				self.displayTestLog(test)
607*7c568831SAndroid Build Coastguard Worker			if options.reportMemLeakErrOnly and test.memLeak != 0:
608*7c568831SAndroid Build Coastguard Worker				self.displayTestLog(test)
609*7c568831SAndroid Build Coastguard Worker			if options.reportUnimplErrOnly and test.unimplemented:
610*7c568831SAndroid Build Coastguard Worker				self.displayTestLog(test)
611*7c568831SAndroid Build Coastguard Worker			if (options.verbose or error) and (not options.reportInternalErrOnly) and (not options.reportMemLeakErrOnly) and (not options.reportUnimplErrOnly):
612*7c568831SAndroid Build Coastguard Worker				self.displayTestLog(test)
613*7c568831SAndroid Build Coastguard Worker
614*7c568831SAndroid Build Coastguard Worker
615*7c568831SAndroid Build Coastguard Worker	def addToCombines(self, test):
616*7c568831SAndroid Build Coastguard Worker		found = False
617*7c568831SAndroid Build Coastguard Worker		if test.combineName in self.combinesRan:
618*7c568831SAndroid Build Coastguard Worker			self.combinesRan[test.combineName].append(test)
619*7c568831SAndroid Build Coastguard Worker		else:
620*7c568831SAndroid Build Coastguard Worker			self.combinesRan[test.combineName] = [test]
621*7c568831SAndroid Build Coastguard Worker
622*7c568831SAndroid Build Coastguard Worker	def run(self):
623*7c568831SAndroid Build Coastguard Worker
624*7c568831SAndroid Build Coastguard Worker		global options
625*7c568831SAndroid Build Coastguard Worker
626*7c568831SAndroid Build Coastguard Worker		if options.info:
627*7c568831SAndroid Build Coastguard Worker			for test in self.testList:
628*7c568831SAndroid Build Coastguard Worker				self.addToCombines(test)
629*7c568831SAndroid Build Coastguard Worker			sys.stdout.write("Combines: %d\n" % len(self.combinesRan))
630*7c568831SAndroid Build Coastguard Worker			sys.stdout.write("%s\n" % self.combinesRan.keys())
631*7c568831SAndroid Build Coastguard Worker			return
632*7c568831SAndroid Build Coastguard Worker
633*7c568831SAndroid Build Coastguard Worker		if options.enableLog:
634*7c568831SAndroid Build Coastguard Worker			self.logFile = open(options.logFile, "w")
635*7c568831SAndroid Build Coastguard Worker		try:
636*7c568831SAndroid Build Coastguard Worker			for test in self.testList:
637*7c568831SAndroid Build Coastguard Worker				self.counters[self.CNT_TOTAL] += 1
638*7c568831SAndroid Build Coastguard Worker				#
639*7c568831SAndroid Build Coastguard Worker				# Filter tests.
640*7c568831SAndroid Build Coastguard Worker				#
641*7c568831SAndroid Build Coastguard Worker				if options.singleTest is not None and options.singleTest != "":
642*7c568831SAndroid Build Coastguard Worker					if (test.name != options.singleTest):
643*7c568831SAndroid Build Coastguard Worker						continue
644*7c568831SAndroid Build Coastguard Worker				elif options.combines is not None:
645*7c568831SAndroid Build Coastguard Worker					if not options.combines.__contains__(test.combineName):
646*7c568831SAndroid Build Coastguard Worker						continue
647*7c568831SAndroid Build Coastguard Worker				elif options.testStartsWith is not None:
648*7c568831SAndroid Build Coastguard Worker					if not test.name.startswith(options.testStartsWith):
649*7c568831SAndroid Build Coastguard Worker						continue
650*7c568831SAndroid Build Coastguard Worker				elif options.combineStartsWith is not None:
651*7c568831SAndroid Build Coastguard Worker					if not test.combineName.startswith(options.combineStartsWith):
652*7c568831SAndroid Build Coastguard Worker						continue
653*7c568831SAndroid Build Coastguard Worker
654*7c568831SAndroid Build Coastguard Worker				if options.maxTestCount != -1 and self.counters[self.CNT_RAN] >= options.maxTestCount:
655*7c568831SAndroid Build Coastguard Worker					break
656*7c568831SAndroid Build Coastguard Worker				self.counters[self.CNT_RAN] += 1
657*7c568831SAndroid Build Coastguard Worker				#
658*7c568831SAndroid Build Coastguard Worker				# Run the thing, dammit.
659*7c568831SAndroid Build Coastguard Worker				#
660*7c568831SAndroid Build Coastguard Worker				try:
661*7c568831SAndroid Build Coastguard Worker					test.setUp()
662*7c568831SAndroid Build Coastguard Worker					try:
663*7c568831SAndroid Build Coastguard Worker						test.run()
664*7c568831SAndroid Build Coastguard Worker					finally:
665*7c568831SAndroid Build Coastguard Worker						test.tearDown()
666*7c568831SAndroid Build Coastguard Worker				finally:
667*7c568831SAndroid Build Coastguard Worker					#
668*7c568831SAndroid Build Coastguard Worker					# Evaluate.
669*7c568831SAndroid Build Coastguard Worker					#
670*7c568831SAndroid Build Coastguard Worker					test.finalize()
671*7c568831SAndroid Build Coastguard Worker					self.reportTest(test)
672*7c568831SAndroid Build Coastguard Worker					if options.reportCombines or options.reportErrCombines:
673*7c568831SAndroid Build Coastguard Worker						self.addToCombines(test)
674*7c568831SAndroid Build Coastguard Worker					self.counters = self.updateCounters(test, self.counters)
675*7c568831SAndroid Build Coastguard Worker		finally:
676*7c568831SAndroid Build Coastguard Worker			if options.reportCombines or options.reportErrCombines:
677*7c568831SAndroid Build Coastguard Worker				#
678*7c568831SAndroid Build Coastguard Worker				# Build a report for every single combine.
679*7c568831SAndroid Build Coastguard Worker				#
680*7c568831SAndroid Build Coastguard Worker				# TODO: How to sort a dict?
681*7c568831SAndroid Build Coastguard Worker				#
682*7c568831SAndroid Build Coastguard Worker				self.combinesRan.keys().sort(None)
683*7c568831SAndroid Build Coastguard Worker				for key in self.combinesRan.keys():
684*7c568831SAndroid Build Coastguard Worker					self.reportCombine(key)
685*7c568831SAndroid Build Coastguard Worker
686*7c568831SAndroid Build Coastguard Worker			#
687*7c568831SAndroid Build Coastguard Worker			# Display the final report.
688*7c568831SAndroid Build Coastguard Worker			#
689*7c568831SAndroid Build Coastguard Worker			if options.silent:
690*7c568831SAndroid Build Coastguard Worker				self.displayShortResults(sys.stdout, True, None, self.counters)
691*7c568831SAndroid Build Coastguard Worker			else:
692*7c568831SAndroid Build Coastguard Worker				sys.stdout.write("===========================\n")
693*7c568831SAndroid Build Coastguard Worker				self.displayResults(sys.stdout, True, None, self.counters)
694