fune/taskcluster/taskgraph/test/test_util_schema.py
Andrew Halberstadt d024a31639 Bug 1726573 - Run 'pyupgrade --py36-plus' on taskcluster/taskgraph directory, r=taskgraph-reviewers,bhearsum
This patch was generated via:

  $ pyupgrade --py36-plus $(find taskcluster/taskgraph -name "*.py" -type f)
  $ autoflake --remove-all-unused-imports -i $(find taskcluster/taskgraph -name "*.py" -type f)

The same set of commands are being applied to standalone taskgraph as well so
they remain in sync.

Differential Revision: https://phabricator.services.mozilla.com/D123234
2021-08-24 19:35:46 +00:00

216 lines
6.1 KiB
Python

# 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 unittest
from mozunit import main
from taskgraph.util.schema import (
validate_schema,
resolve_keyed_by,
Schema,
)
schema = Schema(
{
"x": int,
"y": str,
}
)
class TestValidateSchema(unittest.TestCase):
def test_valid(self):
validate_schema(schema, {"x": 10, "y": "foo"}, "pfx")
def test_invalid(self):
try:
validate_schema(schema, {"x": "not-int"}, "pfx")
self.fail("no exception raised")
except Exception as e:
self.assertTrue(str(e).startswith("pfx\n"))
class TestCheckSchema(unittest.TestCase):
def test_schema(self):
"Creating a schema applies taskgraph checks."
with self.assertRaises(Exception):
Schema({"camelCase": int})
def test_extend_schema(self):
"Extending a schema applies taskgraph checks."
with self.assertRaises(Exception):
Schema({"kebab-case": int}).extend({"camelCase": int})
def test_extend_schema_twice(self):
"Extending a schema twice applies taskgraph checks."
with self.assertRaises(Exception):
Schema({"kebab-case": int}).extend({"more-kebab": int}).extend(
{"camelCase": int}
)
class TestResolveKeyedBy(unittest.TestCase):
def test_no_by(self):
self.assertEqual(resolve_keyed_by({"x": 10}, "z", "n"), {"x": 10})
def test_no_by_dotted(self):
self.assertEqual(
resolve_keyed_by({"x": {"y": 10}}, "x.z", "n"), {"x": {"y": 10}}
)
def test_no_by_not_dict(self):
self.assertEqual(resolve_keyed_by({"x": 10}, "x.y", "n"), {"x": 10})
def test_no_by_not_by(self):
self.assertEqual(resolve_keyed_by({"x": {"a": 10}}, "x", "n"), {"x": {"a": 10}})
def test_nested(self):
x = {
"by-foo": {
"F1": {
"by-bar": {
"B1": 11,
"B2": 12,
},
},
"F2": 20,
"default": 0,
},
}
self.assertEqual(
resolve_keyed_by({"x": x}, "x", "x", foo="F1", bar="B1"), {"x": 11}
)
self.assertEqual(
resolve_keyed_by({"x": x}, "x", "x", foo="F1", bar="B2"), {"x": 12}
)
self.assertEqual(resolve_keyed_by({"x": x}, "x", "x", foo="F2"), {"x": 20})
self.assertEqual(
resolve_keyed_by({"x": x}, "x", "x", foo="F99", bar="B1"), {"x": 0}
)
# bar is deferred
self.assertEqual(
resolve_keyed_by({"x": x}, "x", "x", defer=["bar"], foo="F1", bar="B1"),
{"x": {"by-bar": {"B1": 11, "B2": 12}}},
)
def test_no_by_empty_dict(self):
self.assertEqual(resolve_keyed_by({"x": {}}, "x", "n"), {"x": {}})
def test_no_by_not_only_by(self):
self.assertEqual(
resolve_keyed_by({"x": {"by-y": True, "a": 10}}, "x", "n"),
{"x": {"by-y": True, "a": 10}},
)
def test_match_nested_exact(self):
self.assertEqual(
resolve_keyed_by(
{
"f": "shoes",
"x": {"y": {"by-f": {"shoes": "feet", "gloves": "hands"}}},
},
"x.y",
"n",
),
{"f": "shoes", "x": {"y": "feet"}},
)
def test_match_regexp(self):
self.assertEqual(
resolve_keyed_by(
{
"f": "shoes",
"x": {"by-f": {"s?[hH]oes?": "feet", "gloves": "hands"}},
},
"x",
"n",
),
{"f": "shoes", "x": "feet"},
)
def test_match_partial_regexp(self):
self.assertEqual(
resolve_keyed_by(
{"f": "shoes", "x": {"by-f": {"sh": "feet", "default": "hands"}}},
"x",
"n",
),
{"f": "shoes", "x": "hands"},
)
def test_match_default(self):
self.assertEqual(
resolve_keyed_by(
{"f": "shoes", "x": {"by-f": {"hat": "head", "default": "anywhere"}}},
"x",
"n",
),
{"f": "shoes", "x": "anywhere"},
)
def test_match_extra_value(self):
self.assertEqual(
resolve_keyed_by({"f": {"by-foo": {"x": 10, "y": 20}}}, "f", "n", foo="y"),
{"f": 20},
)
def test_no_match(self):
self.assertRaises(
Exception,
resolve_keyed_by,
{"f": "shoes", "x": {"by-f": {"hat": "head"}}},
"x",
"n",
)
def test_multiple_matches(self):
self.assertRaises(
Exception,
resolve_keyed_by,
{"f": "hats", "x": {"by-f": {"hat.*": "head", "ha.*": "hair"}}},
"x",
"n",
)
self.assertEqual(
resolve_keyed_by(
{"f": "hats", "x": {"by-f": {"hat.*": "head", "ha.*": "hair"}}},
"x",
"n",
enforce_single_match=False,
),
{"f": "hats", "x": "head"},
)
def test_no_key_no_default(self):
"""
When the key referenced in `by-*` doesn't exist, and there is not default value,
an exception is raised.
"""
self.assertRaises(
Exception,
resolve_keyed_by,
{"x": {"by-f": {"hat.*": "head", "ha.*": "hair"}}},
"x",
"n",
)
def test_no_key(self):
"""
When the key referenced in `by-*` doesn't exist, and there is a default value,
that value is used as the result.
"""
self.assertEqual(
resolve_keyed_by(
{"x": {"by-f": {"hat": "head", "default": "anywhere"}}},
"x",
"n",
),
{"x": "anywhere"},
)
if __name__ == "__main__":
main()