diff --git a/CHANGELOG.md b/CHANGELOG.md index 417f39db..a459ab03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - New lint: error when there are metrics whose names are too similar ([bug 1934099](https://bugzilla.mozilla.org/show_bug.cgi?id=1934099)) +- Require `array` or `object` as the root type in object metrics ([#780](https://github.com/mozilla/glean_parser/pull/780)) ## 16.1.0 diff --git a/glean_parser/metrics.py b/glean_parser/metrics.py index bda287b7..e6509927 100644 --- a/glean_parser/metrics.py +++ b/glean_parser/metrics.py @@ -509,6 +509,20 @@ def validate_structure(structure): if None: raise ValueError("`structure` needed for object metric.") + # Different from `ALLOWED_TYPES`: + # We _require_ the root type to be an object or array. + allowed_types = ["object", "array"] + if "type" not in structure: + raise ValueError( + f"missing `type` in object structure. Allowed: {allowed_types}" + ) + if structure["type"] not in allowed_types: + raise ValueError( + "invalid `type` in object structure. found: {}, allowed: {}".format( + structure["type"], allowed_types + ) + ) + structure = Object._validate_substructure(structure) return structure diff --git a/tests/test_parser.py b/tests/test_parser.py index c073e8f7..28e5e9d7 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -1273,3 +1273,11 @@ def test_object_invalid(): errors = list(all_metrics) assert len(errors) == 1 assert "`items` not allowed in object structure" in errors[0] + + structure = {"type": "string"} + contents = [{"category": {"metric": {"type": "object", "structure": structure}}}] + contents = [util.add_required(x) for x in contents] + all_metrics = parser.parse_objects(contents) + errors = list(all_metrics) + assert len(errors) == 1 + assert "invalid `type` in object structure." in errors[0]