📄 test.py.svn-base
字号:
op = scan.Current() scan.Advance() right = ParseOperatorExpression(scan) if not right: return None left = Operation(left, op, right) return leftdef ParseConditionalExpression(scan): left = ParseOperatorExpression(scan) if not left: return None while scan.HasMore() and (scan.Current() == 'IF'): scan.Advance() right = ParseOperatorExpression(scan) if not right: return None left= Operation(left, 'if', right) return leftLOGICALS = ["&&", "||", ","]def ParseLogicalExpression(scan): left = ParseConditionalExpression(scan) if not left: return None while scan.HasMore() and (scan.Current() in LOGICALS): op = scan.Current() scan.Advance() right = ParseConditionalExpression(scan) if not right: return None left = Operation(left, op, right) return leftdef ParseCondition(expr): """Parses a logical expression into an Expression object""" tokens = Tokenizer(expr).Tokenize() if not tokens: print "Malformed expression: '%s'" % expr return None scan = Scanner(tokens) ast = ParseLogicalExpression(scan) if not ast: print "Malformed expression: '%s'" % expr return None return astclass ClassifiedTest(object): def __init__(self, case, outcomes): self.case = case self.outcomes = outcomesclass Configuration(object): """The parsed contents of a configuration file""" def __init__(self, sections, defs): self.sections = sections self.defs = defs def ClassifyTests(self, cases, env): sections = [s for s in self.sections if s.condition.Evaluate(env, self.defs)] all_rules = reduce(list.__add__, [s.rules for s in sections], []) unused_rules = set(all_rules) result = [ ] for case in cases: matches = [ r for r in all_rules if r.Contains(case.path) ] outcomes = set([]) for rule in matches: outcomes = outcomes.union(rule.GetOutcomes(env, self.defs)) unused_rules.discard(rule) if not outcomes: outcomes = [PASS] case.outcomes = outcomes result.append(ClassifiedTest(case, outcomes)) return (result, list(unused_rules))class Section(object): """A section of the configuration file. Sections are enabled or disabled prior to running the tests, based on their conditions""" def __init__(self, condition): self.condition = condition self.rules = [ ] def AddRule(self, rule): self.rules.append(rule)class Rule(object): """A single rule that specifies the expected outcome for a single test.""" def __init__(self, raw_path, path, value): self.raw_path = raw_path self.path = path self.value = value def GetOutcomes(self, env, defs): set = self.value.GetOutcomes(env, defs) assert isinstance(set, ListSet) return set.elms def Contains(self, path): if len(self.path) > len(path): return False for i in xrange(len(self.path)): if not self.path[i].match(path[i]): return False return TrueHEADER_PATTERN = re.compile(r'\[([^]]+)\]')RULE_PATTERN = re.compile(r'\s*([^: ]*)\s*:(.*)')DEF_PATTERN = re.compile(r'^def\s*(\w+)\s*=(.*)$')PREFIX_PATTERN = re.compile(r'^\s*prefix\s+([\w\_\.\-\/]+)$')def ReadConfigurationInto(path, sections, defs): current_section = Section(Constant(True)) sections.append(current_section) prefix = [] for line in utils.ReadLinesFrom(path): header_match = HEADER_PATTERN.match(line) if header_match: condition_str = header_match.group(1).strip() condition = ParseCondition(condition_str) new_section = Section(condition) sections.append(new_section) current_section = new_section continue rule_match = RULE_PATTERN.match(line) if rule_match: path = prefix + SplitPath(rule_match.group(1).strip()) value_str = rule_match.group(2).strip() value = ParseCondition(value_str) if not value: return False current_section.AddRule(Rule(rule_match.group(1), path, value)) continue def_match = DEF_PATTERN.match(line) if def_match: name = def_match.group(1).lower() value = ParseCondition(def_match.group(2).strip()) if not value: return False defs[name] = value continue prefix_match = PREFIX_PATTERN.match(line) if prefix_match: prefix = SplitPath(prefix_match.group(1).strip()) continue print "Malformed line: '%s'." % line return False return True# ---------------# --- M a i n ---# ---------------ARCH_GUESS = utils.GuessArchitecture()def BuildOptions(): result = optparse.OptionParser() result.add_option("-m", "--mode", help="The test modes in which to run (comma-separated)", default='release') result.add_option("-v", "--verbose", help="Verbose output", default=False, action="store_true") result.add_option("-S", dest="scons_flags", help="Flag to pass through to scons", default=[], action="append") result.add_option("-p", "--progress", help="The style of progress indicator (verbose, dots, color, mono)", choices=PROGRESS_INDICATORS.keys(), default="mono") result.add_option("--no-build", help="Don't build requirements", default=False, action="store_true") result.add_option("--report", help="Print a summary of the tests to be run", default=False, action="store_true") result.add_option("-s", "--suite", help="A test suite", default=[], action="append") result.add_option("-t", "--timeout", help="Timeout in seconds", default=60, type="int") result.add_option("--arch", help='The architecture to run tests for', default='none') result.add_option("--simulator", help="Run tests with architecture simulator", default='none') result.add_option("--special-command", default=None) result.add_option("--cat", help="Print the source of the tests", default=False, action="store_true") return resultdef ProcessOptions(options): global VERBOSE VERBOSE = options.verbose options.mode = options.mode.split(',') for mode in options.mode: if not mode in ['debug', 'release']: print "Unknown mode %s" % mode return False if options.simulator != 'none': # Simulator argument was set. Make sure arch and simulator agree. if options.simulator != options.arch: if options.arch == 'none': options.arch = options.simulator else: print "Architecture %s does not match sim %s" %(options.arch, options.simulator) return False # Ensure that the simulator argument is handed down to scons. options.scons_flags.append("simulator=" + options.simulator) else: # If options.arch is not set by the command line and no simulator setting # was found, set the arch to the guess. if options.arch == 'none': options.arch = ARCH_GUESS return TrueREPORT_TEMPLATE = """\Total: %(total)i tests * %(skipped)4d tests will be skipped * %(nocrash)4d tests are expected to be flaky but not crash * %(pass)4d tests are expected to pass * %(fail_ok)4d tests are expected to fail that we won't fix * %(fail)4d tests are expected to fail that we should fix\"""def PrintReport(cases): def IsFlaky(o): return (PASS in o) and (FAIL in o) and (not CRASH in o) and (not OKAY in o) def IsFailOk(o): return (len(o) == 2) and (FAIL in o) and (OKAY in o) unskipped = [c for c in cases if not SKIP in c.outcomes] print REPORT_TEMPLATE % { 'total': len(cases), 'skipped': len(cases) - len(unskipped), 'nocrash': len([t for t in unskipped if IsFlaky(t.outcomes)]), 'pass': len([t for t in unskipped if list(t.outcomes) == [PASS]]), 'fail_ok': len([t for t in unskipped if IsFailOk(t.outcomes)]), 'fail': len([t for t in unskipped if list(t.outcomes) == [FAIL]]) }class Pattern(object): def __init__(self, pattern): self.pattern = pattern self.compiled = None def match(self, str): if not self.compiled: pattern = "^" + self.pattern.replace('*', '.*') + "$" self.compiled = re.compile(pattern) return self.compiled.match(str) def __str__(self): return self.patterndef SplitPath(s): stripped = [ c.strip() for c in s.split('/') ] return [ Pattern(s) for s in stripped if len(s) > 0 ]def GetSpecialCommandProcessor(value): if (not value) or (value.find('@') == -1): def ExpandCommand(args): return args return ExpandCommand else: pos = value.find('@') prefix = value[:pos].split() suffix = value[pos+1:].split() def ExpandCommand(args): return prefix + args + suffix return ExpandCommandBUILT_IN_TESTS = ['mjsunit', 'cctest']def Main(): parser = BuildOptions() (options, args) = parser.parse_args() if not ProcessOptions(options): parser.print_help() return 1 workspace = abspath(join(dirname(sys.argv[0]), '..')) repositories = [TestRepository(join(workspace, 'test', name)) for name in BUILT_IN_TESTS] repositories += [TestRepository(a) for a in options.suite] root = LiteralTestSuite(repositories) if len(args) == 0: paths = [SplitPath(t) for t in BUILT_IN_TESTS] else: paths = [ ] for arg in args: path = SplitPath(arg) paths.append(path) # First build the required targets buildspace = abspath('.') context = Context(workspace, buildspace, VERBOSE, join(buildspace, 'shell'), options.timeout, GetSpecialCommandProcessor(options.special_command)) if not options.no_build: reqs = [ ] for path in paths: reqs += root.GetBuildRequirements(path, context) reqs = list(set(reqs)) if len(reqs) > 0: if not BuildRequirements(context, reqs, options.mode, options.scons_flags): return 1 # Get status for tests sections = [ ] defs = { } root.GetTestStatus(context, sections, defs) config = Configuration(sections, defs) # List the tests all_cases = [ ] all_unused = [ ] unclassified_tests = [ ] for path in paths: for mode in options.mode: env = { 'mode': mode, 'system': platform.system().lower(), 'arch': options.arch } test_list = root.ListTests([], path, context, mode) unclassified_tests += test_list (cases, unused_rules) = config.ClassifyTests(test_list, env) all_cases += cases all_unused.append(unused_rules) if options.cat: visited = set() for test in unclassified_tests: key = tuple(test.path) if key in visited: continue visited.add(key) print "--- begin source: %s ---" % test.GetLabel() source = test.GetSource().strip() print source print "--- end source: %s ---" % test.GetLabel() return 0# for rule in unused_rules:# print "Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path]) if options.report: PrintReport(all_cases) if len(all_cases) == 0: print "No tests to run." return 0 else: try: if RunTestCases(all_cases, options.progress): return 0 else: return 1 except KeyboardInterrupt: print "Interrupted" return 1if __name__ == '__main__': sys.exit(Main())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -