1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5from __future__ import absolute_import, print_function, unicode_literals 6 7import itertools 8import json 9import logging 10import math 11 12from mozbuild.util import memoize 13from mozpack.path import match as mozpackmatch 14from taskgraph import files_changed 15import taskgraph 16from .. import GECKO 17 18logger = logging.getLogger(__name__) 19 20 21@memoize 22def perfile_number_of_chunks(is_try, try_task_config, head_repository, head_rev, type): 23 if taskgraph.fast and not is_try: 24 # When iterating on taskgraph changes, the exact number of chunks that 25 # test-verify runs usually isn't important, so skip it when going fast. 26 return 3 27 tests_per_chunk = 10.0 28 if type.startswith("test-coverage"): 29 tests_per_chunk = 30.0 30 31 if type.startswith("test-verify-wpt") or type.startswith("test-coverage-wpt"): 32 file_patterns = [ 33 "testing/web-platform/tests/**", 34 "testing/web-platform/mozilla/tests/**", 35 ] 36 elif type.startswith("test-verify-gpu") or type.startswith("test-coverage-gpu"): 37 file_patterns = [ 38 "**/*webgl*/**/test_*", 39 "**/dom/canvas/**/test_*", 40 "**/gfx/tests/**/test_*", 41 "**/devtools/canvasdebugger/**/browser_*", 42 "**/reftest*/**", 43 ] 44 elif type.startswith("test-verify") or type.startswith("test-coverage"): 45 file_patterns = [ 46 "**/test_*", 47 "**/browser_*", 48 "**/crashtest*/**", 49 "js/src/tests/test/**", 50 "js/src/tests/non262/**", 51 "js/src/tests/test262/**", 52 ] 53 else: 54 # Returning 0 means no tests to run, this captures non test-verify tasks 55 return 1 56 57 changed_files = set() 58 if try_task_config: 59 suite_to_paths = json.loads(try_task_config) 60 specified_files = itertools.chain.from_iterable(suite_to_paths.values()) 61 changed_files.update(specified_files) 62 63 if is_try: 64 changed_files.update(files_changed.get_locally_changed_files(GECKO)) 65 else: 66 changed_files.update(files_changed.get_changed_files(head_repository, head_rev)) 67 68 test_count = 0 69 for pattern in file_patterns: 70 for path in changed_files: 71 # TODO: consider running tests if a manifest changes 72 if path.endswith(".list") or path.endswith(".ini"): 73 continue 74 if path.endswith("^headers^"): 75 continue 76 77 if mozpackmatch(path, pattern): 78 gpu = False 79 if type == "test-verify-e10s" or type == "test-coverage-e10s": 80 # file_patterns for test-verify will pick up some gpu tests, lets ignore 81 # in the case of reftest, we will not have any in the regular case 82 gpu_dirs = [ 83 "dom/canvas", 84 "gfx/tests", 85 "devtools/canvasdebugger", 86 "webgl", 87 ] 88 for gdir in gpu_dirs: 89 if len(path.split(gdir)) > 1: 90 gpu = True 91 92 if not gpu: 93 test_count += 1 94 95 chunks = test_count / tests_per_chunk 96 chunks = int(math.ceil(chunks)) 97 98 # Never return 0 chunks on try, so that per-file tests can be pushed to try with 99 # an explicit path, and also so "empty" runs can be checked on try. 100 if is_try and chunks == 0: 101 chunks = 1 102 103 return chunks 104