Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update error messagings from json schema #3798

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/cfnlint/jsonschema/_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@ def maxItems(
validator: Validator, mI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult: # pylint: disable=arguments-renamed
if validator.is_type(instance, "array") and len(instance) > mI:
yield ValidationError(f"{instance!r} is too long ({mI})")
yield ValidationError(
f"expected maximum item count: {mI}, found: {len(instance)}"
)


def maxLength(
Expand All @@ -333,7 +335,7 @@ def maxLength(
return

if len(instance) > mL:
yield ValidationError(f"{instance!r} is longer than {mL}")
yield ValidationError(f"expected maximum length: {mL}, found: {len(instance)}")


def maxProperties(
Expand All @@ -342,7 +344,9 @@ def maxProperties(
if not validator.is_type(instance, "object"):
return
if validator.is_type(instance, "object") and len(instance) > mP:
yield ValidationError(f"{instance!r} has too many properties")
yield ValidationError(
f"expected maximum property count: {mP}, found: {len(instance)}"
)


def maximum(
Expand All @@ -366,7 +370,9 @@ def minItems(
validator: Validator, mI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.is_type(instance, "array") and len(instance) < mI:
yield ValidationError(f"{instance!r} is too short ({mI})")
yield ValidationError(
f"expected minimum item count: {mI}, found: {len(instance)}"
)


def minLength(
Expand All @@ -376,14 +382,16 @@ def minLength(
return

if len(instance) < mL:
yield ValidationError(f"{instance!r} is shorter than {mL}")
yield ValidationError(f"expected minimum length: {mL}, found: {len(instance)}")


def minProperties(
validator: Validator, mP: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.is_type(instance, "object") and len(instance) < mP:
yield ValidationError(f"{instance!r} does not have enough properties")
yield ValidationError(
f"expected minimum property count: {mP}, found: {len(instance)}"
)


def minimum(
Expand Down Expand Up @@ -590,14 +598,14 @@ def uniqueItems(
validator: Validator, uI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if uI and validator.is_type(instance, "array") and not uniq(instance):
yield ValidationError(f"{instance!r} has non-unique elements")
yield ValidationError("array items are not unique")


def uniqueKeys(
validator: Validator, uKs: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if uKs and validator.is_type(instance, "array") and not uniq_keys(instance, uKs):
yield ValidationError(f"{instance!r} has non-unique elements for keys {uKs!r}")
yield ValidationError(f"array items are not unique for keys {uKs!r}")


def type(
Expand Down
2 changes: 1 addition & 1 deletion src/cfnlint/rules/functions/_BaseFn.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def resolve(
all_errs = []
for value, v, resolve_err in validator.resolve_value(instance):
if resolve_err:
yield resolve_err
yield from self.fix_errors(iter([resolve_err]))
continue
errs = list(
self.fix_errors(
Expand Down
18 changes: 3 additions & 15 deletions test/integration/jsonschema/test_validator_cfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand All @@ -220,11 +216,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand Down Expand Up @@ -289,11 +281,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand Down
21 changes: 8 additions & 13 deletions test/unit/module/jsonschema/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ def test_validator(name, schema, instance, expected, validator):
[],
[
ValidationError(
"[] is too short (2)",
"expected minimum item count: 2, found: 0",
)
],
),
Expand All @@ -552,11 +552,7 @@ def test_validator(name, schema, instance, expected, validator):
"maxItems",
{"maxItems": 0},
["foo"],
[
ValidationError(
"['foo'] is too long (0)",
)
],
[ValidationError("expected maximum item count: 0, found: 1")],
),
(
"valid minLength",
Expand All @@ -576,7 +572,7 @@ def test_validator(name, schema, instance, expected, validator):
"",
[
ValidationError(
"'' is shorter than 2",
"expected minimum length: 2, found: 0",
)
],
),
Expand All @@ -598,7 +594,7 @@ def test_validator(name, schema, instance, expected, validator):
"foo",
[
ValidationError(
"'foo' is longer than 0",
"expected maximum length: 0, found: 3",
)
],
),
Expand Down Expand Up @@ -768,7 +764,7 @@ def test_validator(name, schema, instance, expected, validator):
{},
[
ValidationError(
"{} does not have enough properties",
"expected minimum property count: 1, found: 0",
)
],
),
Expand All @@ -790,7 +786,7 @@ def test_validator(name, schema, instance, expected, validator):
{"foo": {}, "bar": {}},
[
ValidationError(
"{'foo': {}, 'bar': {}} has too many properties",
"expected maximum property count: 1, found: 2",
)
],
),
Expand Down Expand Up @@ -943,7 +939,7 @@ def test_validator(name, schema, instance, expected, validator):
[1, 2, "1"],
[
ValidationError(
"[1, 2, '1'] has non-unique elements",
"array items are not unique",
)
],
),
Expand Down Expand Up @@ -1035,8 +1031,7 @@ def test_validator(name, schema, instance, expected, validator):
],
[
ValidationError(
"[{'Name': 'foo'}, {'Name': 'foo'}] has non-unique "
"elements for keys ['Name']",
"array items are not unique " "for keys ['Name']",
)
],
),
Expand Down
7 changes: 2 additions & 5 deletions test/unit/rules/functions/test_dynamic_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def context(cfn):
},
[
ValidationError(
"['resolve', 'ssm'] is too short (3)",
"expected minimum item count: 3, found: 2",
validator="minItems",
rule=DynamicReference(),
)
Expand Down Expand Up @@ -182,10 +182,7 @@ def context(cfn):
},
[
ValidationError(
"['resolve', 'secretsmanager', 'arn', 'aws', "
"'secretsmanager', 'us-east-1', '012345678901', "
"'secret', 'my-secret', 'SecretString', "
"'', '', '', ''] is too long (13)",
"expected maximum item count: 13, found: 14",
validator="maxItems",
rule=DynamicReference(),
)
Expand Down
3 changes: 2 additions & 1 deletion test/unit/rules/functions/test_find_in_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def context(cfn):
None,
[
ValidationError(
"['foo', 'bar', 'key', 'key2'] is too long (3)",
"expected maximum item count: 3, found: 4",
path=deque(["Fn::FindInMap"]),
schema_path=deque(["maxItems"]),
validator="fn_findinmap",
Expand Down Expand Up @@ -164,6 +164,7 @@ def context(cfn):
"'C' is not one of ['B'] for mapping 'A'",
path=deque(["Fn::FindInMap", 1]),
schema_path=deque([]),
validator="fn_findinmap",
),
],
),
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/functions/test_if.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def validator(cfn, context):
{"type": "string"},
[
ValidationError(
"['IsUsEast1', 'foo', 'bar', 'key'] is too long (3)",
"expected maximum item count: 3, found: 4",
path=deque(["Fn::If"]),
schema_path=deque(["maxItems"]),
validator="fn_if",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/functions/test_sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def context(cfn):
{"type": "string"},
[
ValidationError(
"['${foo}', {'foo': 'bar'}, {}] is too long (2)",
"expected maximum item count: 2, found: 3",
path=deque(["Fn::Sub"]),
schema_path=deque(["maxItems"]),
validator="fn_sub",
Expand Down
4 changes: 2 additions & 2 deletions test/unit/rules/functions/test_tojsonstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def context(cfn):
{"transforms": Transforms(["AWS::LanguageExtensions"])},
[
ValidationError(
"{} does not have enough properties",
"expected minimum property count: 1, found: 0",
path=deque(["Fn::ToJsonString"]),
schema_path=deque(["minProperties"]),
validator="fn_tojsonstring",
Expand All @@ -93,7 +93,7 @@ def context(cfn):
{"transforms": Transforms(["AWS::LanguageExtensions"])},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
path=deque(["Fn::ToJsonString"]),
schema_path=deque(["minItems"]),
validator="fn_tojsonstring",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/mappings/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def rule():
{"a" * 256: {"Key": {"Value": "Foo"}}},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # empty because we didn't load child rules
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/outputs/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def context(cfn):
},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # none becuase we don't load child rule
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/parameters/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def context(cfn):
},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # none becuase we don't load child rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def template():
{"HealthCheckGracePeriodSeconds": "Foo", "LoadBalancers": []},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
rule=ServiceHealthCheckGracePeriodSeconds(),
path=deque(["LoadBalancers"]),
validator="minItems",
Expand Down Expand Up @@ -80,7 +80,7 @@ def template():
},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
rule=ServiceHealthCheckGracePeriodSeconds(),
path=deque(["LoadBalancers"]),
validator="minItems",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def rule():
{"Subnets": ["SubnetA"]},
[
ValidationError(
("['SubnetA'] is too short (2)"),
"expected minimum item count: 2, found: 1",
rule=LoadBalancerApplicationSubnets(),
path=deque(["Subnets"]),
validator="minItems",
Expand All @@ -55,7 +55,7 @@ def rule():
},
[
ValidationError(
("['SubnetA'] is too short (2)"),
"expected minimum item count: 2, found: 1",
rule=LoadBalancerApplicationSubnets(),
path=deque(["Subnets"]),
validator="minItems",
Expand Down
10 changes: 3 additions & 7 deletions test/unit/rules/resources/properties/test_tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ def rule():
{"taggable": True},
[
ValidationError(
(
"[{'Key': 'Foo', 'Value': 'Bar'}, "
"{'Key': 'Foo', 'Value': 'Bar'}] "
"has non-unique elements for keys ['Key']"
),
("array items are not unique for keys ['Key']"),
path=deque(["Tags"]),
schema_path=deque(["properties", "Tags", "uniqueKeys"]),
validator="tagging",
Expand All @@ -59,7 +55,7 @@ def rule():
{"taggable": True},
[
ValidationError(
f"{'a'*257!r} is longer than 256",
"expected maximum length: 256, found: 257",
path=deque(["Tags", 0, "Value"]),
schema_path=deque(
[
Expand All @@ -83,7 +79,7 @@ def rule():
{"taggable": True},
[
ValidationError(
f"{'a'*257!r} is longer than 256",
"expected maximum length: 256, found: 257",
path=deque(["Tags", "Foo"]),
schema_path=deque(
[
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/resources/route53/test_recordsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def rule():
),
),
ValidationError(
"['cname1.example.com', 'foo√bar'] is too long (1)",
"expected maximum item count: 1, found: 2",
rule=RecordSet(),
path=deque(["ResourceRecords"]),
validator="maxItems",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/templates/test_limitsize_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def rule():
None,
[
ValidationError(
("'FooBar' is longer than 3"),
("expected maximum length: 3, found: 6"),
)
],
),
Expand Down
Loading