def try_syntax(self, **kwargs): """Push the current tree to try, with the specified syntax. Build options, platforms and regression tests may be selected using the usual try options (-b, -p and -u respectively). In addition, tests in a given directory may be automatically selected by passing that directory as a positional argument to the command. For example: mach try -b d -p linux64 dom testing/web-platform/tests/dom would schedule a try run for linux64 debug consisting of all tests under dom/ and testing/web-platform/tests/dom. Test selection using positional arguments is available for mochitests, reftests, xpcshell tests and web-platform-tests. Tests may be also filtered by passing --tag to the command, which will run only tests marked as having the specified tags e.g. mach try -b d -p win64 --tag media would run all tests tagged 'media' on Windows 64. If both positional arguments or tags and -u are supplied, the suites in -u will be run in full. Where tests are selected by positional argument they will be run in a single chunk. If no build option is selected, both debug and opt will be scheduled. If no platform is selected a default is taken from the AUTOTRY_PLATFORM_HINT environment variable, if set. The command requires either its own mercurial extension ("push-to-try", installable from mach mercurial-setup) or a git repo using git-cinnabar (available at https://github.com/glandium/git-cinnabar). """ from mozbuild.testing import TestResolver from tryselect.selectors.syntax import AutoTry try: if self.substs.get("MOZ_ARTIFACT_BUILDS"): kwargs['local_artifact_build'] = True except BuildEnvironmentNotFoundException: # If we don't have a build locally, we can't tell whether # an artifact build is desired, but we still want the # command to succeed, if possible. pass config_status = os.path.join(self.topobjdir, 'config.status') if (kwargs['paths'] or kwargs['tags']) and not config_status: print(CONFIG_ENVIRONMENT_NOT_FOUND) sys.exit(1) def resolver_func(): return self._spawn(TestResolver) at = AutoTry(self.topsrcdir, resolver_func, self._mach_context) return at.run(**kwargs)
def try_syntax(self, **kwargs): """Push the current tree to try, with the specified syntax. Build options, platforms and regression tests may be selected using the usual try options (-b, -p and -u respectively). In addition, tests in a given directory may be automatically selected by passing that directory as a positional argument to the command. For example: mach try -b d -p linux64 dom testing/web-platform/tests/dom would schedule a try run for linux64 debug consisting of all tests under dom/ and testing/web-platform/tests/dom. Test selection using positional arguments is available for mochitests, reftests, xpcshell tests and web-platform-tests. Tests may be also filtered by passing --tag to the command, which will run only tests marked as having the specified tags e.g. mach try -b d -p win64 --tag media would run all tests tagged 'media' on Windows 64. If both positional arguments or tags and -u are supplied, the suites in -u will be run in full. Where tests are selected by positional argument they will be run in a single chunk. If no build option is selected, both debug and opt will be scheduled. If no platform is selected a default is taken from the AUTOTRY_PLATFORM_HINT environment variable, if set. The command requires either its own mercurial extension ("push-to-try", installable from mach mercurial-setup) or a git repo using git-cinnabar (available at https://github.com/glandium/git-cinnabar). """ from tryselect.selectors.syntax import AutoTry try: if self.substs.get("MOZ_ARTIFACT_BUILDS"): kwargs['local_artifact_build'] = True except BuildEnvironmentNotFoundException: # If we don't have a build locally, we can't tell whether # an artifact build is desired, but we still want the # command to succeed, if possible. pass config_status = os.path.join(self.topobjdir, 'config.status') if (kwargs['paths'] or kwargs['tags']) and not config_status: print(CONFIG_ENVIRONMENT_NOT_FOUND) sys.exit(1) at = AutoTry(self.topsrcdir, self._mach_context) return at.run(**kwargs)
def test(self, what, extra_args): """Run tests from names or paths. mach test accepts arguments specifying which tests to run. Each argument can be: * The path to a test file * A directory containing tests * A test suite name * An alias to a test suite name (codes used on TreeHerder) If no input is provided, tests will be run based on files changed in the local tree. Relevant tests, tags, or flavors are determined by IMPACTED_TESTS annotations in moz.build files relevant to the changed files. When paths or directories are given, they are first resolved to test files known to the build system. If resolved tests belong to more than one test type/flavor/harness, the harness for each relevant type/flavor will be invoked. e.g. if you specify a directory with xpcshell and browser chrome mochitests, both harnesses will be invoked. """ from mozbuild.testing import TestResolver # Parse arguments and assemble a test "plan." run_suites = set() run_tests = [] resolver = self._spawn(TestResolver) for entry in what: # If the path matches the name or alias of an entire suite, run # the entire suite. if entry in TEST_SUITES: run_suites.add(entry) continue suitefound = False for suite, v in TEST_SUITES.items(): if entry in v.get('aliases', []): run_suites.add(suite) suitefound = True if suitefound: continue # Now look for file/directory matches in the TestResolver. relpath = self._wrap_path_argument(entry).relpath() tests = list(resolver.resolve_tests(paths=[relpath])) run_tests.extend(tests) if not tests: print('UNKNOWN TEST: %s' % entry, file=sys.stderr) if not what: from tryselect.selectors.syntax import AutoTry at = AutoTry(self.topsrcdir, resolver, self._mach_context) res = at.find_paths_and_metadata(False, detect_paths=True) paths = res['paths'] tags = res['tags'] flavors = res['flavors'] if paths: print("Tests will be run based on modifications to the " "following files:\n\t%s" % "\n\t".join(paths)) # This requires multiple calls to resolve_tests, because the test # resolver returns tests that match every condition, while we want # tests that match any condition. Bug 1210213 tracks implementing # more flexible querying. if tags: run_tests = list(resolver.resolve_tests(tags=tags)) if paths: run_tests += [ t for t in resolver.resolve_tests(paths=paths) if not (tags & set(t.get('tags', '').split())) ] if flavors: run_tests = [ t for t in run_tests if t['flavor'] not in flavors ] for flavor in flavors: run_tests += list(resolver.resolve_tests(flavor=flavor)) if not run_suites and not run_tests: print(UNKNOWN_TEST) return 1 status = None for suite_name in run_suites: suite = TEST_SUITES[suite_name] if 'mach_command' in suite: res = self._mach_context.commands.dispatch( suite['mach_command'], self._mach_context, argv=extra_args, **suite['kwargs']) if res: status = res buckets = {} for test in run_tests: key = (test['flavor'], test.get('subsuite', '')) buckets.setdefault(key, []).append(test) for (flavor, subsuite), tests in sorted(buckets.items()): if flavor not in TEST_FLAVORS: print(UNKNOWN_FLAVOR % flavor) status = 1 continue m = TEST_FLAVORS[flavor] if 'mach_command' not in m: print(UNKNOWN_FLAVOR % flavor) status = 1 continue kwargs = dict(m['kwargs']) kwargs['subsuite'] = subsuite res = self._mach_context.commands.dispatch(m['mach_command'], self._mach_context, argv=extra_args, test_objects=tests, **kwargs) if res: status = res return status