OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 3 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
4 # for details. All rights reserved. Use of this source code is governed by a | 4 # for details. All rights reserved. Use of this source code is governed by a |
5 # BSD-style license that can be found in the LICENSE file. | 5 # BSD-style license that can be found in the LICENSE file. |
6 # | 6 # |
7 | 7 |
8 """Test driver for the Dart project used by continuous build and developers.""" | 8 """Test driver for the Dart project used by continuous build and developers.""" |
9 | 9 |
10 | 10 |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 | 410 |
411 | 411 |
412 class TestCase(object): | 412 class TestCase(object): |
413 """A single test case, like running 'dart' on a single .dart file.""" | 413 """A single test case, like running 'dart' on a single .dart file.""" |
414 | 414 |
415 def __init__(self, context, path): | 415 def __init__(self, context, path): |
416 self.path = path | 416 self.path = path |
417 self.context = context | 417 self.context = context |
418 self.duration = None | 418 self.duration = None |
419 self.arch = [] | 419 self.arch = [] |
| 420 self.component = [] |
420 | 421 |
421 def IsBatchable(self): | 422 def IsBatchable(self): |
422 if self.context.use_batch: | 423 if self.context.use_batch: |
423 if self.arch and 'dartc' in self.arch: | 424 if self.component and 'dartc' in self.component: |
424 return True | 425 return True |
425 return False | 426 return False |
426 | 427 |
427 def IsNegative(self): | 428 def IsNegative(self): |
428 return False | 429 return False |
429 | 430 |
430 def CompareTime(self, other): | 431 def CompareTime(self, other): |
431 return cmp(other.duration, self.duration) | 432 return cmp(other.duration, self.duration) |
432 | 433 |
433 def DidFail(self, output): | 434 def DidFail(self, output): |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 try: | 524 try: |
524 (filename, pathname, description) = imp.find_module( | 525 (filename, pathname, description) = imp.find_module( |
525 'testcfg', [self.path]) | 526 'testcfg', [self.path]) |
526 module = imp.load_module('testcfg', filename, pathname, description) | 527 module = imp.load_module('testcfg', filename, pathname, description) |
527 self.config = module.GetConfiguration(context, self.path) | 528 self.config = module.GetConfiguration(context, self.path) |
528 finally: | 529 finally: |
529 if filename: | 530 if filename: |
530 filename.close() | 531 filename.close() |
531 return self.config | 532 return self.config |
532 | 533 |
533 def ListTests(self, current_path, path, context, mode, arch): | 534 def ListTests(self, current_path, path, context, mode, arch, component): |
534 return self.GetConfiguration(context).ListTests(current_path, | 535 return self.GetConfiguration(context).ListTests(current_path, |
535 path, | 536 path, |
536 mode, | 537 mode, |
537 arch) | 538 arch, |
| 539 component) |
538 | 540 |
539 def GetTestStatus(self, context, sections, defs): | 541 def GetTestStatus(self, context, sections, defs): |
540 self.GetConfiguration(context).GetTestStatus(sections, defs) | 542 self.GetConfiguration(context).GetTestStatus(sections, defs) |
541 | 543 |
542 | 544 |
543 class LiteralTestSuite(TestSuite): | 545 class LiteralTestSuite(TestSuite): |
544 """Represents one set of tests.""" | 546 """Represents one set of tests.""" |
545 | 547 |
546 def __init__(self, tests): | 548 def __init__(self, tests): |
547 super(LiteralTestSuite, self).__init__('root') | 549 super(LiteralTestSuite, self).__init__('root') |
548 self.tests = tests | 550 self.tests = tests |
549 | 551 |
550 def ListTests(self, current_path, path, context, mode, arch): | 552 def ListTests(self, current_path, path, context, mode, arch, component): |
551 name = path[0] | 553 name = path[0] |
552 result = [] | 554 result = [] |
553 for test in self.tests: | 555 for test in self.tests: |
554 test_name = test.GetName() | 556 test_name = test.GetName() |
555 if name.match(test_name): | 557 if name.match(test_name): |
556 full_path = current_path + [test_name] | 558 full_path = current_path + [test_name] |
557 result += test.ListTests(full_path, path, context, mode, arch) | 559 result += test.ListTests(full_path, path, context, mode, arch, component
) |
558 return result | 560 return result |
559 | 561 |
560 def GetTestStatus(self, context, sections, defs): | 562 def GetTestStatus(self, context, sections, defs): |
561 for test in self.tests: | 563 for test in self.tests: |
562 test.GetTestStatus(context, sections, defs) | 564 test.GetTestStatus(context, sections, defs) |
563 | 565 |
564 | 566 |
565 class Context(object): | 567 class Context(object): |
566 """A way to send global context for the test run to each test case.""" | 568 """A way to send global context for the test run to each test case.""" |
567 | 569 |
(...skipping 23 matching lines...) Expand all Loading... |
591 def GetExecutable(self, mode, arch, name): | 593 def GetExecutable(self, mode, arch, name): |
592 """Returns the name of the executable used to run the test.""" | 594 """Returns the name of the executable used to run the test.""" |
593 if self.executable is not None: | 595 if self.executable is not None: |
594 return self.executable | 596 return self.executable |
595 path = os.path.abspath(os.path.join(self.GetBuildRoot(mode, arch), name)) | 597 path = os.path.abspath(os.path.join(self.GetBuildRoot(mode, arch), name)) |
596 if utils.IsWindows() and not path.endswith('.exe'): | 598 if utils.IsWindows() and not path.endswith('.exe'): |
597 return path + '.exe' | 599 return path + '.exe' |
598 else: | 600 else: |
599 return path | 601 return path |
600 | 602 |
601 def GetDart(self, mode, arch): | 603 def GetDart(self, mode, arch, component): |
602 """Returns the path to the Dart test runner (executes the .dart file).""" | 604 """Returns the path to the Dart test runner (executes the .dart file).""" |
603 if arch == 'dartc': | 605 if component == 'dartc': |
604 command = [os.path.abspath( | 606 command = [os.path.abspath( |
605 os.path.join(self.GetBuildRoot(mode, arch), | 607 os.path.join(self.GetBuildRoot(mode, arch), |
606 'compiler', 'bin', 'dartc_test'))] | 608 'compiler', 'bin', 'dartc_test'))] |
607 else: | 609 else: |
608 command = [self.GetExecutable(mode, arch, 'dart_bin')] | 610 command = [self.GetExecutable(mode, arch, 'dart_bin')] |
609 | 611 |
610 return command | 612 return command |
611 | 613 |
612 def GetDartC(self, mode, arch): | 614 def GetDartC(self, mode, arch): |
613 """Returns the path to the Dart --> JS compiler.""" | 615 """Returns the path to the Dart --> JS compiler.""" |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 """A conditional expression. e.g. ($arch == ia32).""" | 738 """A conditional expression. e.g. ($arch == ia32).""" |
737 | 739 |
738 def __init__(self, left, op, right): | 740 def __init__(self, left, op, right): |
739 super(Operation, self).__init__() | 741 super(Operation, self).__init__() |
740 self.left = left | 742 self.left = left |
741 self.op = op | 743 self.op = op |
742 self.right = right | 744 self.right = right |
743 | 745 |
744 def Evaluate(self, env, defs): | 746 def Evaluate(self, env, defs): |
745 """Evaluates expression in the .status file. e.g. ($arch == ia32).""" | 747 """Evaluates expression in the .status file. e.g. ($arch == ia32).""" |
746 | |
747 if self.op == '||' or self.op == ',': | 748 if self.op == '||' or self.op == ',': |
748 return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs) | 749 return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs) |
749 elif self.op == 'if': | 750 elif self.op == 'if': |
750 return False | 751 return False |
751 elif self.op == '==': | 752 elif self.op == '==': |
752 outcomes = self.left.GetOutcomes(env, defs) | 753 outcomes = self.left.GetOutcomes(env, defs) |
753 inter = outcomes.Intersect(self.right.GetOutcomes(env, defs)) | 754 inter = outcomes.Intersect(self.right.GetOutcomes(env, defs)) |
754 return not inter.IsEmpty() | 755 return not inter.IsEmpty() |
755 else: | 756 else: |
756 assert self.op == '&&' | 757 assert self.op == '&&' |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 self.tokens.append(token) | 802 self.tokens.append(token) |
802 | 803 |
803 def SkipSpaces(self): | 804 def SkipSpaces(self): |
804 while self.HasMore() and self.Current().isspace(): | 805 while self.HasMore() and self.Current().isspace(): |
805 self.Advance() | 806 self.Advance() |
806 | 807 |
807 def Tokenize(self): | 808 def Tokenize(self): |
808 """Lexical analysis of an expression in a .status file. | 809 """Lexical analysis of an expression in a .status file. |
809 | 810 |
810 Example: | 811 Example: |
811 [ $mode == debug && ($arch == chromium || $arch == dartc) ] | 812 [ $mode == debug && ($component == chromium || $component == dartc) ] |
812 | 813 |
813 Args: | 814 Args: |
814 None. | 815 None. |
815 | 816 |
816 Returns: | 817 Returns: |
817 A list of tokens on success, None on failure. | 818 A list of tokens on success, None on failure. |
818 """ | 819 """ |
819 | 820 |
820 self.tokens = [] | 821 self.tokens = [] |
821 while self.HasMore(): | 822 while self.HasMore(): |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 | 977 |
977 def ClassifyTests(self, cases, env): | 978 def ClassifyTests(self, cases, env): |
978 """Matches a test case with the test prefixes requested on the cmdline. | 979 """Matches a test case with the test prefixes requested on the cmdline. |
979 | 980 |
980 This 'wraps' each TestCase object with some meta information | 981 This 'wraps' each TestCase object with some meta information |
981 about the test. | 982 about the test. |
982 | 983 |
983 Args: | 984 Args: |
984 cases: list of TestCase objects to classify. | 985 cases: list of TestCase objects to classify. |
985 env: dictionary containing values for 'mode', | 986 env: dictionary containing values for 'mode', |
986 'system', 'arch' and 'checked'. | 987 'system', 'component', 'arch' and 'checked'. |
987 | 988 |
988 Returns: | 989 Returns: |
989 A triplet of (result, rules, expected_outcomes). | 990 A triplet of (result, rules, expected_outcomes). |
990 """ | 991 """ |
991 sections = [s for s in self.sections | 992 sections = [s for s in self.sections |
992 if s.condition.Evaluate(env, self.defs)] | 993 if s.condition.Evaluate(env, self.defs)] |
993 all_rules = reduce(list.__add__, [s.rules for s in sections], []) | 994 all_rules = reduce(list.__add__, [s.rules for s in sections], []) |
994 unused_rules = set(all_rules) | 995 unused_rules = set(all_rules) |
995 result = [] | 996 result = [] |
996 all_outcomes = set([]) | 997 all_outcomes = set([]) |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 default=False, | 1147 default=False, |
1147 action='store_true') | 1148 action='store_true') |
1148 result.add_option( | 1149 result.add_option( |
1149 '--flag', | 1150 '--flag', |
1150 help='Pass this additional flag to the VM', | 1151 help='Pass this additional flag to the VM', |
1151 default=[], | 1152 default=[], |
1152 action='append') | 1153 action='append') |
1153 result.add_option( | 1154 result.add_option( |
1154 '--arch', | 1155 '--arch', |
1155 help='The architecture to run tests for', | 1156 help='The architecture to run tests for', |
1156 metavar='[all,ia32,x64,simarm,arm,dartc]', | 1157 metavar='[all,ia32,x64,simarm,arm]', |
1157 default=ARCH_GUESS) | 1158 default=ARCH_GUESS) |
1158 result.add_option( | 1159 result.add_option( |
1159 '--os', | 1160 '--os', |
1160 help='The OS to run tests on', | 1161 help='The OS to run tests on', |
1161 default=OS_GUESS) | 1162 default=OS_GUESS) |
1162 result.add_option( | 1163 result.add_option( |
1163 '--valgrind', | 1164 '--valgrind', |
1164 help='Run tests through valgrind', | 1165 help='Run tests through valgrind', |
1165 default=False, | 1166 default=False, |
1166 action='store_true') | 1167 action='store_true') |
(...skipping 12 matching lines...) Expand all Loading... |
1179 '--executable', | 1180 '--executable', |
1180 help='The executable with which to run the tests', | 1181 help='The executable with which to run the tests', |
1181 default=None) | 1182 default=None) |
1182 result.add_option( | 1183 result.add_option( |
1183 '--keep_temporary_files', | 1184 '--keep_temporary_files', |
1184 help='Do not delete temporary files after running the tests', | 1185 help='Do not delete temporary files after running the tests', |
1185 default=False, | 1186 default=False, |
1186 action='store_true') | 1187 action='store_true') |
1187 result.add_option( | 1188 result.add_option( |
1188 '--batch', | 1189 '--batch', |
1189 help='Run multiple tests for dartc architecture in a single vm', | 1190 help='Run multiple tests for dartc component in a single vm', |
1190 choices=['true', 'false'], | 1191 choices=['true', 'false'], |
1191 default='true', | 1192 default='true', |
1192 type='choice') | 1193 type='choice') |
1193 result.add_option( | 1194 result.add_option( |
1194 '--optimize', | 1195 '--optimize', |
1195 help='Invoke dart compiler with --optimize flag', | 1196 help='Invoke dart compiler with --optimize flag', |
1196 default=False, | 1197 default=False, |
1197 action='store_true') | 1198 action='store_true') |
| 1199 result.add_option( |
| 1200 '-c', '--component', |
| 1201 help='The component to test against ' |
| 1202 '(most, vm, dartc, chromium, dartium)', |
| 1203 metavar='[most,vm,dartc,chromium,dartium]', |
| 1204 default='vm') |
1198 return result | 1205 return result |
1199 | 1206 |
1200 | 1207 |
1201 def ProcessOptions(options): | 1208 def ProcessOptions(options): |
1202 """Process command line options.""" | 1209 """Process command line options.""" |
1203 if options.arch == 'all': | 1210 if options.arch == 'all': |
1204 options.arch = 'ia32,x64,simarm' | 1211 options.arch = 'ia32,x64,simarm' |
1205 if options.mode == 'all': | 1212 if options.mode == 'all': |
1206 options.mode = 'debug,release' | 1213 options.mode = 'debug,release' |
| 1214 if options.component == 'most': |
| 1215 options.component = 'vm,dartc' |
| 1216 |
| 1217 if 'dartc' in options.arch: |
| 1218 options.component = 'dartc' |
| 1219 if 'dartium' in options.arch: |
| 1220 options.component = 'dartium' |
| 1221 if 'chromium' in options.arch: |
| 1222 options.component = 'chromium' |
| 1223 |
1207 # By default we run with a higher timeout setting in when running on | 1224 # By default we run with a higher timeout setting in when running on |
1208 # a simulated architecture and in debug mode. | 1225 # a simulated architecture and in debug mode. |
1209 if not options.timeout: | 1226 if not options.timeout: |
1210 options.timeout = TIMEOUT_SECS | 1227 options.timeout = TIMEOUT_SECS |
1211 if 'dartc' in options.arch: | 1228 if 'dartc' in options.component: |
1212 options.timeout *= 4 | 1229 options.timeout *= 4 |
1213 elif 'chromium' in options.arch: | 1230 elif 'chromium' in options.component: |
1214 options.timeout *= 4 | 1231 options.timeout *= 4 |
1215 elif 'dartium' in options.arch: | 1232 elif 'dartium' in options.component: |
1216 options.timeout *= 4 | 1233 options.timeout *= 4 |
1217 elif 'debug' in options.mode: | 1234 elif 'debug' in options.mode: |
1218 options.timeout *= 2 | 1235 options.timeout *= 2 |
1219 options.mode = options.mode.split(',') | 1236 options.mode = options.mode.split(',') |
1220 options.arch = options.arch.split(',') | 1237 options.arch = options.arch.split(',') |
| 1238 options.component = options.component.split(',') |
1221 for mode in options.mode: | 1239 for mode in options.mode: |
1222 if not mode in ['debug', 'release']: | 1240 if not mode in ['debug', 'release']: |
1223 print 'Unknown mode %s' % mode | 1241 print 'Unknown mode %s' % mode |
1224 return False | 1242 return False |
1225 for arch in options.arch: | 1243 for arch in options.arch: |
1226 if not arch in ['ia32', 'x64', 'simarm', 'arm', 'dartc', 'dartium', | 1244 if not arch in ['ia32', 'x64', 'simarm', 'arm']: |
1227 'chromium']: | |
1228 print 'Unknown arch %s' % arch | 1245 print 'Unknown arch %s' % arch |
1229 return False | 1246 return False |
| 1247 for component in options.component: |
| 1248 if not component in ['vm', 'dartc', 'chromium', 'dartium']: |
| 1249 print 'Unknown component %s' % component |
| 1250 return False |
1230 options.flags = [] | 1251 options.flags = [] |
1231 options.flags.append('--ignore-unrecognized-flags') | 1252 options.flags.append('--ignore-unrecognized-flags') |
1232 if options.checked: | 1253 if options.checked: |
1233 options.flags.append('--enable_asserts') | 1254 options.flags.append('--enable_asserts') |
1234 options.flags.append('--enable_type_checks') | 1255 options.flags.append('--enable_type_checks') |
1235 if options.optimize: | 1256 if options.optimize: |
1236 options.flags.append('--optimize') | 1257 options.flags.append('--optimize') |
1237 for flag in options.flag: | 1258 for flag in options.flag: |
1238 options.flags.append(flag) | 1259 options.flags.append(flag) |
1239 if options.verbose: | 1260 if options.verbose: |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 root.GetTestStatus(context, sections, defs) | 1437 root.GetTestStatus(context, sections, defs) |
1417 config = Configuration(sections, defs) | 1438 config = Configuration(sections, defs) |
1418 | 1439 |
1419 # List the tests | 1440 # List the tests |
1420 all_cases = [] | 1441 all_cases = [] |
1421 all_unused = [] | 1442 all_unused = [] |
1422 globally_unused_rules = None | 1443 globally_unused_rules = None |
1423 for path in paths: | 1444 for path in paths: |
1424 for mode in options.mode: | 1445 for mode in options.mode: |
1425 for arch in options.arch: | 1446 for arch in options.arch: |
1426 env = { | 1447 for component in options.component: |
1427 'mode': mode, | 1448 env = { |
1428 'system': utils.GuessOS(), | 1449 'mode': mode, |
1429 'arch': arch, | 1450 'system': utils.GuessOS(), |
1430 'checked': options.checked | 1451 'arch': arch, |
1431 } | 1452 'component': component, |
1432 test_list = root.ListTests([], path, context, mode, arch) | 1453 'checked': options.checked |
1433 (cases, unused_rules, unused_outcomes) = config.ClassifyTests( | 1454 } |
1434 test_list, env) | 1455 test_list = root.ListTests([], path, context, mode, arch, component) |
1435 if globally_unused_rules is None: | 1456 (cases, unused_rules, unused_outcomes) = config.ClassifyTests( |
1436 globally_unused_rules = set(unused_rules) | 1457 test_list, env) |
1437 else: | 1458 if globally_unused_rules is None: |
1438 globally_unused_rules = ( | 1459 globally_unused_rules = set(unused_rules) |
1439 globally_unused_rules.intersection(unused_rules)) | 1460 else: |
1440 all_cases += cases | 1461 globally_unused_rules = ( |
1441 all_unused.append(unused_rules) | 1462 globally_unused_rules.intersection(unused_rules)) |
| 1463 all_cases += cases |
| 1464 all_unused.append(unused_rules) |
1442 | 1465 |
1443 if options.report: | 1466 if options.report: |
1444 PrintReport(all_cases) | 1467 PrintReport(all_cases) |
1445 | 1468 |
1446 if options.list: | 1469 if options.list: |
1447 PrintTests(all_cases) | 1470 PrintTests(all_cases) |
1448 return 0 | 1471 return 0 |
1449 | 1472 |
1450 result = None | 1473 result = None |
1451 | 1474 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 for entry in timed_tests[:20]: | 1506 for entry in timed_tests[:20]: |
1484 t = FormatTime(entry.duration) | 1507 t = FormatTime(entry.duration) |
1485 print '%4i (%s) %s' % (index, t, entry.GetLabel()) | 1508 print '%4i (%s) %s' % (index, t, entry.GetLabel()) |
1486 index += 1 | 1509 index += 1 |
1487 | 1510 |
1488 return result | 1511 return result |
1489 | 1512 |
1490 | 1513 |
1491 if __name__ == '__main__': | 1514 if __name__ == '__main__': |
1492 sys.exit(Main()) | 1515 sys.exit(Main()) |
OLD | NEW |