Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: tools/lint/test/python.toml
# 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
from pathlib import Path
import mozunit
import pytest
LINTER = "test-manifest-toml"
fixed = 0
ERROR = "error"
WARNING = "warning"
def test_valid(lint, paths):
results = lint(paths("valid.toml"))
assert len(results) == 0
def test_invalid(lint, paths):
results = lint(paths("invalid.toml"))
assert len(results) == 1
assert results[0].message.startswith("The manifest is not valid TOML")
assert results[0].level == ERROR
def test_assignment_in_preamble(lint, paths):
# NOTE: The tomlkit parser will throw an error for this legal TOML
# so our linter never gets to find the preamble assignment
results = lint(paths("assignment-in-preamble.toml"))
assert len(results) == 1
assert (
results[0].message
== "The manifest is not valid TOML: 'bool' object has no attribute 'keys'"
)
assert results[0].level == ERROR
def test_no_default(lint, paths):
"""Test verifying [DEFAULT] section."""
results = lint(paths("no-default.toml"))
assert len(results) == 1
assert results[0].message == "The manifest does not start with a [DEFAULT] section."
assert results[0].level == WARNING
def test_no_default_fix(lint, paths, create_temp_file):
"""Test fixing missing [DEFAULT] section."""
contents = "# this Manifest has no DEFAULT section\n"
path = create_temp_file(contents, "no-default.toml")
results = lint([path], fix=True)
assert len(results) == 1
assert results[0].message == "The manifest does not start with a [DEFAULT] section."
assert results[0].level == WARNING
assert fixed == 1
expected = contents + "[DEFAULT]\n"
assert Path(path).read_text() == expected
def test_non_double_quote_sections_fix(lint, paths, create_temp_file):
"""Test and fix sections that do not have double quotes"""
basename = "non-double-quote-sections"
orig, fix = paths(f"{basename}.toml", f"{basename}-fix.toml")
original = Path(orig).read_text()
expected = Path(fix).read_text()
path = create_temp_file(original, f"{basename}.toml")
results = lint([path], fix=True)
assert len(results) == 2
assert results[0].message == "The section name must be double quoted: [aaa.js]"
assert results[0].level == WARNING
assert results[0].lineno == 3
assert results[1].message == "The section name must be double quoted: ['bbb.js']"
assert results[1].level == WARNING
assert results[1].lineno == 6
assert Path(path).read_text() == expected
def test_unsorted_fix(lint, paths, create_temp_file):
"""Test and fix sections in alpha order."""
basename = "unsorted"
orig, fix = paths(f"{basename}.toml", f"{basename}-fix.toml")
original = Path(orig).read_text()
expected = Path(fix).read_text()
path = create_temp_file(original, f"{basename}.toml")
results = lint([path], fix=True)
assert len(results) == 5
i: int = 0
assert results[i].message == "The manifest sections are not in alphabetical order."
assert results[i].level == WARNING
i += 1
assert (
results[i].message == "linux condition requires display == 'x11' or 'wayland'"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== 'instead of "!debug" use three conditions: "asan", "opt", "tsan"'
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message == "linux condition requires display == 'x11' or 'wayland'"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "non canonical condition: variable os (rank 1) should appear before variable ccov (rank 7) in condition: ccov && os == 'linux' && os_version == '22.04'"
)
assert results[i].level == ERROR
i += 1
assert Path(path).read_text() == expected
def test_comment_section(lint, paths):
"""Test for commented sections."""
results = lint(paths("comment-section.toml"))
assert len(results) == 2
assert results[0].message.startswith(
"Use 'disabled = \"<reason>\"' to disable a test instead of a comment:"
)
assert results[0].level == ERROR
def test_skip_if_not_array(lint, paths):
"""Test for non-array skip-if value."""
results = lint(paths("skip-if-not-array.toml"))
assert len(results) == 1
assert results[0].message.startswith("Value for conditional must be an array:")
assert results[0].level == ERROR
assert results[0].lineno == 3
def test_skip_if_explicit_or(lint, paths):
"""Test for explicit || in skip-if."""
results = lint(paths("skip-if-explicit-or.toml"))
assert len(results) == 1
assert results[0].message.startswith(
"Value for conditional must not include explicit ||, instead put on multiple lines:"
)
assert results[0].level == ERROR
assert results[0].lineno == 4
def test_missing_include(lint, paths):
"""Test for missing include"""
results = lint(paths("missing-include.toml"))
assert len(results) == 1
assert "non-existent.toml' does not exist" in results[0].message
assert results[0].level == ERROR
def test_non_idiomatic_fix(lint, paths, create_temp_file):
"""Test and fix non-idiomatic conditions."""
basename = "non-idiomatic"
orig, fix = paths(f"{basename}.toml", f"{basename}-fix.toml")
original = Path(orig).read_text()
expected = Path(fix).read_text()
path = create_temp_file(original, f"{basename}.toml")
results = lint([path], fix=True)
assert len(results) == 15
i: int = 0
assert (
results[i].message
== "non canonical condition: unknown var 'bits' in comparison: bits == 64"
)
assert results[i].level == ERROR
i += 1
assert results[i].message == "using 'bits' is not idiomatic, use 'arch' instead"
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "non canonical condition: unknown var 'processor' in comparison: processor == 'aarch64'"
)
assert results[i].level == ERROR
i += 1
assert results[i].message == "using 'bits' is not idiomatic, use 'arch' instead"
assert results[i].level == WARNING
i += 1
assert (
results[i].message == "using 'processor' is not idiomatic, use 'arch' instead"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "non canonical condition: unknown var 'android_version' in comparison: android_version == '36'"
)
assert results[i].level == ERROR
i += 1
assert (
results[i].message
== "using 'android_version' is not idiomatic, use 'os_version' instead (see testing/mozbase/mozinfo/mozinfo/platforminfo.py)"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "linux os_version == '24.04' is only supported on display == 'x11'"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "non canonical condition: unknown var 'processor' in comparison: processor == 'x86_64'"
)
assert results[i].level == ERROR
i += 1
assert (
results[i].message == "using 'processor' is not idiomatic, use 'arch' instead"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message == "linux condition requires display == 'x11' or 'wayland'"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== 'instead of "!debug" use three conditions: "asan", "opt", "tsan"'
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message == "linux condition requires display == 'x11' or 'wayland'"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "use boolean variables directly instead of testing for literal values"
)
assert results[i].level == WARNING
i += 1
assert (
results[i].message
== "use boolean variables directly instead of testing for literal values"
)
assert results[i].level == WARNING
i += 1
# wait to disable 18.04 until the Thunderbird migration is complete
# assert results[i].message == "linux os_version == '18.04' is no longer used"
# assert results[i].level == WARNING
# i += 1
assert Path(path).read_text() == expected
def test_android_os_mismatch(lint, paths, create_temp_file):
"""Test an android_version os_version mismatch"""
contents = (
"[DEFAULT]\nskip-if = [\"android_version == '36' && os_version == '15'\"]"
)
path = create_temp_file(contents, "android_mismatch.toml")
with pytest.raises(Exception) as e:
_results = lint([path], fix=True)
assert str(e.value) == "android_version == '36' conflicts with os_version == '15'"
def test_unknown_android_version(lint, paths, create_temp_file):
"""Test unknown android_version"""
contents = "[DEFAULT]\nskip-if = [\"android_version == '37'\"]"
path = create_temp_file(contents, "unknown_android.toml")
with pytest.raises(Exception) as e:
_results = lint([path], fix=True)
assert (
str(e.value)
== "Unknown Android API version '37'. Supported versions are dict_values(['24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36'])."
)
def test_invalid_combinations(lint, paths, create_temp_file):
"""Test invalid combinations of platforms and build-types"""
skip_if = "os == 'win' && os_version == '11.26100' && arch == 'x86' && tsan"
contents = f'[DEFAULT]\nskip-if = ["{skip_if}"]'
path = create_temp_file(contents, "combination.toml")
results = lint([path], fix=True)
assert len(results) == 1
assert results[0].message == "tsan build-type is not tested on Windows"
assert results[0].level == ERROR
skip_if = "os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland' && asan"
contents = f'[DEFAULT]\nskip-if = ["{skip_if}"]'
path = create_temp_file(contents, "combination.toml")
results = lint([path], fix=True)
assert len(results) == 1
assert results[0].message == "asan build-type is not tested on Linux 22.04"
assert results[0].level == ERROR
skip_if = "os == 'linux' && os_version == '22.04' && arch == 'x86_64' && display == 'wayland' && tsan"
contents = f'[DEFAULT]\nskip-if = ["{skip_if}"]'
path = create_temp_file(contents, "combination.toml")
results = lint([path], fix=True)
assert len(results) == 1
assert results[0].message == "tsan build-type is not tested on Linux 22.04"
assert results[0].level == ERROR
if __name__ == "__main__":
mozunit.main()