iotedgedev 3.3.4__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- s/.devcontainer/Dockerfile +75 -0
- s/.devcontainer/devcontainer.json +40 -0
- s/.devcontainer/library-scripts/docker-in-docker-debian.sh +236 -0
- s/.env.tmp +108 -0
- s/.git/FETCH_HEAD +61 -0
- s/.git/HEAD +1 -0
- s/.git/config +12 -0
- s/.git/description +1 -0
- s/.git/hooks/applypatch-msg.sample +15 -0
- s/.git/hooks/commit-msg.sample +24 -0
- s/.git/hooks/fsmonitor-watchman.sample +173 -0
- s/.git/hooks/post-update.sample +8 -0
- s/.git/hooks/pre-applypatch.sample +14 -0
- s/.git/hooks/pre-commit.sample +49 -0
- s/.git/hooks/pre-merge-commit.sample +13 -0
- s/.git/hooks/pre-push.sample +53 -0
- s/.git/hooks/pre-rebase.sample +169 -0
- s/.git/hooks/pre-receive.sample +24 -0
- s/.git/hooks/prepare-commit-msg.sample +42 -0
- s/.git/hooks/push-to-checkout.sample +78 -0
- s/.git/hooks/update.sample +128 -0
- s/.git/index +0 -0
- s/.git/info/exclude +6 -0
- s/.git/logs/HEAD +1 -0
- s/.git/logs/refs/remotes/origin/EO +1 -0
- s/.git/logs/refs/remotes/origin/avagraw/security_fix +1 -0
- s/.git/logs/refs/remotes/origin/cherry-pick-rename +1 -0
- s/.git/logs/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
- s/.git/logs/refs/remotes/origin/chyuan/update-linux-agent +1 -0
- s/.git/logs/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
- s/.git/logs/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
- s/.git/logs/refs/remotes/origin/main +1 -0
- s/.git/logs/refs/remotes/origin/ray-deps +1 -0
- s/.git/logs/refs/remotes/origin/ray-dev-setup +1 -0
- s/.git/logs/refs/remotes/origin/ray-tox +1 -0
- s/.git/logs/refs/remotes/origin/release-pipeline-automation +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/layered-deployments +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2 +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/update-pipeline +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/fixsimver +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/master-to-main +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/pipeline +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas2 +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_pypi +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_pypi-1 +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_testing +1 -0
- s/.git/logs/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
- s/.git/logs/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
- s/.git/logs/refs/remotes/origin/vikas/azure +1 -0
- s/.git/logs/refs/remotes/origin/vikas/dependebot +1 -0
- s/.git/logs/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
- s/.git/logs/refs/remotes/origin/xinzed/update-runtime +1 -0
- s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.idx +0 -0
- s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.pack +0 -0
- s/.git/refs/remotes/origin/EO +1 -0
- s/.git/refs/remotes/origin/avagraw/security_fix +1 -0
- s/.git/refs/remotes/origin/cherry-pick-rename +1 -0
- s/.git/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
- s/.git/refs/remotes/origin/chyuan/update-linux-agent +1 -0
- s/.git/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
- s/.git/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
- s/.git/refs/remotes/origin/main +1 -0
- s/.git/refs/remotes/origin/ray-deps +1 -0
- s/.git/refs/remotes/origin/ray-dev-setup +1 -0
- s/.git/refs/remotes/origin/ray-tox +1 -0
- s/.git/refs/remotes/origin/release-pipeline-automation +1 -0
- s/.git/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
- s/.git/refs/remotes/origin/spmcdono/layered-deployments +1 -0
- s/.git/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
- s/.git/refs/remotes/origin/spmcdono/remove-py2 +1 -0
- s/.git/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
- s/.git/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
- s/.git/refs/remotes/origin/spmcdono/update-pipeline +1 -0
- s/.git/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
- s/.git/refs/remotes/origin/user/marine/fixsimver +1 -0
- s/.git/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
- s/.git/refs/remotes/origin/user/marine/master-to-main +1 -0
- s/.git/refs/remotes/origin/user/marine/pipeline +1 -0
- s/.git/refs/remotes/origin/user/vikas +1 -0
- s/.git/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
- s/.git/refs/remotes/origin/user/vikas2 +1 -0
- s/.git/refs/remotes/origin/user/vikas_pypi +1 -0
- s/.git/refs/remotes/origin/user/vikas_pypi-1 +1 -0
- s/.git/refs/remotes/origin/user/vikas_testing +1 -0
- s/.git/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
- s/.git/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
- s/.git/refs/remotes/origin/vikas/azure +1 -0
- s/.git/refs/remotes/origin/vikas/dependebot +1 -0
- s/.git/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
- s/.git/refs/remotes/origin/xinzed/update-runtime +1 -0
- s/.git/refs/tags/v0.49.0 +1 -0
- s/.git/refs/tags/v0.50.0 +1 -0
- s/.git/refs/tags/v0.51.0 +1 -0
- s/.git/refs/tags/v0.52.0 +1 -0
- s/.git/refs/tags/v0.53.0 +1 -0
- s/.git/refs/tags/v0.54.0 +1 -0
- s/.git/refs/tags/v0.55.0 +1 -0
- s/.git/refs/tags/v0.56.0 +1 -0
- s/.git/refs/tags/v0.57.0 +1 -0
- s/.git/refs/tags/v0.58.0 +1 -0
- s/.git/refs/tags/v0.59.0 +1 -0
- s/.git/refs/tags/v0.60.0 +1 -0
- s/.git/refs/tags/v0.61.0 +1 -0
- s/.git/refs/tags/v0.62.0 +1 -0
- s/.git/refs/tags/v0.63.0 +1 -0
- s/.git/refs/tags/v0.64.0 +1 -0
- s/.git/refs/tags/v0.65.0 +1 -0
- s/.git/refs/tags/v0.66.0 +1 -0
- s/.git/refs/tags/v0.67.0 +1 -0
- s/.git/refs/tags/v0.68.0 +1 -0
- s/.git/refs/tags/v0.69.0 +1 -0
- s/.git/refs/tags/v0.70.0 +1 -0
- s/.git/refs/tags/v0.71.0 +1 -0
- s/.git/refs/tags/v0.72.0 +1 -0
- s/.git/refs/tags/v0.73.0 +1 -0
- s/.git/refs/tags/v0.74.0 +1 -0
- s/.git/refs/tags/v0.75.0 +1 -0
- s/.git/refs/tags/v0.76.0 +1 -0
- s/.git/refs/tags/v0.77.0 +1 -0
- s/.git/refs/tags/v0.78.0 +1 -0
- s/.git/refs/tags/v0.79.0 +1 -0
- s/.git/refs/tags/v0.82.0 +1 -0
- s/.git/refs/tags/v0.82.0-container +1 -0
- s/.git/refs/tags/v1.0.0 +1 -0
- s/.git/refs/tags/v1.1.0 +1 -0
- s/.git/refs/tags/v1.2.0 +1 -0
- s/.git/refs/tags/v1.3.0 +1 -0
- s/.git/refs/tags/v2.0.0 +1 -0
- s/.git/refs/tags/v2.0.1 +1 -0
- s/.git/refs/tags/v2.0.2 +1 -0
- s/.git/refs/tags/v2.1.0 +1 -0
- s/.git/refs/tags/v2.1.1 +1 -0
- s/.git/refs/tags/v2.1.2 +1 -0
- s/.git/refs/tags/v2.1.3 +1 -0
- s/.git/refs/tags/v2.1.4 +1 -0
- s/.git/refs/tags/v2.1.6 +1 -0
- s/.git/refs/tags/v2.2.0 +1 -0
- s/.git/refs/tags/v3.0.0 +1 -0
- s/.git/refs/tags/v3.0.0-rc +1 -0
- s/.git/refs/tags/v3.1.0 +1 -0
- s/.git/refs/tags/v3.1.1 +1 -0
- s/.git/refs/tags/v3.1.2 +1 -0
- s/.git/refs/tags/v3.2.0 +1 -0
- s/.git/refs/tags/v3.2.0rc0 +1 -0
- s/.git/refs/tags/v3.3.0 +1 -0
- s/.git/refs/tags/v3.3.1 +1 -0
- s/.git/refs/tags/v3.3.2 +1 -0
- s/.git/refs/tags/v3.3.3 +1 -0
- s/.git/refs/tags/v3.3.3-rc0 +1 -0
- s/.git/refs/tags/v3.3.4 +1 -0
- s/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
- s/.github/ISSUE_TEMPLATE/feature_request.md +7 -0
- s/.github/workflows/wiki.yml +54 -0
- s/.gitignore +103 -0
- s/.vscode/launch.json +26 -0
- s/.vscode/settings.json +30 -0
- s/CHANGELOG.md +156 -0
- s/CODE_OF_CONDUCT.md +1 -0
- s/CONTRIBUTING.md +122 -0
- s/LICENSE +14 -0
- s/MANIFEST.in +7 -0
- s/Makefile +87 -0
- s/README.md +204 -0
- s/assets/armdeployment.png +0 -0
- s/assets/armoutputs.png +0 -0
- s/assets/deploy/ARMDeployment/ARMDeployment.deployproj +36 -0
- s/assets/deploy/ARMDeployment/Deploy-AzureResourceGroup.ps1 +118 -0
- s/assets/deploy/ARMDeployment/azuredeploy.json +145 -0
- s/assets/deploy/ARMDeployment/azuredeploy.parameters.json +6 -0
- s/assets/deploy/ARMDeployment.sln +25 -0
- s/assets/edgedevtool2mins.png +0 -0
- s/assets/edgedevtoolintro.png +0 -0
- s/assets/edgedevtoolquickstartlarge.png +0 -0
- s/assets/edgedevtoolquickstartsmall.png +0 -0
- s/assets/edgedevtoolwsl.png +0 -0
- s/azure-pipelines.yml +144 -0
- s/build/lib/iotedgedev/__init__.py +6 -0
- s/build/lib/iotedgedev/args.py +18 -0
- s/build/lib/iotedgedev/azurecli.py +542 -0
- s/build/lib/iotedgedev/buildoptionsparser.py +151 -0
- s/build/lib/iotedgedev/buildprofile.py +5 -0
- s/build/lib/iotedgedev/cli.py +830 -0
- s/build/lib/iotedgedev/connectionstring.py +58 -0
- s/build/lib/iotedgedev/constants.py +12 -0
- s/build/lib/iotedgedev/containerregistry.py +5 -0
- s/build/lib/iotedgedev/decorators.py +116 -0
- s/build/lib/iotedgedev/deploymentmanifest.py +313 -0
- s/build/lib/iotedgedev/dockercls.py +255 -0
- s/build/lib/iotedgedev/dotnet.py +31 -0
- s/build/lib/iotedgedev/edge.py +33 -0
- s/build/lib/iotedgedev/envvars.py +240 -0
- s/build/lib/iotedgedev/iothub.py +65 -0
- s/build/lib/iotedgedev/module.py +62 -0
- s/build/lib/iotedgedev/modules.py +332 -0
- s/build/lib/iotedgedev/organizedgroup.py +48 -0
- s/build/lib/iotedgedev/output.py +57 -0
- s/build/lib/iotedgedev/simulator.py +58 -0
- s/build/lib/iotedgedev/solution.py +48 -0
- s/build/lib/iotedgedev/telemetry.py +155 -0
- s/build/lib/iotedgedev/telemetryconfig.py +85 -0
- s/build/lib/iotedgedev/telemetryuploader.py +53 -0
- s/build/lib/iotedgedev/template/.env.tmp +87 -0
- s/build/lib/iotedgedev/template/.gitignore +10 -0
- s/build/lib/iotedgedev/template/deployment.template.json +79 -0
- s/build/lib/iotedgedev/template/launch_c.json +50 -0
- s/build/lib/iotedgedev/template/launch_csharp.json +43 -0
- s/build/lib/iotedgedev/template/launch_java.json +27 -0
- s/build/lib/iotedgedev/template/launch_node.json +36 -0
- s/build/lib/iotedgedev/template/launch_python.json +22 -0
- s/build/lib/iotedgedev/utility.py +179 -0
- s/build/lib/iotedgedev/version.py +4 -0
- s/build.sh +150 -0
- s/cleanup.sh +7 -0
- s/dist/iotedgedev-3.3.4-py3-none-any.whl +0 -0
- s/docker/tool/build-docker.sh +168 -0
- s/docker/tool/deps.txt +7 -0
- s/docker/tool/linux/Dockerfile +7 -0
- s/docker/tool/linux/Dockerfile.base +61 -0
- s/docker/tool/linux/install-dev.sh +8 -0
- s/docker/tool/linux/run.ps1 +5 -0
- s/docker/tool/linux/run.sh +5 -0
- s/docker/tool/push-docker.sh +35 -0
- s/docker/tool/windows/Dockerfile +4 -0
- s/docker/tool/windows/Dockerfile.base +63 -0
- s/docker/tool/windows/install-dev.bat +4 -0
- s/docker/tool/windows/run.ps1 +30 -0
- s/docs/Azure-Setup.md +102 -0
- s/docs/Command-List.md +564 -0
- s/docs/Command-Tips.md +51 -0
- s/docs/Edge-Device-Setup.md +23 -0
- s/docs/Home.md +10 -0
- s/docs/Manual-Dev-Machine-Setup.md +77 -0
- s/docs/Migration-Guides.md +131 -0
- s/docs/Overview.md +66 -0
- s/docs/Python-Virtual-Environment-Setup.md +35 -0
- s/docs/Quickstart-with-IoT-Edge-Dev-Container.md +145 -0
- s/docs/Test-Coverage.md +7 -0
- s/docs/Troubleshooting.md +21 -0
- s/docs/Usage.md +123 -0
- s/docs/_Sidebar.md +13 -0
- s/iotedgedev/__init__.py +6 -0
- s/iotedgedev/args.py +18 -0
- s/iotedgedev/azurecli.py +542 -0
- s/iotedgedev/buildoptionsparser.py +151 -0
- s/iotedgedev/buildprofile.py +5 -0
- s/iotedgedev/cli.py +830 -0
- s/iotedgedev/connectionstring.py +58 -0
- s/iotedgedev/constants.py +12 -0
- s/iotedgedev/containerregistry.py +5 -0
- s/iotedgedev/decorators.py +116 -0
- s/iotedgedev/deploymentmanifest.py +313 -0
- s/iotedgedev/dockercls.py +255 -0
- s/iotedgedev/dotnet.py +31 -0
- s/iotedgedev/edge.py +33 -0
- s/iotedgedev/envvars.py +240 -0
- s/iotedgedev/iothub.py +65 -0
- s/iotedgedev/module.py +62 -0
- s/iotedgedev/modules.py +332 -0
- s/iotedgedev/organizedgroup.py +48 -0
- s/iotedgedev/output.py +57 -0
- s/iotedgedev/simulator.py +58 -0
- s/iotedgedev/solution.py +48 -0
- s/iotedgedev/telemetry.py +155 -0
- s/iotedgedev/telemetryconfig.py +85 -0
- s/iotedgedev/telemetryuploader.py +53 -0
- s/iotedgedev/template/.env.tmp +87 -0
- s/iotedgedev/template/.gitignore +10 -0
- s/iotedgedev/template/deployment.template.json +79 -0
- s/iotedgedev/template/launch_c.json +50 -0
- s/iotedgedev/template/launch_csharp.json +43 -0
- s/iotedgedev/template/launch_java.json +27 -0
- s/iotedgedev/template/launch_node.json +36 -0
- s/iotedgedev/template/launch_python.json +22 -0
- s/iotedgedev/utility.py +179 -0
- s/iotedgedev/version.py +4 -0
- s/iotedgedev.egg-info/PKG-INFO +21 -0
- s/iotedgedev.egg-info/SOURCES.txt +100 -0
- s/iotedgedev.egg-info/dependency_links.txt +1 -0
- s/iotedgedev.egg-info/entry_points.txt +3 -0
- s/iotedgedev.egg-info/not-zip-safe +1 -0
- s/iotedgedev.egg-info/requires.txt +18 -0
- s/iotedgedev.egg-info/top_level.txt +1 -0
- s/pull_request_template.md +9 -0
- s/pytest.ini +4 -0
- s/requirements.txt +12 -0
- s/requirements_dev.txt +17 -0
- s/scripts/gen-help-markdown.bat +177 -0
- s/scripts/install-pip.sh +1 -0
- s/scripts/setup-wsl.sh +7 -0
- s/setup.cfg +18 -0
- s/setup.py +66 -0
- s/tests/__init__.py +5 -0
- s/tests/assets/deployment.manifest_invalid.json +106 -0
- s/tests/assets/deployment.manifest_invalid_createoptions.json +102 -0
- s/tests/assets/deployment.manifest_invalid_schema.json +69 -0
- s/tests/assets/deployment.template.non_str_placeholder.json +79 -0
- s/tests/assets/deployment.template_1.json +163 -0
- s/tests/assets/deployment.template_2.json +163 -0
- s/tests/assets/deployment.template_3.json +174 -0
- s/tests/assets/deployment.template_4.json +79 -0
- s/tests/assets/deployment.template_invalidresult.json +183 -0
- s/tests/assets/deployment.template_without_schema_template.json +99 -0
- s/tests/assets/launch.json +225 -0
- s/tests/assets/launch_without_nodejs.json +194 -0
- s/tests/assets/test_solution_shared_lib/.gitignore +2 -0
- s/tests/assets/test_solution_shared_lib/.vscode/launch.json +43 -0
- s/tests/assets/test_solution_shared_lib/deployment.debug.template.json +100 -0
- s/tests/assets/test_solution_shared_lib/deployment.escapedpath.template.json +90 -0
- s/tests/assets/test_solution_shared_lib/deployment.template.json +106 -0
- s/tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json +21 -0
- s/tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json +12 -0
- s/tests/assets/test_solution_shared_lib/libs/sharedlib/Class1.cs +12 -0
- s/tests/assets/test_solution_shared_lib/libs/sharedlib/sharedlib.csproj +7 -0
- s/tests/assets/test_solution_shared_lib/modules/non_module_project/placeholder.txt +0 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/.gitignore +34 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64 +18 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64.debug +25 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.windows-amd64 +15 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Program.cs +91 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/module.json +18 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/sample_module.csproj +26 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/.gitignore +34 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64 +18 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64.debug +25 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.windows-amd64 +15 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Program.cs +91 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/module.json +18 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/sample_module_2.csproj +26 -0
- s/tests/test_azurecli.py +33 -0
- s/tests/test_buildoptionsparser.py +155 -0
- s/tests/test_cli.py +55 -0
- s/tests/test_config.py +28 -0
- s/tests/test_connectionstring.py +87 -0
- s/tests/test_decorators.py +44 -0
- s/tests/test_deploymentmanifest.py +106 -0
- s/tests/test_envvars.py +169 -0
- s/tests/test_iotedgedev_iothub_deploy.py +199 -0
- s/tests/test_iotedgedev_simulator.py +133 -0
- s/tests/test_iotedgedev_solution.py +457 -0
- s/tests/test_iotedgedev_solution_build.py +246 -0
- s/tests/test_iotedgedev_solution_tag.py +99 -0
- s/tests/test_utility.py +132 -0
- s/tests/utility.py +132 -0
- s/tox.ini +29 -0
- s/vsts_ci/.vsts-ci.yml +93 -0
- s/vsts_ci/darwin/continuous-build-darwin.yml +54 -0
- s/vsts_ci/linux/continuous-build-linux.yml +28 -0
- s/vsts_ci/win32/continuous-build-win32.yml +26 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import platform
|
|
4
|
+
import shutil
|
|
5
|
+
import time
|
|
6
|
+
from unittest import mock
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
from iotedgedev.envvars import EnvVars
|
|
10
|
+
from iotedgedev.output import Output
|
|
11
|
+
|
|
12
|
+
from .utility import (get_all_docker_images, get_docker_os_type,
|
|
13
|
+
get_file_content, get_platform_type, runner_invoke,
|
|
14
|
+
update_file_content)
|
|
15
|
+
|
|
16
|
+
pytestmark = pytest.mark.e2e
|
|
17
|
+
|
|
18
|
+
output = Output()
|
|
19
|
+
envvars = EnvVars(output)
|
|
20
|
+
|
|
21
|
+
tests_dir = os.path.join(os.getcwd(), "tests")
|
|
22
|
+
tests_assets_dir = os.path.join(tests_dir, "assets")
|
|
23
|
+
|
|
24
|
+
env_file_name = envvars.get_dotenv_file()
|
|
25
|
+
env_file_path = envvars.get_dotenv_path(env_file_name)
|
|
26
|
+
|
|
27
|
+
launch_json_file = os.path.join(tests_dir, "assets", "launch.json")
|
|
28
|
+
launch_json_file_without_nodejs = os.path.join(tests_assets_dir, "launch_without_nodejs.json")
|
|
29
|
+
test_solution_shared_lib_dir = os.path.join(tests_assets_dir, "test_solution_shared_lib")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@pytest.fixture
|
|
33
|
+
def prepare_solution_with_env():
|
|
34
|
+
os.chdir(tests_dir)
|
|
35
|
+
test_solution = "test_solution"
|
|
36
|
+
test_solution_dir = os.path.join(tests_dir, test_solution)
|
|
37
|
+
template = "csharp"
|
|
38
|
+
module_name = "filtermodule"
|
|
39
|
+
result = runner_invoke(['new', test_solution, '-m', module_name, '-t', template])
|
|
40
|
+
|
|
41
|
+
if 'AZURE IOT EDGE SOLUTION CREATED' not in result.output:
|
|
42
|
+
raise Exception(result.stdout)
|
|
43
|
+
|
|
44
|
+
shutil.copyfile(env_file_path, os.path.join(test_solution_dir, env_file_name))
|
|
45
|
+
|
|
46
|
+
os.chdir(test_solution_dir)
|
|
47
|
+
|
|
48
|
+
yield prepare_solution_with_env
|
|
49
|
+
os.chdir(tests_dir)
|
|
50
|
+
time.sleep(5)
|
|
51
|
+
shutil.rmtree(test_solution_dir, ignore_errors=True)
|
|
52
|
+
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def test_solution_build_and_push_with_layered_deployment():
|
|
57
|
+
# Arrange
|
|
58
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
59
|
+
new_config_deployment_path = os.path.join(test_solution_shared_lib_dir, 'config', "layered_deployment.flattened_props.json")
|
|
60
|
+
|
|
61
|
+
# Act
|
|
62
|
+
result = runner_invoke(['build', '--push', '-f', "layered_deployment.flattened_props.template.json", '-P', get_platform_type()])
|
|
63
|
+
|
|
64
|
+
# Assert
|
|
65
|
+
assert os.path.exists(new_config_deployment_path)
|
|
66
|
+
assert 'sample_module:0.0.1-RC' in result.output
|
|
67
|
+
assert 'BUILD COMPLETE' in result.output
|
|
68
|
+
assert 'PUSH COMPLETE' in result.output
|
|
69
|
+
assert 'ERROR' not in result.output
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_solution_build_and_push_with_layered_deployment_no_modules():
|
|
73
|
+
# Arrange
|
|
74
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
75
|
+
new_config_deployment_path = os.path.join(test_solution_shared_lib_dir, 'config', 'layered_deployment.no_modules.json')
|
|
76
|
+
|
|
77
|
+
# Act
|
|
78
|
+
result = runner_invoke(['build', '--push', '-f', "layered_deployment.no_modules.template.json", '-P', get_platform_type()])
|
|
79
|
+
|
|
80
|
+
# Assert
|
|
81
|
+
|
|
82
|
+
with open(new_config_deployment_path, "r") as f:
|
|
83
|
+
content = json.load(f)
|
|
84
|
+
|
|
85
|
+
set_property = content["content"]["modulesContent"]["exampleModule"]["properties.desired"]["foo"]
|
|
86
|
+
|
|
87
|
+
assert 'ERROR' not in result.output
|
|
88
|
+
assert 'bar-1.2' == set_property
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_solution_build_and_push_with_platform():
|
|
92
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
93
|
+
|
|
94
|
+
result = runner_invoke(['build', '-P', get_platform_type()])
|
|
95
|
+
|
|
96
|
+
assert 'BUILD COMPLETE' in result.output
|
|
97
|
+
assert 'PUSH COMPLETE' not in result.output
|
|
98
|
+
assert 'sample_module:0.0.1-RC' in result.output
|
|
99
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
100
|
+
assert 'ERROR' not in result.output
|
|
101
|
+
|
|
102
|
+
result = runner_invoke(['push', '--no-build', '-P', get_platform_type()])
|
|
103
|
+
|
|
104
|
+
assert 'PUSH COMPLETE' in result.output
|
|
105
|
+
assert 'BUILD COMPLETE' not in result.output
|
|
106
|
+
assert 'sample_module:0.0.1-RC' in result.output
|
|
107
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
108
|
+
assert 'ERROR' not in result.output
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def test_solution_build_and_push_with_different_cwd():
|
|
112
|
+
cwd = os.path.join(test_solution_shared_lib_dir, 'config')
|
|
113
|
+
if not os.path.exists(cwd):
|
|
114
|
+
os.makedirs(cwd)
|
|
115
|
+
os.chdir(cwd)
|
|
116
|
+
|
|
117
|
+
result = runner_invoke(['build', '-f', '../deployment.template.json', '-P', get_platform_type()])
|
|
118
|
+
|
|
119
|
+
assert 'BUILD COMPLETE' in result.output
|
|
120
|
+
assert 'sample_module:0.0.1-RC' in result.output
|
|
121
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
122
|
+
assert 'ERROR' not in result.output
|
|
123
|
+
|
|
124
|
+
result = runner_invoke(['push', '-f', '../deployment.template.json', '--no-build', '-P', get_platform_type()])
|
|
125
|
+
|
|
126
|
+
assert 'PUSH COMPLETE' in result.output
|
|
127
|
+
assert 'sample_module:0.0.1-RC' in result.output
|
|
128
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
129
|
+
assert 'ERROR' not in result.output
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.mark.skipif(platform.system().lower() != 'windows', reason='The path is not valid in non windows platform')
|
|
133
|
+
def test_solution_build_and_push_with_escapedpath():
|
|
134
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
135
|
+
|
|
136
|
+
result = runner_invoke(['build', '-f', 'deployment.escapedpath.template.json', '-P', get_platform_type()])
|
|
137
|
+
|
|
138
|
+
assert 'BUILD COMPLETE' in result.output
|
|
139
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
140
|
+
assert 'ERROR' not in result.output
|
|
141
|
+
|
|
142
|
+
result = runner_invoke(['push', '--no-build', '-P', get_platform_type()])
|
|
143
|
+
|
|
144
|
+
assert 'PUSH COMPLETE' in result.output
|
|
145
|
+
assert 'sample_module_2:0.0.1-RC' in result.output
|
|
146
|
+
assert 'ERROR' not in result.output
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@mock.patch.dict(os.environ, {"VERSION": "0.0.2"})
|
|
150
|
+
def test_solution_build_with_version_and_build_options():
|
|
151
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
152
|
+
module_json_file_path = os.path.join(test_solution_shared_lib_dir, "modules", "sample_module", "module.json")
|
|
153
|
+
module_2_json_file_path = os.path.join(test_solution_shared_lib_dir, "sample_module_2", "module.json")
|
|
154
|
+
try:
|
|
155
|
+
update_file_content(module_json_file_path, '"version": "0.0.1-RC"', '"version": "${VERSION}"')
|
|
156
|
+
update_file_content(module_json_file_path, '"buildOptions": (.*),', '"buildOptions": [ "--add-host=github.com:192.30.255.112", "--build-arg a=b" ],')
|
|
157
|
+
update_file_content(module_2_json_file_path, '"version": "0.0.1-RC"', '"version": "${VERSION}"')
|
|
158
|
+
update_file_content(module_2_json_file_path, '"buildOptions": (.*),', '"buildOptions": [ "--add-host=github.com:192.30.255.112", "--build-arg a=b" ],')
|
|
159
|
+
|
|
160
|
+
result = runner_invoke(['build', '-P', get_platform_type()])
|
|
161
|
+
|
|
162
|
+
assert 'BUILD COMPLETE' in result.output
|
|
163
|
+
assert 'sample_module:0.0.2' in result.output
|
|
164
|
+
assert 'sample_module_2:0.0.2' in result.output
|
|
165
|
+
assert 'ERROR' not in result.output
|
|
166
|
+
assert '0.0.2' in get_all_docker_images()
|
|
167
|
+
|
|
168
|
+
finally:
|
|
169
|
+
update_file_content(module_json_file_path, '"version": "(.*)"', '"version": "0.0.1-RC"')
|
|
170
|
+
update_file_content(module_json_file_path, '"buildOptions": (.*),', '"buildOptions": [],')
|
|
171
|
+
update_file_content(module_2_json_file_path, '"version": "(.*)"', '"version": "0.0.1-RC"')
|
|
172
|
+
update_file_content(module_2_json_file_path, '"buildOptions": (.*),', '"buildOptions": [],')
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def test_solution_build_without_schema_template():
|
|
176
|
+
try:
|
|
177
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
178
|
+
|
|
179
|
+
os.rename('deployment.template.json', 'deployment.template.backup.json')
|
|
180
|
+
template_without_schema_version = os.path.join(tests_dir, "assets", "deployment.template_without_schema_template.json")
|
|
181
|
+
shutil.copyfile(template_without_schema_version, 'deployment.template.json')
|
|
182
|
+
|
|
183
|
+
update_file_content('deployment.template.json', '"image": "(.*)MODULES.sample_module}",', '"image": "${MODULES.sample_module.' + get_platform_type() + '}",')
|
|
184
|
+
|
|
185
|
+
result = runner_invoke(['build'])
|
|
186
|
+
|
|
187
|
+
assert 'BUILD COMPLETE' in result.output
|
|
188
|
+
assert 'ERROR' not in result.output
|
|
189
|
+
|
|
190
|
+
config_file_path = os.path.join(test_solution_shared_lib_dir, "config", "deployment.json")
|
|
191
|
+
assert os.path.exists(config_file_path)
|
|
192
|
+
|
|
193
|
+
content = get_file_content(config_file_path)
|
|
194
|
+
assert "sample_module:0.0.1-RC-" + get_platform_type() in content
|
|
195
|
+
finally:
|
|
196
|
+
os.remove('deployment.template.json')
|
|
197
|
+
os.rename('deployment.template.backup.json', 'deployment.template.json')
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_solution_build_with_default_platform(prepare_solution_with_env):
|
|
201
|
+
result = runner_invoke(['build'])
|
|
202
|
+
|
|
203
|
+
module_name = "filtermodule"
|
|
204
|
+
test_solution_config_dir = os.path.join('config', 'deployment.' + get_platform_type() + '.json')
|
|
205
|
+
env_container_registry_server = os.getenv("CONTAINER_REGISTRY_SERVER")
|
|
206
|
+
with open(test_solution_config_dir) as f:
|
|
207
|
+
content = json.load(f)
|
|
208
|
+
|
|
209
|
+
assert 'BUILD COMPLETE' in result.output
|
|
210
|
+
assert 'ERROR' not in result.output
|
|
211
|
+
assert env_container_registry_server + "/" + module_name + ":0.0.1-" + get_platform_type() in content[
|
|
212
|
+
"modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_name]["settings"]["image"]
|
|
213
|
+
assert module_name in get_all_docker_images()
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
@pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Debugger does not support C# in windows container')
|
|
217
|
+
def test_solution_build_with_debug_template():
|
|
218
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
219
|
+
|
|
220
|
+
result = runner_invoke(['build', '-f', os.environ["DEPLOYMENT_CONFIG_DEBUG_TEMPLATE_FILE"], '-P', get_platform_type()])
|
|
221
|
+
|
|
222
|
+
module_name = "sample_module"
|
|
223
|
+
module_2_name = "sample_module_2"
|
|
224
|
+
test_solution_shared_debug_config = os.path.join('config', 'deployment.debug.' + get_platform_type() + '.json')
|
|
225
|
+
env_container_registry_server = os.getenv("CONTAINER_REGISTRY_SERVER")
|
|
226
|
+
with open(test_solution_shared_debug_config) as f:
|
|
227
|
+
content = json.load(f)
|
|
228
|
+
|
|
229
|
+
assert 'BUILD COMPLETE' in result.output
|
|
230
|
+
assert 'ERROR' not in result.output
|
|
231
|
+
assert env_container_registry_server + "/" + module_name + ":0.0.1-RC-" + get_platform_type() + ".debug" in content[
|
|
232
|
+
"modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_name]["settings"]["image"]
|
|
233
|
+
assert env_container_registry_server + "/" + module_2_name + ":0.0.1-RC-" + get_platform_type() + ".debug" in content[
|
|
234
|
+
"modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_2_name]["settings"]["image"]
|
|
235
|
+
all_docker_images = get_all_docker_images()
|
|
236
|
+
assert module_name in all_docker_images
|
|
237
|
+
assert module_2_name in all_docker_images
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@pytest.mark.skipif(get_docker_os_type() == 'windows', reason='The output of docker build logs is not captured by logs on windows, need to capture this before enabling this test')
|
|
241
|
+
def test_verify_docker_build_status_in_output():
|
|
242
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
243
|
+
|
|
244
|
+
result = runner_invoke(['build', '-f' 'deployment.debug.template.json', '-P', get_platform_type()])
|
|
245
|
+
|
|
246
|
+
assert all(x in result.output for x in ["--->", "Step 1/", "Successfully tagged"])
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pytest
|
|
3
|
+
from .utility import (
|
|
4
|
+
runner_invoke,
|
|
5
|
+
)
|
|
6
|
+
from iotedgedev.azurecli import AzureCli
|
|
7
|
+
from iotedgedev.envvars import EnvVars
|
|
8
|
+
from iotedgedev.output import Output
|
|
9
|
+
from iotedgedev.connectionstring import DeviceConnectionString
|
|
10
|
+
from unittest import mock
|
|
11
|
+
|
|
12
|
+
pytestmark = pytest.mark.e2e
|
|
13
|
+
|
|
14
|
+
output = Output()
|
|
15
|
+
envvars = EnvVars(output)
|
|
16
|
+
test_solution_shared_lib_dir = os.path.join(os.getcwd(), "tests", "assets", "test_solution_shared_lib")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Test that cmd line tags (--tags) overrides DEVICE_TAGS from .env
|
|
20
|
+
@ mock.patch.dict(os.environ, {"DEVICE_TAGS": "invalid_target"})
|
|
21
|
+
def test_add_tags():
|
|
22
|
+
# Arrange
|
|
23
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
24
|
+
|
|
25
|
+
# Act
|
|
26
|
+
result = runner_invoke(['solution', 'tag', '--tags', '{"environment":"dev","building":"9"}'])
|
|
27
|
+
|
|
28
|
+
# Assert
|
|
29
|
+
assert 'TAG UPDATE COMPLETE' in result.output
|
|
30
|
+
assert '{"environment":"dev","building":"9"}' in result.output
|
|
31
|
+
assert 'ERROR' not in result.output
|
|
32
|
+
|
|
33
|
+
# Cleanup
|
|
34
|
+
azure_cli = AzureCli(output, envvars)
|
|
35
|
+
|
|
36
|
+
assert azure_cli.invoke_az_cli_outproc(["iot", "hub", "device-twin", "replace", "-d", DeviceConnectionString(envvars.get_envvar("DEVICE_CONNECTION_STRING")).device_id,
|
|
37
|
+
"-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING"), "--json", "{}"])
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.mark.parametrize(
|
|
41
|
+
"tags",
|
|
42
|
+
[
|
|
43
|
+
"tags.environment='dev'",
|
|
44
|
+
"dev"
|
|
45
|
+
]
|
|
46
|
+
)
|
|
47
|
+
def test_add_invalid_tag(tags):
|
|
48
|
+
# Arrange
|
|
49
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
50
|
+
|
|
51
|
+
# Act
|
|
52
|
+
result = runner_invoke(['solution', 'tag', '--tags', tags])
|
|
53
|
+
|
|
54
|
+
# Assert
|
|
55
|
+
assert f"ERROR: Failed to add tag: '{tags}' to device" in result.output
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_error_missing_tag():
|
|
59
|
+
# Arrange
|
|
60
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
61
|
+
|
|
62
|
+
# Act
|
|
63
|
+
with pytest.raises(Exception) as context:
|
|
64
|
+
runner_invoke(['solution', 'tag', '--tags'])
|
|
65
|
+
|
|
66
|
+
# Assert
|
|
67
|
+
assert "Error: Option '--tags' requires an argument." in str(context)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@ mock.patch.dict(os.environ, {"DEVICE_TAGS": '{"environment":"dev","building":"9"}'})
|
|
71
|
+
def test_default_tag_from_env():
|
|
72
|
+
# Arrange
|
|
73
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
74
|
+
|
|
75
|
+
# Act
|
|
76
|
+
result = runner_invoke(['solution', 'tag'])
|
|
77
|
+
|
|
78
|
+
# Assert
|
|
79
|
+
assert 'TAG UPDATE COMPLETE' in result.output
|
|
80
|
+
assert '{"environment":"dev","building":"9"}' in result.output
|
|
81
|
+
assert 'ERROR' not in result.output
|
|
82
|
+
|
|
83
|
+
# Cleanup
|
|
84
|
+
azure_cli = AzureCli(output, envvars)
|
|
85
|
+
|
|
86
|
+
assert azure_cli.invoke_az_cli_outproc(["iot", "hub", "device-twin", "replace", "-d", DeviceConnectionString(envvars.get_envvar("DEVICE_CONNECTION_STRING")).device_id,
|
|
87
|
+
"-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING"), "--json", "{}"])
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_missing_default_tag_from_env():
|
|
91
|
+
# Arrange
|
|
92
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
93
|
+
|
|
94
|
+
# Act
|
|
95
|
+
with pytest.raises(Exception) as context:
|
|
96
|
+
runner_invoke(['solution', 'tag'])
|
|
97
|
+
|
|
98
|
+
# Assert
|
|
99
|
+
assert "ERROR: Environment Variable DEVICE_TAGS not set. Either add to .env file or to your system's Environment Variables" in str(context)
|
s/tests/test_utility.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from unittest import mock
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
from iotedgedev.envvars import EnvVars
|
|
6
|
+
from iotedgedev.output import Output
|
|
7
|
+
from iotedgedev.utility import Utility
|
|
8
|
+
|
|
9
|
+
from .utility import (assert_file_equal, assert_json_file_equal,
|
|
10
|
+
assert_list_equal)
|
|
11
|
+
|
|
12
|
+
pytestmark = pytest.mark.unit
|
|
13
|
+
|
|
14
|
+
tests_dir = os.path.join(os.getcwd(), "tests")
|
|
15
|
+
test_assets_dir = os.path.join(tests_dir, "assets")
|
|
16
|
+
test_file_1 = os.path.join(test_assets_dir, "deployment.template_1.json")
|
|
17
|
+
test_file_2 = os.path.join(test_assets_dir, "deployment.template_2.json")
|
|
18
|
+
test_file_4 = os.path.join(test_assets_dir, "deployment.template_4.json")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def utility():
|
|
23
|
+
output = Output()
|
|
24
|
+
envvars = EnvVars(output)
|
|
25
|
+
envvars.load()
|
|
26
|
+
return Utility(envvars, output)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_ensure_dir(request, utility):
|
|
30
|
+
before_ensure = os.listdir(tests_dir)
|
|
31
|
+
utility.ensure_dir(test_assets_dir)
|
|
32
|
+
after_ensure = os.listdir(tests_dir)
|
|
33
|
+
assert_list_equal(before_ensure, after_ensure)
|
|
34
|
+
|
|
35
|
+
new_dir = "new_dir"
|
|
36
|
+
utility.ensure_dir(new_dir)
|
|
37
|
+
assert os.path.exists(new_dir)
|
|
38
|
+
|
|
39
|
+
def clean():
|
|
40
|
+
if os.path.exists(new_dir):
|
|
41
|
+
os.rmdir(new_dir)
|
|
42
|
+
request.addfinalizer(clean)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_copy_from_template_dir(utility, tmpdir):
|
|
46
|
+
src_file = "deployment.template.json"
|
|
47
|
+
dest_dir = tmpdir.strpath
|
|
48
|
+
dest_file = tmpdir.join(src_file).strpath
|
|
49
|
+
utility.copy_from_template_dir(src_file, dest_dir, replacements={"%MODULE%": "filtermodule"})
|
|
50
|
+
assert_file_equal(dest_file, test_file_4)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_copy_template(utility, tmpdir):
|
|
54
|
+
replacements = {
|
|
55
|
+
"${MODULES.csharpmodule.amd64}": "localhost:5000/csharpmodule:0.0.1-amd64",
|
|
56
|
+
"${MODULES.csharpfunction.amd64.debug}": "localhost:5000/csharpfunction:0.0.1-amd64.debug"
|
|
57
|
+
}
|
|
58
|
+
dest = tmpdir.join("deployment_template_1.dest.json").strpath
|
|
59
|
+
utility.copy_template(test_file_1, dest, replacements=replacements, expandvars=False)
|
|
60
|
+
assert_json_file_equal(test_file_2, dest)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@mock.patch.dict(os.environ, {"CONTAINER_REGISTRY_SERVER": "localhost:5000"})
|
|
64
|
+
def test_copy_template_expandvars(utility, tmpdir):
|
|
65
|
+
replacements = {
|
|
66
|
+
"${MODULES.csharpmodule.amd64}": "${CONTAINER_REGISTRY_SERVER}/csharpmodule:0.0.1-amd64",
|
|
67
|
+
"${MODULES.csharpfunction.amd64.debug}": "${CONTAINER_REGISTRY_SERVER}/csharpfunction:0.0.1-amd64.debug"
|
|
68
|
+
}
|
|
69
|
+
dest = tmpdir.join("deployment_template_2.dest.json").strpath
|
|
70
|
+
dest2 = tmpdir.join("deployment_template_2.dest2.json").strpath
|
|
71
|
+
utility.copy_template(test_file_1, dest, replacements=replacements, expandvars=True)
|
|
72
|
+
utility.copy_template(test_file_2, dest2, expandvars=True)
|
|
73
|
+
assert_json_file_equal(dest, dest2)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_in_asterisk_list(utility):
|
|
77
|
+
assert utility.in_asterisk_list("filtermodule", "pipemodule, filtermodule")
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_in_asterisk_list_empty(utility):
|
|
81
|
+
assert not utility.in_asterisk_list("filtermodule", "")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_in_asterisk_list_asterisk(utility):
|
|
85
|
+
assert utility.in_asterisk_list("filtermodule", "*")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_del_key(utility):
|
|
89
|
+
dict_ = {
|
|
90
|
+
"1": 0,
|
|
91
|
+
"2": {
|
|
92
|
+
"3": 0,
|
|
93
|
+
"4": "foo",
|
|
94
|
+
"5": {
|
|
95
|
+
"6": 0
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
assert utility.del_key("not a dict", ["1", "2"]) is None
|
|
101
|
+
assert utility.del_key(dict_, ["2", "5"]) == {"6": 0}
|
|
102
|
+
assert utility.del_key(dict_, ["1", "non_existent_key"]) is None
|
|
103
|
+
assert utility.del_key(dict_, ["2", "non_existent_key"]) is None
|
|
104
|
+
|
|
105
|
+
expected = {
|
|
106
|
+
"1": 0,
|
|
107
|
+
"2": {
|
|
108
|
+
"3": 0,
|
|
109
|
+
"4": "foo"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
assert dict_ == expected
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_get_sha256_hash():
|
|
117
|
+
assert Utility.get_sha256_hash("foo") == "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@mock.patch.dict(os.environ, {"DEPLOYMENT_CONFIG_FILE": "foo.json"})
|
|
121
|
+
def test_get_deployment_manifest_name__set_from_envvar():
|
|
122
|
+
assert Utility.get_deployment_manifest_name("deployment.debug.template.json", "1.0.0", "amd64") == "foo.json"
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_get_deployment_manifest_name():
|
|
126
|
+
assert Utility.get_deployment_manifest_name("config/deployment.template.json", "0.0.1", "amd64") == "deployment.json"
|
|
127
|
+
assert Utility.get_deployment_manifest_name("deployment.template.json", "0.0.1", "amd64") == "deployment.json"
|
|
128
|
+
assert Utility.get_deployment_manifest_name("deployment.debug.template.json", "0.0.1", "amd64") == "deployment.debug.json"
|
|
129
|
+
assert Utility.get_deployment_manifest_name("config/deployment.template.json", "1.0.0", "amd64") == "deployment.amd64.json"
|
|
130
|
+
assert Utility.get_deployment_manifest_name("deployment.template.json", "1.0.0", "amd64") == "deployment.amd64.json"
|
|
131
|
+
assert Utility.get_deployment_manifest_name("deployment.debug.template.json", "1.0.0", "amd64") == "deployment.debug.amd64.json"
|
|
132
|
+
assert Utility.get_deployment_manifest_name("", "", "") == "deployment.json"
|
s/tests/utility.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from click.testing import CliRunner
|
|
8
|
+
from iotedgedev.dockercls import Docker
|
|
9
|
+
from iotedgedev.envvars import EnvVars
|
|
10
|
+
from iotedgedev.output import Output
|
|
11
|
+
from iotedgedev.utility import Utility
|
|
12
|
+
|
|
13
|
+
output = Output()
|
|
14
|
+
envvars = EnvVars(output)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def assert_list_equal(list1, list2):
|
|
18
|
+
assert len(list1) == len(list2) and sorted(list1) == sorted(list2)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def assert_file_equal(file1, file2):
|
|
22
|
+
with open(file1, "r") as f1:
|
|
23
|
+
with open(file2, "r") as f2:
|
|
24
|
+
assert f1.read() == f2.read()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def assert_json_file_equal(file1, file2):
|
|
28
|
+
with open(file1, "r") as f1:
|
|
29
|
+
with open(file2, "r") as f2:
|
|
30
|
+
assert json.load(f1) == json.load(f2)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def get_docker_client():
|
|
34
|
+
envvars.load(force=True)
|
|
35
|
+
utility = Utility(envvars, output)
|
|
36
|
+
docker_client = Docker(envvars, utility, output)
|
|
37
|
+
docker_client.init_registry()
|
|
38
|
+
return docker_client
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_docker_os_type():
|
|
42
|
+
os_type = get_docker_client().get_os_type().lower()
|
|
43
|
+
return os_type
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_platform_type():
|
|
47
|
+
if get_docker_os_type() == 'windows':
|
|
48
|
+
platform_type = 'windows-amd64'
|
|
49
|
+
else:
|
|
50
|
+
platform_type = 'amd64'
|
|
51
|
+
return platform_type
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_all_docker_containers():
|
|
55
|
+
output = start_process(['docker', 'ps', '-a'], False)
|
|
56
|
+
return output
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_all_docker_images():
|
|
60
|
+
output = start_process(['docker', 'image', 'ls'], False)
|
|
61
|
+
return output
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def prune_docker_images():
|
|
65
|
+
output = start_process(['docker', 'image', 'prune', '-f'], False)
|
|
66
|
+
return output
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def prune_docker_containers():
|
|
70
|
+
output = start_process(['docker', 'container', 'prune', '-f'], False)
|
|
71
|
+
return output
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def prune_docker_build_cache():
|
|
75
|
+
output = start_process(['docker', 'builder', 'prune', '-f'], False)
|
|
76
|
+
return output
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def remove_docker_container(container_name):
|
|
80
|
+
output = start_process(['docker', 'rm', '-f', container_name], False)
|
|
81
|
+
return output
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def remove_docker_image(image_name):
|
|
85
|
+
output = start_process(['docker', 'rmi', '-f', image_name], False)
|
|
86
|
+
return output
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def runner_invoke(args, expect_failure=False):
|
|
90
|
+
runner = CliRunner()
|
|
91
|
+
with runner.isolation(env={"DEFAULT_PLATFORM": get_platform_type()}):
|
|
92
|
+
iotedgedev_import = "iotedgedev.cli"
|
|
93
|
+
cli = __import__(iotedgedev_import, fromlist=['main'])
|
|
94
|
+
# Remove "iotedgedev.cli" import from cache, to prevent variables being saved across tests
|
|
95
|
+
del sys.modules[iotedgedev_import]
|
|
96
|
+
result = runner.invoke(cli.main, args)
|
|
97
|
+
if (result.exit_code == 0) or (expect_failure is True):
|
|
98
|
+
return result
|
|
99
|
+
else:
|
|
100
|
+
raise Exception(result.stdout)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def start_process(command, is_shell):
|
|
104
|
+
process = subprocess.Popen(command, shell=is_shell,
|
|
105
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
106
|
+
output, error = process.communicate()
|
|
107
|
+
if process.returncode == 0:
|
|
108
|
+
return str(output)
|
|
109
|
+
else:
|
|
110
|
+
raise Exception(error)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def update_file_content(file_path, actual_value, expected_value):
|
|
114
|
+
with open(file_path, "r+") as f:
|
|
115
|
+
stream_data = f.read()
|
|
116
|
+
ret = re.sub(actual_value, expected_value, stream_data)
|
|
117
|
+
f.seek(0)
|
|
118
|
+
f.truncate()
|
|
119
|
+
f.write(ret)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_file_content(file_path):
|
|
123
|
+
with open(file_path, "r+") as f:
|
|
124
|
+
content = f.read()
|
|
125
|
+
|
|
126
|
+
return content
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def get_cli_command_structure(obj):
|
|
130
|
+
if isinstance(obj, click.Group):
|
|
131
|
+
return {name: get_cli_command_structure(value)
|
|
132
|
+
for name, value in obj.commands.items()}
|
s/tox.ini
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
[tox]
|
|
2
|
+
envlist = py36, py37, py38, py39
|
|
3
|
+
|
|
4
|
+
#[travis]
|
|
5
|
+
#python =
|
|
6
|
+
# 3.6: py36
|
|
7
|
+
|
|
8
|
+
#[testenv:flake8]
|
|
9
|
+
#basepython=python
|
|
10
|
+
#deps=flake8
|
|
11
|
+
#commands=flake8 iotedgedev
|
|
12
|
+
|
|
13
|
+
[testenv]
|
|
14
|
+
deps = -rrequirements_dev.txt
|
|
15
|
+
#setenv = PIP_EXTRA_INDEX_URL=https://test.pypi.org/simple/
|
|
16
|
+
commands = pytest -s -v {posargs}
|
|
17
|
+
#setenv =
|
|
18
|
+
# PYTHONPATH = {toxinidir}
|
|
19
|
+
|
|
20
|
+
#commands =
|
|
21
|
+
# python setup.py test
|
|
22
|
+
|
|
23
|
+
passenv = *
|
|
24
|
+
|
|
25
|
+
; If you want to make tox run the tests with the same versions, create a
|
|
26
|
+
; requirements.txt with the pinned versions and uncomment the following lines:
|
|
27
|
+
; deps =
|
|
28
|
+
; -r{toxinidir}/requirements.txt
|
|
29
|
+
|