Skip to content

Commit

Permalink
Fix genconfig does not fail when schema validation failed (#425)
Browse files Browse the repository at this point in the history
* Fix bug that validation not fail when only schema error exists

* Remove postinstall step which installs az cli
  • Loading branch information
blackchoey authored Mar 27, 2020
1 parent a70852c commit abebb95
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 36 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog
All notable changes to this project since 0.82.0 will be documented in this file.

## [2.1.3] - 2020-03-27
### Changed
- Fix genconfig does not fail when schema validation failed. [[#424](https://github.com/Azure/iotedgedev/issues/424)]

## [2.1.2] - 2020-01-14
### Changed
- Fix error when install on Azure Pipelines agent
Expand Down
2 changes: 1 addition & 1 deletion iotedgedev/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

__author__ = 'Microsoft Corporation'
__email__ = '[email protected]'
__version__ = '2.1.2'
__version__ = '2.1.3'
__AIkey__ = '95b20d64-f54f-4de3-8ad5-165a75a6c6fe'
14 changes: 7 additions & 7 deletions iotedgedev/deploymentmanifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def validate_deployment_template(self):
validation_success = True
try:
template_schema = json.loads(urlopen(Constants.deployment_template_schema_url).read().decode())
self._validate_json_schema(template_schema, self.json, "Deployment template")
validation_success = self._validate_json_schema(template_schema, self.json, "Deployment template")
except Exception as ex: # Ignore other non shcema validation errors
self.output.info("Unexpected error during deployment template schema validation, skip schema validation. Error:%s" % ex)

Expand Down Expand Up @@ -182,14 +182,14 @@ def _validate_json_schema(self, schema_object, json_object, schema_type):
validator_class = jsonschema.validators.validator_for(schema_object)
validator = validator_class(schema_object)
validation_errors = validator.iter_errors(self.json)
error_detected = False
for error in validation_errors:
error_detected = True
validation_success = False
self.output.warning("%s schema error: %s. Property path:%s" % (schema_type, error.message, "->".join(error.path)))
if error_detected:
self.output.warning("%s schema validation failed. Please see previous logs for more details" % schema_type)
else:
if validation_success:
self.output.info("%s schema validation passed." % schema_type)
else:
self.output.warning("%s schema validation failed. Please see previous logs for more details" % schema_type)

except jsonschema.exceptions.SchemaError as schemaErr:
self.output.info("Errors found in %s schema, skip schema validation. Error:%s" % (schema_type, schemaErr.message))
except Exception as ex: # Ignore other non schema validation errors
Expand All @@ -201,7 +201,7 @@ def _validate_deployment_manifest_schema(self):
validation_success = True
try:
deployment_schema = json.loads(urlopen(Constants.deployment_manifest_schema_url).read())
self._validate_json_schema(deployment_schema, self.json, "Deployment manifest")
validation_success = self._validate_json_schema(deployment_schema, self.json, "Deployment manifest")
except Exception as ex: # Ignore other non schema validation errors
self.output.info("Unexpected error during deployment manifest schema validation, skip schema validation. Error:%s" % ex)

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 2.1.2
current_version = 2.1.3
commit = True
tag = True

Expand Down
21 changes: 2 additions & 19 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,6 @@
from setuptools.command.install import install


def _execute():
check_call('pip install azure-cli --no-deps'.split())


class PostInstall(install):
def run(self):
atexit.register(_execute)
install.run(self)


class PostDevelop(develop):
def run(self):
atexit.register(_execute)
develop.run(self)


with open('CHANGELOG.md') as history_file:
history = history_file.read()

Expand Down Expand Up @@ -60,7 +44,7 @@ def run(self):

setup(
name='iotedgedev',
version='2.1.2',
version='2.1.3',
description='The Azure IoT Edge Dev Tool greatly simplifies the IoT Edge development process by automating many routine manual tasks, such as building, deploying, pushing modules and configuring the IoT Edge Runtime.',
long_description='See https://github.com/azure/iotedgedev for usage instructions.',
author='Microsoft Corporation',
Expand Down Expand Up @@ -91,6 +75,5 @@ def run(self):
],
test_suite='tests',
tests_require=test_requirements,
setup_requires=setup_requirements,
cmdclass={'install': PostInstall, 'develop': PostDevelop}
setup_requires=setup_requirements
)
102 changes: 102 additions & 0 deletions tests/assets/deployment.manifest_invalid_createoptions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"schemaVersion": "1.0",
"runtime": {
"type": "docker",
"settings": {
"minDockerVersion": "v1.25",
"loggingOptions": "",
"registryCredentials": {
"test": {
"username": "$USERNAME",
"password": "$PASSWORD",
"address": "docker.io"
}
}
}
},
"systemModules": {
"edgeAgent": {
"type": "docker",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-agent:1.0"
}
},
"edgeHub": {
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
}
}
},
"modules": {
"tempSensor": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0",
"createOptions": "{\"Env\":[\"abcdefghij0=00\",\"abcdefghij1=01\",\"abcdefghij2=02\",\"abcdefghij3=03\",\"abcdefghij4=04\",\"abcdefghij5=05\",\"abcdefghij6=06\",\"abcdefghij7=07\",\"abcdefghij8=08\",\"abcdefghij9=09\",\"abcdefghij10=10\",\"abcdefghij11=11\",\"abcdefghij12=12\",\"abcdefghij13=13\",\"abcdefghij14=14\",\"abcdefghij15=15\",\"abcdefghij16=16\",\"abcdefghij17=17\",\"abcdefghij18=18\",\"abcdefghij19=19\",\"abcdefghij20=20\",\"abcdefghij22=21\",\"abcdefghij22=22\",\"abcdefghij23=23\",\"abcdefghij24=24\",\"abcdefghij25=25\",\"abcdefghij26=26\",\"abcdefghij27=27\",\"abcdefghi",
"createOptions01": "j28=28\",\"abcdefghij29=29\",\"abcdefghij30=30\",\"abcdefghij31=31\",\"abcdefghij32=32\",\"abcdefghij33=33\",\"abcdefghij34=34\",\"abcdefghij35=35\",\"abcdefghij36=36\",\"abcdefghij37=37\",\"abcdefghij38=38\",\"abcdefghij39=39\",\"abcdefghij40=40\",\"abcdefghij41=41\",\"abcdefghij42=42\",\"abcdefghij43=43\",\"abcdefghij44=44\",\"abcdefghij45=45\",\"abcdefghij46=46\",\"abcdefghij47=47\",\"abcdefghij48=48\",\"abcdefghij49=49\",\"abcdefghij50=50\",\"abcdefghij51=51\",\"abcdefghij52=52\",\"abcdefghij53=53\",\"abcdefghij54=54\",\"abcdefghij55=55\",\"abcdefghij56abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh=56\",",
"createOptions02": "\"abcdefghij56abcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefghabcdefgh=57\",\"abcdefghij58=58\",\"abcdefghij59=59\"]}"
}
},
"csharpmodule": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "${MODULES.csharpmodule.amd64}",
"createOptions": "{\"Env\":[\"abcdefghij0=00\",\"abcdefghij1=01\",\"abcdefghij2=02\",\"abcdefghij3=03\",\"abcdefghij4=04\",\"abcdefghij5=05\",\"abcdefghij6=06\",\"abcdefghij7=07\",\"abcdefghij8=08\",\"abcdefghij9=09\",\"abcdefghij10=10\",\"abcdefghij11=11\",\"abcdefghij12=12\",\"abcdefghij13=13\",\"abcdefghij14=14\",\"abcdefghij15=15\",\"abcdefghij16=16\",\"abcdefghij17=17\",\"abcdefghij18=18\",\"abcdefghij19=19\",\"abcdefghij20=20\",\"abcdefghij22=21\",\"abcdefghij22=22\",\"abcdefghij23=23\",\"abcdefghij24=24\",\"abcdefghij25=25\",\"abcdefghij26=26\",\"abcdefghij27=27\",\"abcdefghi",
"createOptions01": "j28=28\",\"abcdefghij29=29\",\"abcdefghij30=30\",\"abcdefghij31=31\",\"abcdefghij32=32\",\"abcdefghij33=33\",\"abcdefghij34=34\",\"abcdefghij35=35\",\"abcdefghij36=36\",\"abcdefghij37=37\",\"abcdefghij38=38\",\"abcdefghij39=39\",\"abcdefghij40=40\",\"abcdefghij41=41\",\"abcdefghij42=42\",\"abcdefghij43=43\",\"abcdefghij44=44\",\"abcdefghij45=45\",\"abcdefghij46=46\",\"abcdefghij47=47\",\"abcdefghij48=48\",\"abcdefghij49=49\",\"abcdefghij50=50\",\"abcdefghij51=51\",\"abcdefghij52=52\",\"abcdefghij53=53\",\"abcdefghij54=54\",\"abcdefghij55=55\",\"abcdefghij56=56\",",
"createOptions03": "\"abcdefghij57=57\",\"abcdefghij58=58\",\"abcdefghij59=59\"]}"
}
},
"csharpfunction": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "${MODULES.csharpfunction.amd64.debug}",
"createOptions": "[1,2,3]"
}
},
"csharpfunction2": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "${MODULES.csharpfunction2.amd64.debug}",
"createOptions": "{\"Env\":[\"abcdefghij0=00\",\"abcdefghij1=01\",\"abcdefghij2=02\",\"abcdefghij3=03\",\"abcdefghij4=04\",\"abcdefghij5=05\",\"abcdefghij6=06\",\"abcdefghij7=07\",\"abcdefghij8=08\",\"abcdefghij9=09\",\"abcdefghij10=10\",\"abcdefghij11=11\",\"abcdefghij12=12\",\"abcdefghij13=13\",\"abcdefghij14=14\",\"abcdefghij15=15\",\"abcdefghij16=16\",\"abcdefghij17=17\",\"abcdefghij18=18\",\"abcdefghij19=19\",\"abcdefghij20=20\",\"abcdefghij22=21\",\"abcdefghij22=22\",\"abcdefghij23=23\",\"abcdefghij24=24\",\"abcdefghij25=25\",\"abcdefghij26=26\",\"abcdefghij27=27\",\"abcdefghi",
"createOptions01": "j28=28\",\"abcdefghij29=29\",\"abcdefghij30=30\",\"abcdefghij31=31\",\"abcdefghij32=32\",\"abcdefghij33=33\",\"abcdefghij34=34\",\"abcdefghij35=35\",\"abcdefghij36=36\",\"abcdefghij37=37\",\"abcdefghij38=38\",\"abcdefghij39=39\",\"abcdefghij40=40\",\"abcdefghij41=41\",\"abcdefghij42=42\",\"abcdefghij43=43\",\"abcdefghij44=44\",\"abcdefghij45=45\",\"abcdefghij46=46\",\"abcdefghij47=47\",\"abcdefghij48=48\",\"abcdefghij49=49\",\"abcdefghij50=50\",\"abcdefghij51=51\",\"abcdefghij52=52\",\"abcdefghij53=53\",\"abcdefghij54=54\",\"abcdefghij55=55\",\"abcdefghij56=56\",",
"createOptions03": "\"abcdefghij57=57\",\"abcdefghij58=58\",\"abcdefghij59=59\"]}",
"createOptions04": {"test": "value"}
}
}
}
}
},
"$edgeHub": {
"properties.desired": {
"schemaVersion": "1.0",
"routes": {
"sensorTocsharpmodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/csharpmodule/inputs/input1\")",
"csharpmoduleToIoTHub": "FROM /messages/modules/csharpmodule/outputs/* INTO $upstream",
"csharpfunctionToIoTHub": "FROM /messages/modules/csharpfunction/outputs/* INTO $upstream"
},
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
}
}
}
}
69 changes: 69 additions & 0 deletions tests/assets/deployment.manifest_invalid_schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"modulesContent": {
"$edgeAgent": {
"properties.desired": {
"schemaVersion": "1.0",
"runtime": {
"type": "docker",
"settings": {
"minDockerVersion": "v1.25",
"loggingOptions": "",
"registryCredentials": {
"test": {
"username": 1,
"password": "pwd"
},
"test2": {
"username": "$USERNAME",
"password": "$PASSWORD",
"address": ""
}
}
}
},
"systemModules": {
"edgeAgent": {
"type": "docker",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-agent:1.0"
}
},
"edgeHub": {
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
}
}
},
"modules": {
"tempSensor": {
"version": "1.0",
"type": "docker",
"status": "running",
"restartPolicy": "always",
"settings": {
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0",
"createOptions": "{}"
}
}
}
}
},
"$edgeHub": {
"properties.desired": {
"schemaVersion": "1.0",
"routes": {
"sensorTocsharpmodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/csharpmodule/inputs/input1\")",
"csharpmoduleToIoTHub": "FROM /messages/modules/csharpmodule/outputs/* INTO $upstream",
"csharpfunctionToIoTHub": "FROM /messages/modules/csharpfunction/outputs/* INTO $upstream"
},
"storeAndForwardConfiguration": {
"timeToLiveSecs": 7200
}
}
}
}
}
19 changes: 11 additions & 8 deletions tests/test_iotedgedev.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,14 +549,17 @@ def test_validate_create_options_failed():

def test_fail_gen_config_on_validation_error():
os.chdir(tests_assets_dir)
deployment_file_name = "deployment.template_invalidresult.json"
try:
if get_docker_os_type() == "windows":
result = runner_invoke(['genconfig', '-P', get_platform_type(), '-f', deployment_file_name, '--fail-on-validation-error'])
else:
result = runner_invoke(['genconfig', '-f', deployment_file_name, '--fail-on-validation-error'])
except Exception as err:
assert "ERROR: Deployment manifest validation failed. Please see previous logs for more details." in "%s" % err
test_files = ["deployment.manifest_invalid.json", "deployment.manifest_invalid_schema.json", "deployment.manifest_invalid_createoptions.json"]
for deployment_file_name in test_files:
try:
if get_docker_os_type() == "windows":
result = runner_invoke(['genconfig', '-P', get_platform_type(), '-f', deployment_file_name, '--fail-on-validation-error'])
else:
result = runner_invoke(['genconfig', '-f', deployment_file_name, '--fail-on-validation-error'])
raise Exception("genconfig command should fail in %s" % deployment_file_name)
except Exception as err:
assert "ERROR: Deployment manifest validation failed. Please see previous logs for more details." in "%s" % err
assert "genconfig command should fail" not in "%s" % err

if get_docker_os_type() == "windows":
result = runner_invoke(['genconfig', '-P', get_platform_type(), '-f', deployment_file_name])
Expand Down

0 comments on commit abebb95

Please sign in to comment.