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.
Files changed (356) hide show
  1. s/.devcontainer/Dockerfile +75 -0
  2. s/.devcontainer/devcontainer.json +40 -0
  3. s/.devcontainer/library-scripts/docker-in-docker-debian.sh +236 -0
  4. s/.env.tmp +108 -0
  5. s/.git/FETCH_HEAD +61 -0
  6. s/.git/HEAD +1 -0
  7. s/.git/config +12 -0
  8. s/.git/description +1 -0
  9. s/.git/hooks/applypatch-msg.sample +15 -0
  10. s/.git/hooks/commit-msg.sample +24 -0
  11. s/.git/hooks/fsmonitor-watchman.sample +173 -0
  12. s/.git/hooks/post-update.sample +8 -0
  13. s/.git/hooks/pre-applypatch.sample +14 -0
  14. s/.git/hooks/pre-commit.sample +49 -0
  15. s/.git/hooks/pre-merge-commit.sample +13 -0
  16. s/.git/hooks/pre-push.sample +53 -0
  17. s/.git/hooks/pre-rebase.sample +169 -0
  18. s/.git/hooks/pre-receive.sample +24 -0
  19. s/.git/hooks/prepare-commit-msg.sample +42 -0
  20. s/.git/hooks/push-to-checkout.sample +78 -0
  21. s/.git/hooks/update.sample +128 -0
  22. s/.git/index +0 -0
  23. s/.git/info/exclude +6 -0
  24. s/.git/logs/HEAD +1 -0
  25. s/.git/logs/refs/remotes/origin/EO +1 -0
  26. s/.git/logs/refs/remotes/origin/avagraw/security_fix +1 -0
  27. s/.git/logs/refs/remotes/origin/cherry-pick-rename +1 -0
  28. s/.git/logs/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
  29. s/.git/logs/refs/remotes/origin/chyuan/update-linux-agent +1 -0
  30. s/.git/logs/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
  31. s/.git/logs/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
  32. s/.git/logs/refs/remotes/origin/main +1 -0
  33. s/.git/logs/refs/remotes/origin/ray-deps +1 -0
  34. s/.git/logs/refs/remotes/origin/ray-dev-setup +1 -0
  35. s/.git/logs/refs/remotes/origin/ray-tox +1 -0
  36. s/.git/logs/refs/remotes/origin/release-pipeline-automation +1 -0
  37. s/.git/logs/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
  38. s/.git/logs/refs/remotes/origin/spmcdono/layered-deployments +1 -0
  39. s/.git/logs/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
  40. s/.git/logs/refs/remotes/origin/spmcdono/remove-py2 +1 -0
  41. s/.git/logs/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
  42. s/.git/logs/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
  43. s/.git/logs/refs/remotes/origin/spmcdono/update-pipeline +1 -0
  44. s/.git/logs/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
  45. s/.git/logs/refs/remotes/origin/user/marine/fixsimver +1 -0
  46. s/.git/logs/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
  47. s/.git/logs/refs/remotes/origin/user/marine/master-to-main +1 -0
  48. s/.git/logs/refs/remotes/origin/user/marine/pipeline +1 -0
  49. s/.git/logs/refs/remotes/origin/user/vikas +1 -0
  50. s/.git/logs/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
  51. s/.git/logs/refs/remotes/origin/user/vikas2 +1 -0
  52. s/.git/logs/refs/remotes/origin/user/vikas_pypi +1 -0
  53. s/.git/logs/refs/remotes/origin/user/vikas_pypi-1 +1 -0
  54. s/.git/logs/refs/remotes/origin/user/vikas_testing +1 -0
  55. s/.git/logs/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
  56. s/.git/logs/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
  57. s/.git/logs/refs/remotes/origin/vikas/azure +1 -0
  58. s/.git/logs/refs/remotes/origin/vikas/dependebot +1 -0
  59. s/.git/logs/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
  60. s/.git/logs/refs/remotes/origin/xinzed/update-runtime +1 -0
  61. s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.idx +0 -0
  62. s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.pack +0 -0
  63. s/.git/refs/remotes/origin/EO +1 -0
  64. s/.git/refs/remotes/origin/avagraw/security_fix +1 -0
  65. s/.git/refs/remotes/origin/cherry-pick-rename +1 -0
  66. s/.git/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
  67. s/.git/refs/remotes/origin/chyuan/update-linux-agent +1 -0
  68. s/.git/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
  69. s/.git/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
  70. s/.git/refs/remotes/origin/main +1 -0
  71. s/.git/refs/remotes/origin/ray-deps +1 -0
  72. s/.git/refs/remotes/origin/ray-dev-setup +1 -0
  73. s/.git/refs/remotes/origin/ray-tox +1 -0
  74. s/.git/refs/remotes/origin/release-pipeline-automation +1 -0
  75. s/.git/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
  76. s/.git/refs/remotes/origin/spmcdono/layered-deployments +1 -0
  77. s/.git/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
  78. s/.git/refs/remotes/origin/spmcdono/remove-py2 +1 -0
  79. s/.git/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
  80. s/.git/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
  81. s/.git/refs/remotes/origin/spmcdono/update-pipeline +1 -0
  82. s/.git/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
  83. s/.git/refs/remotes/origin/user/marine/fixsimver +1 -0
  84. s/.git/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
  85. s/.git/refs/remotes/origin/user/marine/master-to-main +1 -0
  86. s/.git/refs/remotes/origin/user/marine/pipeline +1 -0
  87. s/.git/refs/remotes/origin/user/vikas +1 -0
  88. s/.git/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
  89. s/.git/refs/remotes/origin/user/vikas2 +1 -0
  90. s/.git/refs/remotes/origin/user/vikas_pypi +1 -0
  91. s/.git/refs/remotes/origin/user/vikas_pypi-1 +1 -0
  92. s/.git/refs/remotes/origin/user/vikas_testing +1 -0
  93. s/.git/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
  94. s/.git/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
  95. s/.git/refs/remotes/origin/vikas/azure +1 -0
  96. s/.git/refs/remotes/origin/vikas/dependebot +1 -0
  97. s/.git/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
  98. s/.git/refs/remotes/origin/xinzed/update-runtime +1 -0
  99. s/.git/refs/tags/v0.49.0 +1 -0
  100. s/.git/refs/tags/v0.50.0 +1 -0
  101. s/.git/refs/tags/v0.51.0 +1 -0
  102. s/.git/refs/tags/v0.52.0 +1 -0
  103. s/.git/refs/tags/v0.53.0 +1 -0
  104. s/.git/refs/tags/v0.54.0 +1 -0
  105. s/.git/refs/tags/v0.55.0 +1 -0
  106. s/.git/refs/tags/v0.56.0 +1 -0
  107. s/.git/refs/tags/v0.57.0 +1 -0
  108. s/.git/refs/tags/v0.58.0 +1 -0
  109. s/.git/refs/tags/v0.59.0 +1 -0
  110. s/.git/refs/tags/v0.60.0 +1 -0
  111. s/.git/refs/tags/v0.61.0 +1 -0
  112. s/.git/refs/tags/v0.62.0 +1 -0
  113. s/.git/refs/tags/v0.63.0 +1 -0
  114. s/.git/refs/tags/v0.64.0 +1 -0
  115. s/.git/refs/tags/v0.65.0 +1 -0
  116. s/.git/refs/tags/v0.66.0 +1 -0
  117. s/.git/refs/tags/v0.67.0 +1 -0
  118. s/.git/refs/tags/v0.68.0 +1 -0
  119. s/.git/refs/tags/v0.69.0 +1 -0
  120. s/.git/refs/tags/v0.70.0 +1 -0
  121. s/.git/refs/tags/v0.71.0 +1 -0
  122. s/.git/refs/tags/v0.72.0 +1 -0
  123. s/.git/refs/tags/v0.73.0 +1 -0
  124. s/.git/refs/tags/v0.74.0 +1 -0
  125. s/.git/refs/tags/v0.75.0 +1 -0
  126. s/.git/refs/tags/v0.76.0 +1 -0
  127. s/.git/refs/tags/v0.77.0 +1 -0
  128. s/.git/refs/tags/v0.78.0 +1 -0
  129. s/.git/refs/tags/v0.79.0 +1 -0
  130. s/.git/refs/tags/v0.82.0 +1 -0
  131. s/.git/refs/tags/v0.82.0-container +1 -0
  132. s/.git/refs/tags/v1.0.0 +1 -0
  133. s/.git/refs/tags/v1.1.0 +1 -0
  134. s/.git/refs/tags/v1.2.0 +1 -0
  135. s/.git/refs/tags/v1.3.0 +1 -0
  136. s/.git/refs/tags/v2.0.0 +1 -0
  137. s/.git/refs/tags/v2.0.1 +1 -0
  138. s/.git/refs/tags/v2.0.2 +1 -0
  139. s/.git/refs/tags/v2.1.0 +1 -0
  140. s/.git/refs/tags/v2.1.1 +1 -0
  141. s/.git/refs/tags/v2.1.2 +1 -0
  142. s/.git/refs/tags/v2.1.3 +1 -0
  143. s/.git/refs/tags/v2.1.4 +1 -0
  144. s/.git/refs/tags/v2.1.6 +1 -0
  145. s/.git/refs/tags/v2.2.0 +1 -0
  146. s/.git/refs/tags/v3.0.0 +1 -0
  147. s/.git/refs/tags/v3.0.0-rc +1 -0
  148. s/.git/refs/tags/v3.1.0 +1 -0
  149. s/.git/refs/tags/v3.1.1 +1 -0
  150. s/.git/refs/tags/v3.1.2 +1 -0
  151. s/.git/refs/tags/v3.2.0 +1 -0
  152. s/.git/refs/tags/v3.2.0rc0 +1 -0
  153. s/.git/refs/tags/v3.3.0 +1 -0
  154. s/.git/refs/tags/v3.3.1 +1 -0
  155. s/.git/refs/tags/v3.3.2 +1 -0
  156. s/.git/refs/tags/v3.3.3 +1 -0
  157. s/.git/refs/tags/v3.3.3-rc0 +1 -0
  158. s/.git/refs/tags/v3.3.4 +1 -0
  159. s/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
  160. s/.github/ISSUE_TEMPLATE/feature_request.md +7 -0
  161. s/.github/workflows/wiki.yml +54 -0
  162. s/.gitignore +103 -0
  163. s/.vscode/launch.json +26 -0
  164. s/.vscode/settings.json +30 -0
  165. s/CHANGELOG.md +156 -0
  166. s/CODE_OF_CONDUCT.md +1 -0
  167. s/CONTRIBUTING.md +122 -0
  168. s/LICENSE +14 -0
  169. s/MANIFEST.in +7 -0
  170. s/Makefile +87 -0
  171. s/README.md +204 -0
  172. s/assets/armdeployment.png +0 -0
  173. s/assets/armoutputs.png +0 -0
  174. s/assets/deploy/ARMDeployment/ARMDeployment.deployproj +36 -0
  175. s/assets/deploy/ARMDeployment/Deploy-AzureResourceGroup.ps1 +118 -0
  176. s/assets/deploy/ARMDeployment/azuredeploy.json +145 -0
  177. s/assets/deploy/ARMDeployment/azuredeploy.parameters.json +6 -0
  178. s/assets/deploy/ARMDeployment.sln +25 -0
  179. s/assets/edgedevtool2mins.png +0 -0
  180. s/assets/edgedevtoolintro.png +0 -0
  181. s/assets/edgedevtoolquickstartlarge.png +0 -0
  182. s/assets/edgedevtoolquickstartsmall.png +0 -0
  183. s/assets/edgedevtoolwsl.png +0 -0
  184. s/azure-pipelines.yml +144 -0
  185. s/build/lib/iotedgedev/__init__.py +6 -0
  186. s/build/lib/iotedgedev/args.py +18 -0
  187. s/build/lib/iotedgedev/azurecli.py +542 -0
  188. s/build/lib/iotedgedev/buildoptionsparser.py +151 -0
  189. s/build/lib/iotedgedev/buildprofile.py +5 -0
  190. s/build/lib/iotedgedev/cli.py +830 -0
  191. s/build/lib/iotedgedev/connectionstring.py +58 -0
  192. s/build/lib/iotedgedev/constants.py +12 -0
  193. s/build/lib/iotedgedev/containerregistry.py +5 -0
  194. s/build/lib/iotedgedev/decorators.py +116 -0
  195. s/build/lib/iotedgedev/deploymentmanifest.py +313 -0
  196. s/build/lib/iotedgedev/dockercls.py +255 -0
  197. s/build/lib/iotedgedev/dotnet.py +31 -0
  198. s/build/lib/iotedgedev/edge.py +33 -0
  199. s/build/lib/iotedgedev/envvars.py +240 -0
  200. s/build/lib/iotedgedev/iothub.py +65 -0
  201. s/build/lib/iotedgedev/module.py +62 -0
  202. s/build/lib/iotedgedev/modules.py +332 -0
  203. s/build/lib/iotedgedev/organizedgroup.py +48 -0
  204. s/build/lib/iotedgedev/output.py +57 -0
  205. s/build/lib/iotedgedev/simulator.py +58 -0
  206. s/build/lib/iotedgedev/solution.py +48 -0
  207. s/build/lib/iotedgedev/telemetry.py +155 -0
  208. s/build/lib/iotedgedev/telemetryconfig.py +85 -0
  209. s/build/lib/iotedgedev/telemetryuploader.py +53 -0
  210. s/build/lib/iotedgedev/template/.env.tmp +87 -0
  211. s/build/lib/iotedgedev/template/.gitignore +10 -0
  212. s/build/lib/iotedgedev/template/deployment.template.json +79 -0
  213. s/build/lib/iotedgedev/template/launch_c.json +50 -0
  214. s/build/lib/iotedgedev/template/launch_csharp.json +43 -0
  215. s/build/lib/iotedgedev/template/launch_java.json +27 -0
  216. s/build/lib/iotedgedev/template/launch_node.json +36 -0
  217. s/build/lib/iotedgedev/template/launch_python.json +22 -0
  218. s/build/lib/iotedgedev/utility.py +179 -0
  219. s/build/lib/iotedgedev/version.py +4 -0
  220. s/build.sh +150 -0
  221. s/cleanup.sh +7 -0
  222. s/dist/iotedgedev-3.3.4-py3-none-any.whl +0 -0
  223. s/docker/tool/build-docker.sh +168 -0
  224. s/docker/tool/deps.txt +7 -0
  225. s/docker/tool/linux/Dockerfile +7 -0
  226. s/docker/tool/linux/Dockerfile.base +61 -0
  227. s/docker/tool/linux/install-dev.sh +8 -0
  228. s/docker/tool/linux/run.ps1 +5 -0
  229. s/docker/tool/linux/run.sh +5 -0
  230. s/docker/tool/push-docker.sh +35 -0
  231. s/docker/tool/windows/Dockerfile +4 -0
  232. s/docker/tool/windows/Dockerfile.base +63 -0
  233. s/docker/tool/windows/install-dev.bat +4 -0
  234. s/docker/tool/windows/run.ps1 +30 -0
  235. s/docs/Azure-Setup.md +102 -0
  236. s/docs/Command-List.md +564 -0
  237. s/docs/Command-Tips.md +51 -0
  238. s/docs/Edge-Device-Setup.md +23 -0
  239. s/docs/Home.md +10 -0
  240. s/docs/Manual-Dev-Machine-Setup.md +77 -0
  241. s/docs/Migration-Guides.md +131 -0
  242. s/docs/Overview.md +66 -0
  243. s/docs/Python-Virtual-Environment-Setup.md +35 -0
  244. s/docs/Quickstart-with-IoT-Edge-Dev-Container.md +145 -0
  245. s/docs/Test-Coverage.md +7 -0
  246. s/docs/Troubleshooting.md +21 -0
  247. s/docs/Usage.md +123 -0
  248. s/docs/_Sidebar.md +13 -0
  249. s/iotedgedev/__init__.py +6 -0
  250. s/iotedgedev/args.py +18 -0
  251. s/iotedgedev/azurecli.py +542 -0
  252. s/iotedgedev/buildoptionsparser.py +151 -0
  253. s/iotedgedev/buildprofile.py +5 -0
  254. s/iotedgedev/cli.py +830 -0
  255. s/iotedgedev/connectionstring.py +58 -0
  256. s/iotedgedev/constants.py +12 -0
  257. s/iotedgedev/containerregistry.py +5 -0
  258. s/iotedgedev/decorators.py +116 -0
  259. s/iotedgedev/deploymentmanifest.py +313 -0
  260. s/iotedgedev/dockercls.py +255 -0
  261. s/iotedgedev/dotnet.py +31 -0
  262. s/iotedgedev/edge.py +33 -0
  263. s/iotedgedev/envvars.py +240 -0
  264. s/iotedgedev/iothub.py +65 -0
  265. s/iotedgedev/module.py +62 -0
  266. s/iotedgedev/modules.py +332 -0
  267. s/iotedgedev/organizedgroup.py +48 -0
  268. s/iotedgedev/output.py +57 -0
  269. s/iotedgedev/simulator.py +58 -0
  270. s/iotedgedev/solution.py +48 -0
  271. s/iotedgedev/telemetry.py +155 -0
  272. s/iotedgedev/telemetryconfig.py +85 -0
  273. s/iotedgedev/telemetryuploader.py +53 -0
  274. s/iotedgedev/template/.env.tmp +87 -0
  275. s/iotedgedev/template/.gitignore +10 -0
  276. s/iotedgedev/template/deployment.template.json +79 -0
  277. s/iotedgedev/template/launch_c.json +50 -0
  278. s/iotedgedev/template/launch_csharp.json +43 -0
  279. s/iotedgedev/template/launch_java.json +27 -0
  280. s/iotedgedev/template/launch_node.json +36 -0
  281. s/iotedgedev/template/launch_python.json +22 -0
  282. s/iotedgedev/utility.py +179 -0
  283. s/iotedgedev/version.py +4 -0
  284. s/iotedgedev.egg-info/PKG-INFO +21 -0
  285. s/iotedgedev.egg-info/SOURCES.txt +100 -0
  286. s/iotedgedev.egg-info/dependency_links.txt +1 -0
  287. s/iotedgedev.egg-info/entry_points.txt +3 -0
  288. s/iotedgedev.egg-info/not-zip-safe +1 -0
  289. s/iotedgedev.egg-info/requires.txt +18 -0
  290. s/iotedgedev.egg-info/top_level.txt +1 -0
  291. s/pull_request_template.md +9 -0
  292. s/pytest.ini +4 -0
  293. s/requirements.txt +12 -0
  294. s/requirements_dev.txt +17 -0
  295. s/scripts/gen-help-markdown.bat +177 -0
  296. s/scripts/install-pip.sh +1 -0
  297. s/scripts/setup-wsl.sh +7 -0
  298. s/setup.cfg +18 -0
  299. s/setup.py +66 -0
  300. s/tests/__init__.py +5 -0
  301. s/tests/assets/deployment.manifest_invalid.json +106 -0
  302. s/tests/assets/deployment.manifest_invalid_createoptions.json +102 -0
  303. s/tests/assets/deployment.manifest_invalid_schema.json +69 -0
  304. s/tests/assets/deployment.template.non_str_placeholder.json +79 -0
  305. s/tests/assets/deployment.template_1.json +163 -0
  306. s/tests/assets/deployment.template_2.json +163 -0
  307. s/tests/assets/deployment.template_3.json +174 -0
  308. s/tests/assets/deployment.template_4.json +79 -0
  309. s/tests/assets/deployment.template_invalidresult.json +183 -0
  310. s/tests/assets/deployment.template_without_schema_template.json +99 -0
  311. s/tests/assets/launch.json +225 -0
  312. s/tests/assets/launch_without_nodejs.json +194 -0
  313. s/tests/assets/test_solution_shared_lib/.gitignore +2 -0
  314. s/tests/assets/test_solution_shared_lib/.vscode/launch.json +43 -0
  315. s/tests/assets/test_solution_shared_lib/deployment.debug.template.json +100 -0
  316. s/tests/assets/test_solution_shared_lib/deployment.escapedpath.template.json +90 -0
  317. s/tests/assets/test_solution_shared_lib/deployment.template.json +106 -0
  318. s/tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json +21 -0
  319. s/tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json +12 -0
  320. s/tests/assets/test_solution_shared_lib/libs/sharedlib/Class1.cs +12 -0
  321. s/tests/assets/test_solution_shared_lib/libs/sharedlib/sharedlib.csproj +7 -0
  322. s/tests/assets/test_solution_shared_lib/modules/non_module_project/placeholder.txt +0 -0
  323. s/tests/assets/test_solution_shared_lib/modules/sample_module/.gitignore +34 -0
  324. s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64 +18 -0
  325. s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64.debug +25 -0
  326. s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.windows-amd64 +15 -0
  327. s/tests/assets/test_solution_shared_lib/modules/sample_module/Program.cs +91 -0
  328. s/tests/assets/test_solution_shared_lib/modules/sample_module/module.json +18 -0
  329. s/tests/assets/test_solution_shared_lib/modules/sample_module/sample_module.csproj +26 -0
  330. s/tests/assets/test_solution_shared_lib/sample_module_2/.gitignore +34 -0
  331. s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64 +18 -0
  332. s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64.debug +25 -0
  333. s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.windows-amd64 +15 -0
  334. s/tests/assets/test_solution_shared_lib/sample_module_2/Program.cs +91 -0
  335. s/tests/assets/test_solution_shared_lib/sample_module_2/module.json +18 -0
  336. s/tests/assets/test_solution_shared_lib/sample_module_2/sample_module_2.csproj +26 -0
  337. s/tests/test_azurecli.py +33 -0
  338. s/tests/test_buildoptionsparser.py +155 -0
  339. s/tests/test_cli.py +55 -0
  340. s/tests/test_config.py +28 -0
  341. s/tests/test_connectionstring.py +87 -0
  342. s/tests/test_decorators.py +44 -0
  343. s/tests/test_deploymentmanifest.py +106 -0
  344. s/tests/test_envvars.py +169 -0
  345. s/tests/test_iotedgedev_iothub_deploy.py +199 -0
  346. s/tests/test_iotedgedev_simulator.py +133 -0
  347. s/tests/test_iotedgedev_solution.py +457 -0
  348. s/tests/test_iotedgedev_solution_build.py +246 -0
  349. s/tests/test_iotedgedev_solution_tag.py +99 -0
  350. s/tests/test_utility.py +132 -0
  351. s/tests/utility.py +132 -0
  352. s/tox.ini +29 -0
  353. s/vsts_ci/.vsts-ci.yml +93 -0
  354. s/vsts_ci/darwin/continuous-build-darwin.yml +54 -0
  355. s/vsts_ci/linux/continuous-build-linux.yml +28 -0
  356. s/vsts_ci/win32/continuous-build-win32.yml +26 -0
@@ -0,0 +1,169 @@
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
+
8
+ pytestmark = pytest.mark.unit
9
+
10
+
11
+ def test_get_envvar__valid():
12
+ envvars = EnvVars(Output())
13
+ deployment_template = envvars.get_envvar("DEPLOYMENT_CONFIG_TEMPLATE_FILE")
14
+ assert deployment_template is not None
15
+
16
+
17
+ def test_get_envvar__invalid():
18
+ envvars = EnvVars(Output())
19
+ testerval = envvars.get_envvar("TESTER")
20
+ assert not testerval
21
+
22
+
23
+ def test_load_valid():
24
+ envvars = EnvVars(Output())
25
+ envvars.load()
26
+ assert envvars.DEPLOYMENT_CONFIG_TEMPLATE_FILE == "deployment.template.json"
27
+
28
+
29
+ def test_verify_envvar_has_val__valid():
30
+ envvars = EnvVars(Output())
31
+ envvars.load()
32
+ result = envvars.verify_envvar_has_val("DEPLOYMENT_CONFIG_TEMPLATE_FILE", envvars.DEPLOYMENT_CONFIG_TEMPLATE_FILE)
33
+ assert not result
34
+
35
+
36
+ def test_get_envvar_key_if_val__valid():
37
+ envvars = EnvVars(Output())
38
+ assert envvars.get_envvar_key_if_val("DEPLOYMENT_CONFIG_TEMPLATE_FILE")
39
+
40
+
41
+ def test_get_envvar_key_if_val__invalid():
42
+ envvars = EnvVars(Output())
43
+ assert not envvars.get_envvar_key_if_val("TESTER")
44
+
45
+
46
+ def test_set_envvar():
47
+ envvars = EnvVars(Output())
48
+ registry_server = envvars.get_envvar("DEPLOYMENT_CONFIG_TEMPLATE_FILE")
49
+ envvars.set_envvar("DEPLOYMENT_CONFIG_TEMPLATE_FILE", "deployment.template_new.json")
50
+ new_registry_server = envvars.get_envvar("DEPLOYMENT_CONFIG_TEMPLATE_FILE")
51
+ assert new_registry_server == "deployment.template_new.json"
52
+ envvars.set_envvar("DEPLOYMENT_CONFIG_TEMPLATE_FILE", registry_server)
53
+
54
+
55
+ def test_envvar_clean():
56
+ EnvVars(Output())
57
+ envvar_clean_name = u"IOTEDGEDEV_ENVVAR_CLEAN_TEST"
58
+ os.environ[envvar_clean_name] = u"test unicode string"
59
+
60
+
61
+ @pytest.mark.parametrize(
62
+ "command, command_list",
63
+ [
64
+ ("solution new test_solution", ["init", "e2e", "solution new", "new", "simulator stop"]),
65
+ ("solution new", ["init", "e2e", "solution new", "new", "simulator stop"]),
66
+ ("", ["init", "e2e", "", "new", "simulator stop"]),
67
+ ]
68
+ )
69
+ def test_in_command_list_true(command, command_list):
70
+ envvars = EnvVars(Output())
71
+ assert envvars.in_command_list(command, command_list)
72
+
73
+
74
+ @pytest.mark.parametrize(
75
+ "command, command_list",
76
+ [
77
+ ("solution add filtermodule", ["init", "e2e", "solution new", "new", "simulator stop"]),
78
+ ("solution addotherstuff filtermodule", ["init", "e2e", "solution add", "new", "simulator stop"]),
79
+ ("", ["init", "e2e", "solution new", "new", "simulator stop"]),
80
+ ("solution new test_solution", ["init", "e2e", "", "new", "simulator stop"])
81
+ ]
82
+ )
83
+ def test_in_command_list_false(command, command_list):
84
+ envvars = EnvVars(Output())
85
+ assert not envvars.in_command_list(command, command_list)
86
+
87
+
88
+ @pytest.mark.parametrize(
89
+ "command",
90
+ [
91
+ "iothub setup --update-dotenv",
92
+ ""
93
+ ]
94
+ )
95
+ def test_is_terse_command_true(command):
96
+ envvars = EnvVars(Output())
97
+ assert envvars.is_terse_command(command)
98
+
99
+
100
+ def test_is_terse_command_false():
101
+ envvars = EnvVars(Output())
102
+ assert not envvars.is_terse_command("solution add")
103
+
104
+
105
+ def test_default_container_registry_server_key_exists():
106
+ envvars = EnvVars(Output())
107
+ envvars.load()
108
+ assert "CONTAINER_REGISTRY_SERVER" in os.environ
109
+
110
+
111
+ @pytest.mark.parametrize(
112
+ "envvar",
113
+ [
114
+ "CONTAINER_REGISTRY_SERVER",
115
+ "CONTAINER_REGISTRY_USERNAME",
116
+ "CONTAINER_REGISTRY_PASSWORD"
117
+
118
+ ]
119
+ )
120
+ def test_default_envvar_value_exists(envvar):
121
+ envvars = EnvVars(Output())
122
+ server = envvars.get_envvar(envvar)
123
+ assert server is not None
124
+
125
+
126
+ def test_container_registry_server_key_missing_sys_exit():
127
+ envvars = EnvVars(Output())
128
+ with pytest.raises(ValueError):
129
+ envvars.get_envvar("CONTAINER_REGISTRY_SERVER_UNITTEST", required=True)
130
+
131
+
132
+ @pytest.mark.parametrize(
133
+ "envvar",
134
+ [
135
+ "CONTAINER_REGISTRY_SERVER",
136
+ "CONTAINER_REGISTRY_USERNAME",
137
+ "CONTAINER_REGISTRY_PASSWORD"
138
+
139
+ ]
140
+ )
141
+ def test_unique_envvar_tokens(envvar):
142
+ unique = set()
143
+ envvar_lenght = len(envvar)
144
+ is_unique = True
145
+ envvars = EnvVars(Output())
146
+ envvars.load()
147
+ for key in os.environ:
148
+ if key.startswith(envvar):
149
+ token = key[envvar_lenght:]
150
+ if token not in unique:
151
+ unique.add(token)
152
+ else:
153
+ is_unique = False
154
+ assert is_unique
155
+
156
+
157
+ @mock.patch.dict(os.environ, {
158
+ "CONTAINER_REGISTRY_SERVER_UNITTEST": "unittest.azurecr.io",
159
+ "CONTAINER_REGISTRY_USERNAME_UNITTEST": "username",
160
+ "CONTAINER_REGISTRY_PASSWORD_UNITTEST": "password"
161
+ })
162
+ def test_additional_container_registry_map_is_set_from_environ():
163
+ envvars = EnvVars(Output())
164
+ envvars.load()
165
+ assert len(envvars.CONTAINER_REGISTRY_MAP) == 2
166
+ assert 'UNITTEST' in envvars.CONTAINER_REGISTRY_MAP.keys()
167
+ assert envvars.CONTAINER_REGISTRY_MAP['UNITTEST'].server == 'unittest.azurecr.io'
168
+ assert envvars.CONTAINER_REGISTRY_MAP['UNITTEST'].username == 'username'
169
+ assert envvars.CONTAINER_REGISTRY_MAP['UNITTEST'].password == 'password'
@@ -0,0 +1,199 @@
1
+ import os
2
+ import uuid
3
+ from unittest import mock
4
+
5
+ import pytest
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
+
11
+ from .utility import get_platform_type, runner_invoke
12
+
13
+ pytestmark = pytest.mark.e2e
14
+
15
+ output = Output()
16
+ envvars = EnvVars(output)
17
+ test_solution_shared_lib_dir = os.path.join(os.getcwd(), "tests", "assets", "test_solution_shared_lib")
18
+
19
+
20
+ @pytest.mark.parametrize(
21
+ "config, manifest",
22
+ [
23
+ ("layered_deployment.flattened_props.template.json", "layered_deployment.flattened_props.json"),
24
+ ("layered_deployment.no_modules.template.json", "layered_deployment.no_modules.json"),
25
+ ("deployment.template.json", f"deployment.{get_platform_type()}.json")
26
+ ]
27
+ )
28
+ # Test that cmd line target condition (-t) overrides target condition from .env
29
+ @ mock.patch.dict(os.environ, {"IOTHUB_DEPLOYMENT_TARGET_CONDITION": "invalid_target"})
30
+ def test_iothub_deploy(config, manifest):
31
+ # Arrange
32
+ deployment_name = f'test-{uuid.uuid4()}'
33
+ os.chdir(test_solution_shared_lib_dir)
34
+
35
+ # Act
36
+ result = runner_invoke(['build', '-f', config, '-P', get_platform_type()])
37
+ result = runner_invoke(['iothub', 'deploy',
38
+ '-f', f'config/{manifest}',
39
+ '-n', deployment_name,
40
+ '-p', '10',
41
+ '-t', "tags.environment='dev'"
42
+ ])
43
+
44
+ # Assert
45
+ assert 'DEPLOYMENT COMPLETE' in result.output
46
+ assert 'ERROR' not in result.output
47
+
48
+ # Cleanup
49
+ azure_cli = AzureCli(output, envvars)
50
+ assert azure_cli.invoke_az_cli_outproc(["iot", "edge", "deployment", "delete", "-d", deployment_name, "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING")])
51
+
52
+
53
+ @ mock.patch.dict(os.environ, {"IOTHUB_DEPLOYMENT_TARGET_CONDITION": "tags.environment='dev'"})
54
+ def test_iothub_deploy_with_target_group_set_from_dotenv():
55
+ # Arrange
56
+ deployment_name = f'test-layered{uuid.uuid4()}'
57
+ os.chdir(test_solution_shared_lib_dir)
58
+
59
+ # Act
60
+ result = runner_invoke(['build', '-f', "layered_deployment.flattened_props.template.json", '-P', get_platform_type()])
61
+ result = runner_invoke(['iothub', 'deploy',
62
+ '-f', 'config/layered_deployment.flattened_props.json',
63
+ '-n', deployment_name,
64
+ '-p', '10',
65
+ ])
66
+
67
+ # Assert
68
+ assert 'DEPLOYMENT COMPLETE' in result.output
69
+ assert 'ERROR' not in result.output
70
+
71
+ # Cleanup
72
+ azure_cli = AzureCli(output, envvars)
73
+
74
+ assert azure_cli.invoke_az_cli_outproc(["iot", "edge", "deployment", "delete", "-d", deployment_name, "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING")])
75
+
76
+
77
+ def test_iothub_deploy_error_from_az_cli_bubbled_up():
78
+ # Arrange
79
+ os.chdir(test_solution_shared_lib_dir)
80
+
81
+ # Act
82
+ result = runner_invoke(['build', '-f', "layered_deployment.flattened_props.template.json", '-P', get_platform_type()])
83
+ result = runner_invoke(['iothub', 'deploy',
84
+ '-f', 'config/layered_deployment.flattened_props.json',
85
+ '-n', "test-layered-deployment",
86
+ '-p', '10',
87
+ '-t', "invalid_target_group"
88
+ ])
89
+
90
+ # Assert
91
+ assert "ERROR: {'Message': 'ErrorCode:ArgumentInvalid;BadRequest'," in result.output
92
+
93
+
94
+ def test_iothub_deploy_error_missing_name():
95
+ # Act
96
+ with pytest.raises(Exception) as context:
97
+ runner_invoke(['iothub', 'deploy', '-n', "test"])
98
+
99
+ # Assert
100
+ assert "Error: Missing option '--priority' / '-p'." in str(context)
101
+
102
+
103
+ def test_iothub_deploy_error_missing_priority():
104
+ # Act
105
+ with pytest.raises(Exception) as context:
106
+ runner_invoke(['iothub', 'deploy', '-n', "test"])
107
+
108
+ # Assert
109
+ assert "Error: Missing option '--priority' / '-p'." in str(context)
110
+
111
+
112
+ def test_iothub_deploy_error_missing_target_condition():
113
+ # Act
114
+ with pytest.raises(Exception) as context:
115
+ runner_invoke(['iothub', 'deploy', '-n', "test", '-p', '10'])
116
+
117
+ # Assert
118
+ assert "ERROR: Environment Variable IOTHUB_DEPLOYMENT_TARGET_CONDITION not set. Either add to .env file or to your system's Environment Variables" in str(context.value)
119
+
120
+
121
+ def test_iothub_deploy_and_add_tags():
122
+ # Arrange
123
+ tags = '{"environment":"dev","building":"9"}'
124
+ deployment_name = f'test-{uuid.uuid4()}'
125
+ os.chdir(test_solution_shared_lib_dir)
126
+
127
+ # Act
128
+ result = runner_invoke(['build', '-f', "layered_deployment.flattened_props.template.json", '-P', get_platform_type()])
129
+ result = runner_invoke(['iothub', 'deploy',
130
+ '-f', 'config/layered_deployment.flattened_props.json',
131
+ '-n', deployment_name,
132
+ '-p', '10',
133
+ '-t', "tags.environment='dev'",
134
+ '-dt', tags
135
+ ])
136
+
137
+ # Assert
138
+ assert 'DEPLOYMENT COMPLETE' in result.output
139
+ assert 'TAG UPDATE COMPLETE' in result.output
140
+ assert tags in result.output
141
+ assert 'ERROR' not in result.output
142
+
143
+ # Cleanup
144
+ azure_cli = AzureCli(output, envvars)
145
+
146
+ assert azure_cli.invoke_az_cli_outproc(["iot", "edge", "deployment", "delete", "-d", deployment_name, "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING")])
147
+ assert azure_cli.invoke_az_cli_outproc(["iot", "hub", "device-twin", "replace", "-d", DeviceConnectionString(envvars.get_envvar("DEVICE_CONNECTION_STRING")).device_id,
148
+ "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING"), "--json", "{}"])
149
+
150
+
151
+ def test_iothub_deploy_and_add_tags_retry_after_invalid_tag():
152
+ # GIVEN: `iothub deploy` run fails
153
+ # WHEN: Device tag has an invalid format
154
+ # THEN: Rerunning the command will lead to a failed deploy part,
155
+ # as the deployment already exists from the previous run,
156
+ # but it will succeed in adding the new and correct device tags.
157
+ # Leaving the iothub and device in the initially desired end state again.
158
+
159
+ # Arrange
160
+ tags1 = 'invalid_tag'
161
+ tags2 = '{"environment":"dev","building":"9"}'
162
+ deployment_name = f'test-{uuid.uuid4()}'
163
+ os.chdir(test_solution_shared_lib_dir)
164
+
165
+ # Act
166
+ result = runner_invoke(['build', '-f', "layered_deployment.flattened_props.template.json", '-P', get_platform_type()])
167
+ result = runner_invoke(['iothub', 'deploy',
168
+ '-f', 'config/layered_deployment.flattened_props.json',
169
+ '-n', deployment_name,
170
+ '-p', '10',
171
+ '-t', "tags.environment='dev'",
172
+ '-dt', tags1
173
+ ])
174
+
175
+ result_retry = runner_invoke(['iothub', 'deploy',
176
+ '-f', 'config/layered_deployment.flattened_props.json',
177
+ '-n', deployment_name,
178
+ '-p', '10',
179
+ '-t', "tags.environment='dev'",
180
+ '-dt', tags2
181
+ ])
182
+
183
+ # Assert
184
+ assert 'DEPLOYMENT COMPLETE' in result.output
185
+ assert 'TAG UPDATE COMPLETE' not in result.output
186
+ assert f"ERROR: Failed to add tag: '{tags1}' to device" in result.output
187
+
188
+ assert 'DEPLOYMENT COMPLETE' not in result_retry.output
189
+ assert 'TAG UPDATE COMPLETE' in result_retry.output
190
+ assert tags2 in result_retry.output
191
+ assert 'ERROR: Failed to deploy' in result_retry.output
192
+ assert f'Message\': "ErrorCode:ConfigurationAlreadyExists;Configuration with id \'{deployment_name}\' already exist on IotHub.' in result_retry.output
193
+
194
+ # Cleanup
195
+ azure_cli = AzureCli(output, envvars)
196
+
197
+ assert azure_cli.invoke_az_cli_outproc(["iot", "edge", "deployment", "delete", "-d", deployment_name, "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING")])
198
+ assert azure_cli.invoke_az_cli_outproc(["iot", "hub", "device-twin", "replace", "-d", DeviceConnectionString(envvars.get_envvar("DEVICE_CONNECTION_STRING")).device_id,
199
+ "-l", envvars.get_envvar("IOTHUB_CONNECTION_STRING"), "--json", "{}"])
@@ -0,0 +1,133 @@
1
+ import os
2
+ import pytest
3
+ import shutil
4
+ import time
5
+
6
+ from iotedgedev.version import PY35
7
+ from iotedgedev.envvars import EnvVars
8
+ from iotedgedev.output import Output
9
+
10
+ from .utility import get_docker_os_type
11
+ from .utility import get_platform_type
12
+ from .utility import runner_invoke
13
+
14
+ pytestmark = pytest.mark.e2e
15
+
16
+ output = Output()
17
+ envvars = EnvVars(output)
18
+
19
+ env_file_name = envvars.get_dotenv_file()
20
+ env_file_path = envvars.get_dotenv_path(env_file_name)
21
+
22
+ root_dir = os.getcwd()
23
+ tests_dir = os.path.join(root_dir, 'tests')
24
+
25
+ test_solution = 'test_solution'
26
+ test_solution_dir = os.path.join(tests_dir, test_solution)
27
+
28
+
29
+ @pytest.fixture(scope="module", autouse=True)
30
+ def create_solution(request):
31
+ os.chdir(tests_dir)
32
+ result = runner_invoke(['solution', 'new', test_solution])
33
+
34
+ assert 'AZURE IOT EDGE SOLUTION CREATED' in result.output
35
+
36
+ shutil.copyfile(env_file_path, os.path.join(test_solution_dir, env_file_name))
37
+ os.chdir(test_solution_dir)
38
+
39
+ def clean():
40
+ os.chdir(root_dir)
41
+ time.sleep(5)
42
+ shutil.rmtree(test_solution_dir, ignore_errors=True)
43
+ shutil.rmtree(test_solution_dir+"_shared_lib", ignore_errors=True)
44
+ runner_invoke(['simulator', 'stop'])
45
+
46
+ request.addfinalizer(clean)
47
+
48
+ return
49
+
50
+
51
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
52
+ def test_setup():
53
+ result = runner_invoke(['simulator', 'setup'])
54
+
55
+ assert 'Setup IoT Edge Simulator successfully.' in result.output
56
+
57
+
58
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
59
+ def test_setup_with_iothub():
60
+ result = runner_invoke(['simulator', 'setup', '-i', os.getenv("IOTHUB_CONNECTION_STRING")])
61
+
62
+ assert 'Setup IoT Edge Simulator successfully.' in result.output
63
+
64
+
65
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
66
+ def test_start_single():
67
+ result = runner_invoke(['simulator', 'start', '-i', 'input1'])
68
+
69
+ assert 'IoT Edge Simulator has been started in single module mode.' in result.output
70
+
71
+
72
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
73
+ def test_modulecred():
74
+ result = runner_invoke(['simulator', 'modulecred'])
75
+
76
+ assert 'EdgeHubConnectionString=HostName=' in result.output
77
+ assert 'EdgeModuleCACertificateFile=' in result.output
78
+
79
+
80
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
81
+ def test_stop(capfd):
82
+ runner_invoke(['simulator', 'stop'])
83
+ out, err = capfd.readouterr()
84
+
85
+ assert 'IoT Edge Simulator has been stopped successfully.' in out
86
+
87
+
88
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
89
+ def test_start_solution(capfd):
90
+ result = runner_invoke(['simulator', 'start', '-s', '-b', '-f', 'deployment.template.json'])
91
+ out, err = capfd.readouterr()
92
+
93
+ assert 'BUILD COMPLETE' in result.output
94
+ assert 'IoT Edge Simulator has been started in solution mode.' in out
95
+
96
+
97
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
98
+ def test_start_solution_with_setup(capfd):
99
+ result = runner_invoke(['simulator', 'start', '--setup', '-s', '-b', '-f', 'deployment.template.json'])
100
+ out, err = capfd.readouterr()
101
+
102
+ assert 'Setup IoT Edge Simulator successfully.' in result.output
103
+ assert 'BUILD COMPLETE' in result.output
104
+ assert 'IoT Edge Simulator has been started in solution mode.' in out
105
+
106
+
107
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
108
+ def test_monitor(capfd):
109
+ try:
110
+ result = runner_invoke(['monitor', '--timeout', '30'])
111
+ out, err = capfd.readouterr()
112
+ # Assert output from simulator
113
+ sim_match = 'timeCreated'
114
+
115
+ if not PY35:
116
+ assert 'Monitoring events from device' in out
117
+ assert sim_match in out
118
+ else:
119
+ assert not err
120
+ assert sim_match in result.output
121
+ finally:
122
+ test_stop(capfd)
123
+
124
+
125
+ @pytest.mark.skipif(get_docker_os_type() == 'windows', reason='Simulator does not support windows container')
126
+ def test_start_solution_with_deployment(capfd):
127
+ platform_type = get_platform_type()
128
+ deployment_file_path = os.path.join(test_solution_dir, 'config', 'deployment.' + platform_type + '.json')
129
+ runner_invoke(['simulator', 'start', '-f', deployment_file_path])
130
+ out, err = capfd.readouterr()
131
+
132
+ assert 'IoT Edge Simulator has been started in solution mode.' in out
133
+ test_monitor(capfd)