Skip to content

Commit

Permalink
feat: Add schema validation tests (#5654)
Browse files Browse the repository at this point in the history
* Add validation tests for JSON schema

* Update schema logic for space separated list type

* Fix failing Windows tests

* Actually fix failing tests

* Implement requested changes

* Self dot fail

---------

Co-authored-by: Leonardo Gama <[email protected]>
  • Loading branch information
Leo10Gama and Leonardo Gama authored Aug 2, 2023
1 parent 354e4ae commit 4beb300
Show file tree
Hide file tree
Showing 57 changed files with 818 additions and 5 deletions.
2 changes: 1 addition & 1 deletion samcli/commands/_utils/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ def _space_separated_list_func_type(value):
raise ValueError()


_space_separated_list_func_type.__name__ = "LIST"
_space_separated_list_func_type.__name__ = "list,string"


def generate_next_command_recommendation(command_tuples: List[Tuple[str, str]]) -> str:
Expand Down
20 changes: 16 additions & 4 deletions schema/samcli.json
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,10 @@
},
"notification_arns": {
"title": "notification_arns",
"type": "array",
"type": [
"array",
"string"
],
"description": "ARNs of SNS topics that AWS Cloudformation associates with the stack.",
"items": {
"type": "string"
Expand Down Expand Up @@ -1122,7 +1125,10 @@
},
"capabilities": {
"title": "capabilities",
"type": "array",
"type": [
"array",
"string"
],
"description": "List of capabilities that one must specify before AWS Cloudformation can create certain stacks.\n\nAccepted Values: CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_RESOURCE_POLICY, CAPABILITY_AUTO_EXPAND.\n\nLearn more at: https://docs.aws.amazon.com/serverlessrepo/latest/devguide/acknowledging-application-capabilities.html",
"items": {
"type": "string"
Expand Down Expand Up @@ -1560,7 +1566,10 @@
},
"notification_arns": {
"title": "notification_arns",
"type": "array",
"type": [
"array",
"string"
],
"description": "ARNs of SNS topics that AWS Cloudformation associates with the stack.",
"items": {
"type": "string"
Expand All @@ -1576,7 +1585,10 @@
},
"capabilities": {
"title": "capabilities",
"type": "array",
"type": [
"array",
"string"
],
"description": "List of capabilities that one must specify before AWS Cloudformation can create certain stacks.\n\nAccepted Values: CAPABILITY_IAM, CAPABILITY_NAMED_IAM, CAPABILITY_RESOURCE_POLICY, CAPABILITY_AUTO_EXPAND.\n\nLearn more at: https://docs.aws.amazon.com/serverlessrepo/latest/devguide/acknowledging-application-capabilities.html",
"default": [
"CAPABILITY_NAMED_IAM",
Expand Down
53 changes: 53 additions & 0 deletions tests/unit/schema/test_schema_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import os
from pathlib import Path
import jsonschema
from parameterized import parameterized
from unittest import TestCase

from samcli.lib.config.file_manager import FILE_MANAGER_MAPPER
from schema.make_schema import generate_schema


class TestSchemaValidation(TestCase):
schema = None
testdata_dir = None

@classmethod
def setUpClass(cls):
cls.schema = generate_schema()
testing_dir = Path(__name__).resolve().parents[0]
cls.testdata_dir = str(Path(testing_dir, "tests", "unit", "schema", "testdata"))

def test_samconfig_validates_against_schema(self):
self.assertIsNotNone(self.schema, "Schema was not set")

passing_tests_dir = Path(self.testdata_dir, "passing_tests")

# Read in and assert all files in passing_tests pass
for config_file_path in os.listdir(passing_tests_dir):
config_file = FILE_MANAGER_MAPPER[Path(config_file_path).suffix].read(
Path(str(passing_tests_dir), config_file_path)
)
self.assertNotEqual(config_file, {}, f"Config file {config_file_path} should be read correctly")

try:
jsonschema.validate(config_file, self.schema)
except jsonschema.ValidationError as e:
self.fail(f"File {config_file_path} not validating: {e.message}")

def test_samconfig_doesnt_validate_against_schema(self):
self.assertIsNotNone(self.schema, "Schema was not set")

failing_tests_dir = Path(self.testdata_dir, "failing_tests")

# Read in and assert all files in failing_tests fail
for config_file_path in os.listdir(failing_tests_dir):
config_file = FILE_MANAGER_MAPPER[Path(config_file_path).suffix].read(
Path(str(failing_tests_dir), config_file_path)
)
self.assertNotEqual(config_file, {}, f"Config file {config_file_path} should be read correctly")

with self.assertRaises(
jsonschema.ValidationError, msg=f"Config file {config_file_path} should not validate against schema"
):
jsonschema.validate(config_file, self.schema)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.build]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: 0.1
default:
build:
debug: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.build.parameters]
build_dir = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 0.1

default:
build:
parameters:
build_dir: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.build.parameters]
debug = "false"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 0.1

default:
build:
parameters:
debug: "False"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.build.parameters]
parameter_overrides = 10
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 0.1

default:
build:
parameters:
parameter_overrides: 10
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.delete]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.deploy]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.init]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.list_endpoints]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.list_resources]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.list_stack_outputs]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.local_invoke]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.local_invoke.parameters]
debug_port = "10"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 0.1

default:
local_invoke:
parameters:
debug_port: "10"
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.local_start_api]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.local_start_lambda]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.logs]
debug = false
26 changes: 26 additions & 0 deletions tests/unit/schema/testdata/failing_tests/noversion.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# version = 0.1

[default]
[default.global]
[default.global.parameters]
stack_name = "sam-app"

[default.build.parameters]
cached = true
parallel = true

[default.deploy.parameters]
capabilities = "CAPABILITY_IAM"
confirm_changeset = true
resolve_s3 = true

[default.sync.parameters]
watch = true

[default.local_start_api.parameters]
warm_containers = "EAGER"

[prod]
[prod.sync]
[prod.sync.parameters]
watch = false
4 changes: 4 additions & 0 deletions tests/unit/schema/testdata/failing_tests/noversion.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
default:
build:
parameters:
debug: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.package]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.package.parameters]
image_repositories = "Image repositories"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
version: 0.1

default:
package:
parameters:
image_repositories: Image repositories
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.pipeline_bootstrap]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.pipeline_init]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.publish]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.remote_invoke]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.sync]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.traces]
debug = false
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 0.1

[default.validate]
debug = false
36 changes: 36 additions & 0 deletions tests/unit/schema/testdata/passing_tests/buildcmd.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version = 0.1

[default.build.parameters]
hook_name = "Hook name"
skip_prepare_infra = false
use_container = false
container_env_var = "Container env var"
container_env_var_file = "Container env var file"
build_image = "Build image"
exclude = "Exclude"
parallel = false
mount_with = "READ"
build_dir = "Build dir"
cache_dir = "Cache dir"
base_dir = "Base dir"
manifest = "Manifest"
cached = false
template_file = "Template file"
parameter_overrides = "Parameter overrides"
skip_pull_image = false
docker_network = "Docker network"
beta_features = false
debug = false
profile = "Profile"
region = "Region"

[other.build.parameters]
skip_prepare_infra = true
use_container = true
parallel = true
mount_with = "WRITE"
cached = true
parameter_overrides = ["Parameter", "Overrides"]
skip_pull_image = true
beta_features = true
debug = true
16 changes: 16 additions & 0 deletions tests/unit/schema/testdata/passing_tests/deletecmd.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version = 0.1

[default.delete.parameters]
stack_name = "Stack name"
no_prompts = false
s3_bucket = "S3 Bucket"
s3_prefix = "S3 Prefix"
profile = "Profile"
region = "Region"
beta_features = false
debug = false

[other.delete.parameters]
no_prompts = true
beta_features = true
debug = true
Loading

0 comments on commit 4beb300

Please sign in to comment.