Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(470)

Side by Side Diff: tools/test.py

Issue 3164023: Refactor the tools/test.py script and related testcfg.py files.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/sputnik/testcfg.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # 2 #
3 # Copyright 2008 the V8 project authors. All rights reserved. 3 # Copyright 2008 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 def __init__(self, exit_code, timed_out, stdout, stderr): 324 def __init__(self, exit_code, timed_out, stdout, stderr):
325 self.exit_code = exit_code 325 self.exit_code = exit_code
326 self.timed_out = timed_out 326 self.timed_out = timed_out
327 self.stdout = stdout 327 self.stdout = stdout
328 self.stderr = stderr 328 self.stderr = stderr
329 self.failed = None 329 self.failed = None
330 330
331 331
332 class TestCase(object): 332 class TestCase(object):
333 333
334 def __init__(self, context, path): 334 def __init__(self, context, path, mode):
335 self.path = path 335 self.path = path
336 self.context = context 336 self.context = context
337 self.duration = None 337 self.duration = None
338 self.mode = mode
338 339
339 def IsNegative(self): 340 def IsNegative(self):
340 return False 341 return False
341 342
342 def CompareTime(self, other): 343 def CompareTime(self, other):
343 return cmp(other.duration, self.duration) 344 return cmp(other.duration, self.duration)
344 345
345 def DidFail(self, output): 346 def DidFail(self, output):
346 if output.failed is None: 347 if output.failed is None:
347 output.failed = self.IsFailureOutput(output) 348 output.failed = self.IsFailureOutput(output)
348 return output.failed 349 return output.failed
349 350
350 def IsFailureOutput(self, output): 351 def IsFailureOutput(self, output):
351 return output.exit_code != 0 352 return output.exit_code != 0
352 353
353 def GetSource(self): 354 def GetSource(self):
354 return "(no source available)" 355 return "(no source available)"
355 356
356 def RunCommand(self, command): 357 def RunCommand(self, command):
357 full_command = self.context.processor(command) 358 full_command = self.context.processor(command)
358 output = Execute(full_command, self.context, self.context.timeout) 359 output = Execute(full_command,
360 self.context,
361 self.context.GetTimeout(self.mode))
359 self.Cleanup() 362 self.Cleanup()
360 return TestOutput(self, full_command, output) 363 return TestOutput(self,
364 full_command,
365 output,
366 self.context.store_unexpected_output)
361 367
362 def BeforeRun(self): 368 def BeforeRun(self):
363 pass 369 pass
364 370
365 def AfterRun(self): 371 def AfterRun(self, result):
366 pass 372 pass
367 373
368 def Run(self): 374 def Run(self):
369 self.BeforeRun() 375 self.BeforeRun()
370 try: 376 try:
371 result = self.RunCommand(self.GetCommand()) 377 result = self.RunCommand(self.GetCommand())
372 finally: 378 finally:
373 self.AfterRun() 379 self.AfterRun(result)
374 return result 380 return result
375 381
376 def Cleanup(self): 382 def Cleanup(self):
377 return 383 return
378 384
379 385
380 class TestOutput(object): 386 class TestOutput(object):
381 387
382 def __init__(self, test, command, output): 388 def __init__(self, test, command, output, store_unexpected_output):
383 self.test = test 389 self.test = test
384 self.command = command 390 self.command = command
385 self.output = output 391 self.output = output
392 self.store_unexpected_output = store_unexpected_output
386 393
387 def UnexpectedOutput(self): 394 def UnexpectedOutput(self):
388 if self.HasCrashed(): 395 if self.HasCrashed():
389 outcome = CRASH 396 outcome = CRASH
390 elif self.HasTimedOut(): 397 elif self.HasTimedOut():
391 outcome = TIMEOUT 398 outcome = TIMEOUT
392 elif self.HasFailed(): 399 elif self.HasFailed():
393 outcome = FAIL 400 outcome = FAIL
394 else: 401 else:
395 outcome = PASS 402 outcome = PASS
396 return not outcome in self.test.outcomes 403 return not outcome in self.test.outcomes
397 404
405 def HasPreciousOutput(self):
406 return self.UnexpectedOutput() and self.store_unexpected_output
407
398 def HasCrashed(self): 408 def HasCrashed(self):
399 if utils.IsWindows(): 409 if utils.IsWindows():
400 return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.outpu t.exit_code) 410 return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.outpu t.exit_code)
401 else: 411 else:
402 # Timed out tests will have exit_code -signal.SIGTERM. 412 # Timed out tests will have exit_code -signal.SIGTERM.
403 if self.output.timed_out: 413 if self.output.timed_out:
404 return False 414 return False
405 return self.output.exit_code < 0 and \ 415 return self.output.exit_code < 0 and \
406 self.output.exit_code != -signal.SIGABRT 416 self.output.exit_code != -signal.SIGABRT
407 417
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 560
551 class TestSuite(object): 561 class TestSuite(object):
552 562
553 def __init__(self, name): 563 def __init__(self, name):
554 self.name = name 564 self.name = name
555 565
556 def GetName(self): 566 def GetName(self):
557 return self.name 567 return self.name
558 568
559 569
570 # Use this to run several variants of the tests, e.g.:
571 # VARIANT_FLAGS = [[], ['--always_compact', '--noflush_code']]
572 VARIANT_FLAGS = [[]]
573
574
560 class TestRepository(TestSuite): 575 class TestRepository(TestSuite):
561 576
562 def __init__(self, path): 577 def __init__(self, path):
563 normalized_path = abspath(path) 578 normalized_path = abspath(path)
564 super(TestRepository, self).__init__(basename(normalized_path)) 579 super(TestRepository, self).__init__(basename(normalized_path))
565 self.path = normalized_path 580 self.path = normalized_path
566 self.is_loaded = False 581 self.is_loaded = False
567 self.config = None 582 self.config = None
568 583
569 def GetConfiguration(self, context): 584 def GetConfiguration(self, context):
570 if self.is_loaded: 585 if self.is_loaded:
571 return self.config 586 return self.config
572 self.is_loaded = True 587 self.is_loaded = True
573 file = None 588 file = None
574 try: 589 try:
575 (file, pathname, description) = imp.find_module('testcfg', [ self.path ]) 590 (file, pathname, description) = imp.find_module('testcfg', [ self.path ])
576 module = imp.load_module('testcfg', file, pathname, description) 591 module = imp.load_module('testcfg', file, pathname, description)
577 self.config = module.GetConfiguration(context, self.path) 592 self.config = module.GetConfiguration(context, self.path)
578 finally: 593 finally:
579 if file: 594 if file:
580 file.close() 595 file.close()
581 return self.config 596 return self.config
582 597
583 def GetBuildRequirements(self, path, context): 598 def GetBuildRequirements(self, path, context):
584 return self.GetConfiguration(context).GetBuildRequirements() 599 return self.GetConfiguration(context).GetBuildRequirements()
585 600
586 def ListTests(self, current_path, path, context, mode): 601 def AddTestsToList(self, result, current_path, path, context, mode):
587 return self.GetConfiguration(context).ListTests(current_path, path, mode) 602 for v in VARIANT_FLAGS:
603 tests = self.GetConfiguration(context).ListTests(current_path, path, mode)
604 for t in tests: t.variant_flags = v
605 result += tests
606
588 607
589 def GetTestStatus(self, context, sections, defs): 608 def GetTestStatus(self, context, sections, defs):
590 self.GetConfiguration(context).GetTestStatus(sections, defs) 609 self.GetConfiguration(context).GetTestStatus(sections, defs)
591 610
592 611
593 class LiteralTestSuite(TestSuite): 612 class LiteralTestSuite(TestSuite):
594 613
595 def __init__(self, tests): 614 def __init__(self, tests):
596 super(LiteralTestSuite, self).__init__('root') 615 super(LiteralTestSuite, self).__init__('root')
597 self.tests = tests 616 self.tests = tests
598 617
599 def GetBuildRequirements(self, path, context): 618 def GetBuildRequirements(self, path, context):
600 (name, rest) = CarCdr(path) 619 (name, rest) = CarCdr(path)
601 result = [ ] 620 result = [ ]
602 for test in self.tests: 621 for test in self.tests:
603 if not name or name.match(test.GetName()): 622 if not name or name.match(test.GetName()):
604 result += test.GetBuildRequirements(rest, context) 623 result += test.GetBuildRequirements(rest, context)
605 return result 624 return result
606 625
607 def ListTests(self, current_path, path, context, mode): 626 def ListTests(self, current_path, path, context, mode):
608 (name, rest) = CarCdr(path) 627 (name, rest) = CarCdr(path)
609 result = [ ] 628 result = [ ]
610 for test in self.tests: 629 for test in self.tests:
611 test_name = test.GetName() 630 test_name = test.GetName()
612 if not name or name.match(test_name): 631 if not name or name.match(test_name):
613 full_path = current_path + [test_name] 632 full_path = current_path + [test_name]
614 result += test.ListTests(full_path, path, context, mode) 633 test.AddTestsToList(result, full_path, path, context, mode)
615 return result 634 return result
616 635
617 def GetTestStatus(self, context, sections, defs): 636 def GetTestStatus(self, context, sections, defs):
618 for test in self.tests: 637 for test in self.tests:
619 test.GetTestStatus(context, sections, defs) 638 test.GetTestStatus(context, sections, defs)
620 639
621 640
622 SUFFIX = {'debug': '_g', 'release': ''} 641 SUFFIX = {
642 'debug' : '_g',
643 'release' : '' }
644 FLAGS = {
645 'debug' : ['--enable-slow-asserts', '--debug-code', '--verify-heap'],
646 'release' : []}
647 TIMEOUT_SCALEFACTOR = {
648 'debug' : 4,
649 'release' : 1 }
623 650
624 651
625 class Context(object): 652 class Context(object):
626 653
627 def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, sup press_dialogs): 654 def __init__(self, workspace, buildspace, verbose, vm, timeout, processor, sup press_dialogs, store_unexpected_output):
628 self.workspace = workspace 655 self.workspace = workspace
629 self.buildspace = buildspace 656 self.buildspace = buildspace
630 self.verbose = verbose 657 self.verbose = verbose
631 self.vm_root = vm 658 self.vm_root = vm
632 self.timeout = timeout 659 self.timeout = timeout
633 self.processor = processor 660 self.processor = processor
634 self.suppress_dialogs = suppress_dialogs 661 self.suppress_dialogs = suppress_dialogs
662 self.store_unexpected_output = store_unexpected_output
635 663
636 def GetVm(self, mode): 664 def GetVm(self, mode):
637 name = self.vm_root + SUFFIX[mode] 665 name = self.vm_root + SUFFIX[mode]
638 if utils.IsWindows() and not name.endswith('.exe'): 666 if utils.IsWindows() and not name.endswith('.exe'):
639 name = name + '.exe' 667 name = name + '.exe'
640 return name 668 return name
641 669
670 def GetVmCommand(self, testcase, mode):
671 return [self.GetVm(mode)] + self.GetVmFlags(testcase, mode)
672
673 def GetVmFlags(self, testcase, mode):
674 return testcase.variant_flags + FLAGS[mode]
675
676 def GetTimeout(self, mode):
677 return self.timeout * TIMEOUT_SCALEFACTOR[mode]
678
642 def RunTestCases(cases_to_run, progress, tasks): 679 def RunTestCases(cases_to_run, progress, tasks):
643 progress = PROGRESS_INDICATORS[progress](cases_to_run) 680 progress = PROGRESS_INDICATORS[progress](cases_to_run)
644 return progress.Run(tasks) 681 return progress.Run(tasks)
645 682
646 683
647 def BuildRequirements(context, requirements, mode, scons_flags): 684 def BuildRequirements(context, requirements, mode, scons_flags):
648 command_line = (['scons', '-Y', context.workspace, 'mode=' + ",".join(mode)] 685 command_line = (['scons', '-Y', context.workspace, 'mode=' + ",".join(mode)]
649 + requirements 686 + requirements
650 + scons_flags) 687 + scons_flags)
651 output = ExecuteNoCapture(command_line, context) 688 output = ExecuteNoCapture(command_line, context)
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1114 result.add_option("--warn-unused", help="Report unused rules", 1151 result.add_option("--warn-unused", help="Report unused rules",
1115 default=False, action="store_true") 1152 default=False, action="store_true")
1116 result.add_option("-j", help="The number of parallel tasks to run", 1153 result.add_option("-j", help="The number of parallel tasks to run",
1117 default=1, type="int") 1154 default=1, type="int")
1118 result.add_option("--time", help="Print timing information after running", 1155 result.add_option("--time", help="Print timing information after running",
1119 default=False, action="store_true") 1156 default=False, action="store_true")
1120 result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for cra shing tests", 1157 result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for cra shing tests",
1121 dest="suppress_dialogs", default=True, action="store_true") 1158 dest="suppress_dialogs", default=True, action="store_true")
1122 result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for c rashing tests", 1159 result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for c rashing tests",
1123 dest="suppress_dialogs", action="store_false") 1160 dest="suppress_dialogs", action="store_false")
1124 result.add_option("--shell", help="Path to V8 shell", default="shell"); 1161 result.add_option("--shell", help="Path to V8 shell", default="shell")
1162 result.add_option("--store-unexpected-output",
1163 help="Store the temporary JS files from tests that fails",
1164 dest="store_unexpected_output", default=True, action="store_true")
1165 result.add_option("--no-store-unexpected-output",
1166 help="Deletes the temporary JS files from tests that fails",
1167 dest="store_unexpected_output", action="store_false")
1125 return result 1168 return result
1126 1169
1127 1170
1128 def ProcessOptions(options): 1171 def ProcessOptions(options):
1129 global VERBOSE 1172 global VERBOSE
1130 VERBOSE = options.verbose 1173 VERBOSE = options.verbose
1131 options.mode = options.mode.split(',') 1174 options.mode = options.mode.split(',')
1132 for mode in options.mode: 1175 for mode in options.mode:
1133 if not mode in ['debug', 'release']: 1176 if not mode in ['debug', 'release']:
1134 print "Unknown mode %s" % mode 1177 print "Unknown mode %s" % mode
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 paths.append(path) 1294 paths.append(path)
1252 1295
1253 # Check for --valgrind option. If enabled, we overwrite the special 1296 # Check for --valgrind option. If enabled, we overwrite the special
1254 # command flag with a command that uses the run-valgrind.py script. 1297 # command flag with a command that uses the run-valgrind.py script.
1255 if options.valgrind: 1298 if options.valgrind:
1256 run_valgrind = join(workspace, "tools", "run-valgrind.py") 1299 run_valgrind = join(workspace, "tools", "run-valgrind.py")
1257 options.special_command = "python -u " + run_valgrind + " @" 1300 options.special_command = "python -u " + run_valgrind + " @"
1258 1301
1259 shell = abspath(options.shell) 1302 shell = abspath(options.shell)
1260 buildspace = dirname(shell) 1303 buildspace = dirname(shell)
1304
1261 context = Context(workspace, buildspace, VERBOSE, 1305 context = Context(workspace, buildspace, VERBOSE,
1262 shell, 1306 shell,
1263 options.timeout, 1307 options.timeout,
1264 GetSpecialCommandProcessor(options.special_command), 1308 GetSpecialCommandProcessor(options.special_command),
1265 options.suppress_dialogs) 1309 options.suppress_dialogs,
1310 options.store_unexpected_output)
1266 # First build the required targets 1311 # First build the required targets
1267 if not options.no_build: 1312 if not options.no_build:
1268 reqs = [ ] 1313 reqs = [ ]
1269 for path in paths: 1314 for path in paths:
1270 reqs += root.GetBuildRequirements(path, context) 1315 reqs += root.GetBuildRequirements(path, context)
1271 reqs = list(set(reqs)) 1316 reqs = list(set(reqs))
1272 if len(reqs) > 0: 1317 if len(reqs) > 0:
1273 if options.j != 1: 1318 if options.j != 1:
1274 options.scons_flags += ['-j', str(options.j)] 1319 options.scons_flags += ['-j', str(options.j)]
1275 if not BuildRequirements(context, reqs, options.mode, options.scons_flags) : 1320 if not BuildRequirements(context, reqs, options.mode, options.scons_flags) :
1276 return 1 1321 return 1
1277 1322
1278 # Just return if we are only building the targets for running the tests. 1323 # Just return if we are only building the targets for running the tests.
1279 if options.build_only: 1324 if options.build_only:
1280 return 0 1325 return 0
1281 1326
1282 # Get status for tests 1327 # Get status for tests
1283 sections = [ ] 1328 sections = [ ]
1284 defs = { } 1329 defs = { }
1285 root.GetTestStatus(context, sections, defs) 1330 root.GetTestStatus(context, sections, defs)
1286 config = Configuration(sections, defs) 1331 config = Configuration(sections, defs)
1287 1332
1288 # List the tests 1333 # List the tests
1289 all_cases = [ ] 1334 all_cases = [ ]
1290 all_unused = [ ] 1335 all_unused = [ ]
1291 unclassified_tests = [ ] 1336 unclassified_tests = [ ]
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 for entry in timed_tests[:20]: 1406 for entry in timed_tests[:20]:
1362 t = FormatTime(entry.duration) 1407 t = FormatTime(entry.duration)
1363 sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel())) 1408 sys.stderr.write("%4i (%s) %s\n" % (index, t, entry.GetLabel()))
1364 index += 1 1409 index += 1
1365 1410
1366 return result 1411 return result
1367 1412
1368 1413
1369 if __name__ == '__main__': 1414 if __name__ == '__main__':
1370 sys.exit(Main()) 1415 sys.exit(Main())
OLDNEW
« no previous file with comments | « test/sputnik/testcfg.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698