# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
import re from itertools import combinations
import pytest from mozunit import main
from gecko_taskgraph.util import chunking
pytestmark = pytest.mark.slow
@pytest.fixture(scope="module") def mock_manifest_runtimes(): """Deterministically produce a list of simulated manifest runtimes.
Args:
manifests (list): list of manifests against which simulated manifest
runtimes would be paired up to.
Returns:
dict of manifest data paired with a float value representing runtime. """
def inner(manifests):
manifests = sorted(manifests) # Generate deterministic runtime data.
runtimes = [(i / 10) ** (i / 10) for i in range(len(manifests))] return dict(zip(manifests, runtimes))
return inner
@pytest.fixture(scope="module") def unchunked_manifests(): """Produce a list of unchunked manifests to be consumed by test method.
Args:
length (int, optional): number of path elements to keep.
cutoff (int, optional): number of generated test paths to remove from the test set if user wants to limit the number of paths.
Returns:
list: list of test paths. """
data = ["blueberry", "nashi", "peach", "watermelon"]
# Optionally set build attributes and runtime variants. if build_attrs: if isinstance(build_attrs, str):
build_attrs = [build_attrs] for attr in build_attrs:
setting["build"][attr] = True
if variants: if isinstance(variants, str):
variants = [variants] for variant in variants:
setting["runtime"][variant] = True return {"test-name": "foo", "test-setting": setting}
return inner
@pytest.fixture(scope="module") def mock_mozinfo(): """Returns a mocked mozinfo object, similar to guess_mozinfo_from_task().
Args:
os (str): typically one of 'win, linux, mac, android'.
processor (str): processor architecture.
asan (bool, optional): addressanitizer build.
bits (int, optional): defaults to 64.
ccov (bool, optional): code coverage build.
debug (bool, optional): debug type build.
fission (bool, optional): process fission.
headless (bool, optional): headless browser testing without displays.
tsan (bool, optional): threadsanitizer build.
Returns:
dict: Dictionary mimickign the results from guess_mozinfo_from_task. """
if exception: with pytest.raises(exception):
result = chunking.guess_mozinfo_from_task(task) else:
expected_toolkits = { "android": "android", "linux": "gtk", "mac": "cocoa", "win": "windows",
}
result = chunking.guess_mozinfo_from_task(task)
setting = task["test-setting"]
assert str(result["bits"]) in setting["platform"]["arch"] assert result["os"] in ("android", "linux", "mac", "win") assert result["os"] in setting["platform"]["os"]["name"] assert result["toolkit"] == expected_toolkits[result["os"]]
# Ensure the outcome of special build variants being present match what # guess_mozinfo_from_task method returns for these attributes. assert ("asan"in setting["build"]) == result["asan"] assert ("tsan"in setting["build"]) == result["tsan"] assert ("ccov"in setting["build"]) == result["ccov"]
@pytest.mark.parametrize("platform", ["unix", "windows", "android"])
@pytest.mark.parametrize( "suite", ["crashtest", "reftest", "web-platform-tests", "xpcshell"]
) def test_get_runtimes(platform, suite): """Tests that runtime information is returned for known good configurations.""" assert chunking.get_runtimes(platform, suite)
@pytest.mark.parametrize( "platform,suite,exception",
[
("nonexistent_platform", "nonexistent_suite", KeyError),
("unix", "nonexistent_suite", KeyError),
("unix", "", TypeError),
("", "", TypeError),
("", "nonexistent_suite", TypeError),
],
) def test_get_runtimes_invalid(platform, suite, exception): """Ensure get_runtimes() method raises an exception if improper request is made.""" with pytest.raises(exception):
chunking.get_runtimes(platform, suite)
# Generate the expected results, by generating list of indices that each # manifest should go into and then appending each item to that index. # This method is intentionally different from the way chunking.py performs # chunking for cross-checking.
expected = [[] for _ in range(chunks)]
indexed = zip(manifests, list(range(0, chunks)) * len(manifests)) for i in indexed:
expected[i[1]].append(i[0])
# Call the method under test on unchunked manifests.
chunked_manifests = chunking.chunk_manifests(suite, "unix", chunks, manifests)
# Assertions and end test. assert chunked_manifests if chunks > len(manifests): # If chunk count exceeds number of manifests, not all chunks will have # manifests. with pytest.raises(AssertionError): assert all(chunked_manifests) else: assert all(chunked_manifests)
minimum = min(len(c) for c in chunked_manifests)
maximum = max(len(c) for c in chunked_manifests) assert maximum - minimum <= 1 assert expected == chunked_manifests
# Call the method under test on unchunked manifests.
chunked_manifests = chunking.chunk_manifests(suite, "unix", chunks, manifests)
# Assertions and end test. assert chunked_manifests if chunks > len(manifests): # If chunk count exceeds number of manifests, not all chunks will have # manifests. with pytest.raises(AssertionError): assert all(chunked_manifests) else: assert all(chunked_manifests)
items = manifests["active"] if suite == "xpcshell": assert all([re.search(r"xpcshell(.*)?(.ini|.toml)", m) for m in items]) if"mochitest"in suite: assert all(
[
re.search(r"(perftest|mochitest|chrome|browser).*(.ini|.toml)", m) for m in items
]
) if"web-platform"in suite: assert all([m.startswith("/") and m.count("/") <= 4 for m in items])
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.