neoload 1.3.19.dev1__tar.gz → 1.3.19.dev2__tar.gz

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 (215) hide show
  1. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/PKG-INFO +55 -1
  2. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/README.md +54 -0
  3. neoload-1.3.19.dev2/examples/as-code-demo/default.yaml +140 -0
  4. neoload-1.3.19.dev2/neoload/commands/__init__.py +2 -0
  5. neoload-1.3.19.dev2/neoload/commands/checkvu.py +98 -0
  6. neoload-1.3.19.dev2/neoload/commands/validate.py +19 -0
  7. neoload-1.3.19.dev2/neoload/neoload_cli_lib/checkvu_runner.py +189 -0
  8. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/schema_validation.py +18 -0
  9. neoload-1.3.19.dev2/neoload/version.py +1 -0
  10. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/PKG-INFO +55 -1
  11. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/SOURCES.txt +4 -0
  12. neoload-1.3.19.dev2/tests/commands/test_checkvu.py +207 -0
  13. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_validate.py +25 -0
  14. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/conftest.py +2 -1
  15. neoload-1.3.19.dev1/neoload/commands/__init__.py +0 -2
  16. neoload-1.3.19.dev1/neoload/commands/validate.py +0 -29
  17. neoload-1.3.19.dev1/neoload/version.py +0 -1
  18. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.github/workflows/python-integration-tests.yml +0 -0
  19. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.github/workflows/python-package.yml +0 -0
  20. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.github/workflows/python-post-release-changelog-pr.yml +0 -0
  21. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.github/workflows/python-release.yml +0 -0
  22. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.gitignore +0 -0
  23. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/.travis.yml +0 -0
  24. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/CHANGELOG.md +0 -0
  25. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/LICENSE +0 -0
  26. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/MANIFEST.in +0 -0
  27. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/docker/Dockerfile +0 -0
  28. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/aws/.nlignore +0 -0
  29. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/aws/buildspec.yaml +0 -0
  30. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/.nlignore +0 -0
  31. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/Azure_DevOps_Pipeline_NeoLoad_CLI.jpg +0 -0
  32. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/Azure_DevOps_Pipeline_NeoLoad_SLA_jUnit.jpg +0 -0
  33. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/README.md +0 -0
  34. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/neoload-cli-docker.yml +0 -0
  35. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/azure_devops/neoload-cli-dyninfra.yml +0 -0
  36. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/bamboo-specs/.nlignore +0 -0
  37. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/bamboo-specs/Bamboo_Pipeline_NeoLoad_SLA_jUnit.jpg +0 -0
  38. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/bamboo-specs/README.md +0 -0
  39. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/bamboo-specs/bamboo-v1.yaml +0 -0
  40. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/bamboo-specs/bamboo-v2.yaml +0 -0
  41. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/github/neoload-github-actions-demo.yml +0 -0
  42. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/gitlab/.nlignore +0 -0
  43. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/gitlab/openshift.gitlab-ci.yml +0 -0
  44. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/jenkins/Jenkinsfile_dyninfra +0 -0
  45. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/examples/pipelines/jenkins/Jenkinsfile_slafails +0 -0
  46. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/__init__.py +0 -0
  47. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/__main__.py +0 -0
  48. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/config.py +0 -0
  49. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/docker.py +0 -0
  50. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/fastfail.py +0 -0
  51. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/login.py +0 -0
  52. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/logout.py +0 -0
  53. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/logs.py +0 -0
  54. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/logs_url.py +0 -0
  55. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/project.py +0 -0
  56. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/report.py +0 -0
  57. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/run.py +0 -0
  58. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/status.py +0 -0
  59. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/stop.py +0 -0
  60. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/test_results.py +0 -0
  61. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/test_settings.py +0 -0
  62. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/wait.py +0 -0
  63. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/workspaces.py +0 -0
  64. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/commands/zones.py +0 -0
  65. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/__init__.py +0 -0
  66. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/bad_as_code_exception.py +0 -0
  67. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/cli_exception.py +0 -0
  68. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/config_global.py +0 -0
  69. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/displayer.py +0 -0
  70. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/docker_lib.py +0 -0
  71. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/filtering.py +0 -0
  72. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/hooks.py +0 -0
  73. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/logs_tools.py +0 -0
  74. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/logs_traduction_map.py +0 -0
  75. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/name_resolver.py +0 -0
  76. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/neoLoad_project.py +0 -0
  77. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/paths.py +0 -0
  78. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/rest_crud.py +0 -0
  79. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/running_tools.py +0 -0
  80. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/tools.py +0 -0
  81. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/neoload_cli_lib/user_data.py +0 -0
  82. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/__init__.py +0 -0
  83. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/__init__.py +0 -0
  84. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/builtin_console_summary.j2 +0 -0
  85. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/builtin_transactions_csv.j2 +0 -0
  86. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/common.js +0 -0
  87. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/external_data.html.j2 +0 -0
  88. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/general_details.html.j2 +0 -0
  89. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/header.j2 +0 -0
  90. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/hits_per_second.html.j2 +0 -0
  91. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/running_vus.html.j2 +0 -0
  92. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/styles.css +0 -0
  93. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/transactions.html.j2 +0 -0
  94. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/common/workload_characteristics.html.j2 +0 -0
  95. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/custom_transactions_export.j2 +0 -0
  96. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/sample-custom-report.html.j2 +0 -0
  97. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/sample-trends-report.html.j2 +0 -0
  98. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/trends/general_details.html.j2 +0 -0
  99. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/trends/transaction_trends.html.j2 +0 -0
  100. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/resources/jinja/trends/trends.js +0 -0
  101. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload/version_manager.py +0 -0
  102. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/dependency_links.txt +0 -0
  103. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/entry_points.txt +0 -0
  104. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/requires.txt +0 -0
  105. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/neoload.egg-info/top_level.txt +0 -0
  106. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/notes/PSB_20200421_TODO.txt +0 -0
  107. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/notes/acceptance.txt +0 -0
  108. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/pull_request_template.md +0 -0
  109. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/pytest.ini +0 -0
  110. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/requirements.txt +0 -0
  111. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/resources/as-code.latest.schema.json +0 -0
  112. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/setup.cfg +0 -0
  113. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/setup.py +0 -0
  114. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/sonar-project.properties +0 -0
  115. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/__init__.py +0 -0
  116. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/docker/test_docker_cleanups.py +0 -0
  117. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/docker/test_docker_connections.py +0 -0
  118. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/docker/test_docker_hooks.py +0 -0
  119. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/fastfail/test_fastfail_slas.py +0 -0
  120. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/project/test_upload.py +0 -0
  121. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/project/test_upload_with_password.py +0 -0
  122. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/conftest.py +0 -0
  123. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_report.py +0 -0
  124. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_report_json_output.py +0 -0
  125. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_report_templates.py +0 -0
  126. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_report_transactions.py +0 -0
  127. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_report_trends.py +0 -0
  128. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_trends_json_output.py +0 -0
  129. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/report/test_trends_templates.py +0 -0
  130. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/status/test_status_with_names.py +0 -0
  131. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_config.py +0 -0
  132. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_login.py +0 -0
  133. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_logout.py +0 -0
  134. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_logs/test_logs.py +0 -0
  135. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_logs_url.py +0 -0
  136. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_results/test_result_delete.py +0 -0
  137. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_results/test_result_ls.py +0 -0
  138. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_results/test_result_patch.py +0 -0
  139. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_results/test_result_put.py +0 -0
  140. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_run.py +0 -0
  141. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_create.py +0 -0
  142. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_createorpatch.py +0 -0
  143. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_delete.py +0 -0
  144. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_ls.py +0 -0
  145. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_patch.py +0 -0
  146. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/test_settings/test_put.py +0 -0
  147. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/wait/test_wait.py +0 -0
  148. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/workspaces/test_workspace_ls.py +0 -0
  149. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/workspaces/test_workspace_use.py +0 -0
  150. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/commands/zones/test_zones.py +0 -0
  151. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/helpers/__init__.py +0 -0
  152. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/helpers/test_utils.py +0 -0
  153. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/expected/fastfail.log +0 -0
  154. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/expected/junit-sla.xml +0 -0
  155. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/expected/run.log +0 -0
  156. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/expected/summary.txt +0 -0
  157. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/runAllScripts.sh +0 -0
  158. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/cleanup.sh +0 -0
  159. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/project.upload.test.sh +0 -0
  160. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/results.delete.test.sh +0 -0
  161. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/results.patch.test.sh +0 -0
  162. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/results.put.test.sh +0 -0
  163. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/run.fastfail.test.sh +0 -0
  164. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/run.oneliner.test.sh +0 -0
  165. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/run.test.sh +0 -0
  166. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/settings.create.delete.test.sh +0 -0
  167. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/settings.patch.test.sh +0 -0
  168. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/settings.put.test.sh +0 -0
  169. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/validate.test.sh +0 -0
  170. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/wait.test.sh +0 -0
  171. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/integration/scripts/zones.ls.test.sh +0 -0
  172. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_SchemaValidation.py +0 -0
  173. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_displayer.py +0 -0
  174. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_docker.py +0 -0
  175. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_etag_caching.py +0 -0
  176. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_filtering.py +0 -0
  177. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_include_resolution.py +0 -0
  178. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_rest_crud.py +0 -0
  179. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_running_tools.py +0 -0
  180. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_tools.py +0 -0
  181. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_user_data.py +0 -0
  182. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_cli_lib/test_validator_selection.py +0 -0
  183. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/.nlignore +0 -0
  184. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/broken_yaml.yaml +0 -0
  185. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/circular_includes/a.yaml +0 -0
  186. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/circular_includes/b.yaml +0 -0
  187. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/empty.yaml +0 -0
  188. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/.gitlab-ci.yml +0 -0
  189. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/.nlignore +0 -0
  190. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/data/cities.csv +0 -0
  191. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/default.yaml +0 -0
  192. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/paths/geosearch_get.yaml +0 -0
  193. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/slas/prod.yaml +0 -0
  194. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1/slas/uat.yaml +0 -0
  195. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_1.zip +0 -0
  196. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/example_2.zip +0 -0
  197. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/invalid_to_schema.yaml +0 -0
  198. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/neoload_projects/simpledemo.yml +0 -0
  199. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/__init__.py +0 -0
  200. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/expected_neoload_junit_slas.xml +0 -0
  201. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/expected_summary_text_no_sla.txt +0 -0
  202. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/expected_summary_text_with_sla.txt +0 -0
  203. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/jinja/__init__.py +0 -0
  204. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_custom_report.html +0 -0
  205. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_custom_report_filtered.html +0 -0
  206. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_custom_transactions.csv +0 -0
  207. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_report.json +0 -0
  208. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_report_filtered.json +0 -0
  209. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_template_transactions.json +0 -0
  210. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_template_transactions_csv.csv +0 -0
  211. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_template_trends.html +0 -0
  212. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/expected_trends.json +0 -0
  213. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/raw_expected_custom_report.html +0 -0
  214. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/resources/report/raw_expected_report.json +0 -0
  215. {neoload-1.3.19.dev1 → neoload-1.3.19.dev2}/tests/test_readme.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neoload
3
- Version: 1.3.19.dev1
3
+ Version: 1.3.19.dev2
4
4
  Summary: A command-line native utility for launching and observing NeoLoad performance tests
5
5
  Home-page: https://github.com/Neotys-Labs/neoload-cli
6
6
  Author: Neotys
@@ -86,6 +86,8 @@ NOTE: On the Windows command line, replace the `\` line-continuation characters
86
86
  - [Exporting Transaction CSV data](#exporting-transaction-csv-data)
87
87
  - [View zones](#view-zones)
88
88
  - [Create local Docker infrastructure to run a test](#create-local-docker-infrastructure-to-run-a-test)
89
+ - [Examples](#examples)
90
+ - [As-Code Demo Project](#as-code-demo-project)
89
91
  - [Continuous Testing Examples](#continuous-testing-examples)
90
92
  - [Support for fast-fail based on SLAs](#support-for-fast-fail-based-on-slas)
91
93
  - [Packaging the CLI with Build Agents](#packaging-the-cli-with-build-agents)
@@ -213,6 +215,24 @@ Pressing `Ctrl+C` causes the CLI to attempt to stop the test gracefully.
213
215
  neoload stop # Sends the stop signal to the test and waits until it ends.
214
216
  ```
215
217
 
218
+ ## CheckVU an as-code project
219
+ This command runs a CheckVU on an as-code project: it executes a single virtual user to verify that the project runs. It is meant to support fast iteration on as-code projects (generate -> checkvu -> fix).
220
+
221
+ It delegates to a standalone headless CheckVU JAR and streams the JAR's output and exit code directly.
222
+
223
+ ```
224
+ Usage: neoload checkvu [OPTIONS] PROJECT_FILE
225
+ Help: neoload checkvu --help
226
+ neoload checkvu default.yaml
227
+ neoload checkvu -u myUser default.yaml
228
+ ```
229
+ - `PROJECT_FILE` is a path to an as-code yaml file. The CLI validates it against the as-code schema first (same as `neoload validate`), using `-s, --as-code-schema` to override the default schema.
230
+ - `-e, --engine-jar <path-or-url>` resolves the CheckVU JAR: a local file path or a download URL. If omitted, a previously cached JAR is reused, otherwise a default URL is used to download the latest JAR.
231
+ - `-j, --java` selects the java executable; by default `JAVA_HOME/bin/java` then `java` on the PATH. Java 21+ is required and verified before running.
232
+ - `-w, --work-dir <path>` sets the directory used for engine files and logs. Defaults to a temporary directory deleted afterwards unless `--keep-temp-work-dir` is set; a directory you supply yourself is never deleted.
233
+ - `--app-proxy`, `--app-proxy-username` and `--app-proxy-bypass` configure the proxy used for application traffic. The proxy password is set with `NEOLOAD_CHECK_VU_APP_PROXY_PASSWORD` environment variable instead so it never shows up in the process list or CI logs.
234
+ - `--controller-properties` and `--load-generator-properties` are advanced options to merge a `.properties` file into the JAR's embedded `controller.properties` / `agent.properties`.
235
+
216
236
  ## Reporting
217
237
 
218
238
  The NeoLoad CLI provides basic support for viewing and exporting test results.
@@ -394,6 +414,40 @@ Help: neoload config --help
394
414
  ```
395
415
  The configuration lets you customize the CLI's behavior. For now, it is only used by the `docker` command (see above).
396
416
 
417
+ ## Examples
418
+
419
+ ### As-Code Demo Project
420
+
421
+ [`examples/as-code-demo`](examples/as-code-demo) contains a NeoLoad As-Code YAML project that works out-of-the-box:
422
+ no NeoLoad Web project, no manual scenario setup - just point NeoLoad at
423
+ [`default.yaml`](examples/as-code-demo/default.yaml) and run.
424
+
425
+ Target: [Tricentis Demo Web Shop](https://demowebshop.tricentis.com/) (nopCommerce demo).
426
+
427
+ The `BuyAsGuest` user path walks through a typical guest purchase:
428
+
429
+ 1. Open the shop home page
430
+ 2. Browse a product category
431
+ 3. Add a product to the cart (quantity randomised per iteration via a variable)
432
+ 4. View the cart
433
+ 5. Check out as a guest
434
+ 6. View product details
435
+
436
+ It uses two variables (`product_id`, `quantity`) and a single population (`GuestShoppers`)
437
+
438
+ Run CheckVU against the project:
439
+ ```
440
+ neoload checkvu examples/as-code-demo/default.yaml
441
+ ```
442
+
443
+ Run the full test:
444
+ ```
445
+ neoload login $NLW_TOKEN \
446
+ test-settings --zone defaultzone --lgs 1 createorpatch DemoWebShopTest \
447
+ project --path examples/as-code-demo/default.yaml upload DemoWebShopTest \
448
+ run --scenario DemoWebShop
449
+ ```
450
+
397
451
  ## Continuous Testing Examples
398
452
  The main goal of the NeoLoad CLI is to standardize how load tests are executed across development, non-prod, and production environments.
399
453
  The instructions above can be run from a contributor workstation, but they can also be easily translated to various continuous build and deployment platforms. Examples are provided for:
@@ -47,6 +47,8 @@ NOTE: On the Windows command line, replace the `\` line-continuation characters
47
47
  - [Exporting Transaction CSV data](#exporting-transaction-csv-data)
48
48
  - [View zones](#view-zones)
49
49
  - [Create local Docker infrastructure to run a test](#create-local-docker-infrastructure-to-run-a-test)
50
+ - [Examples](#examples)
51
+ - [As-Code Demo Project](#as-code-demo-project)
50
52
  - [Continuous Testing Examples](#continuous-testing-examples)
51
53
  - [Support for fast-fail based on SLAs](#support-for-fast-fail-based-on-slas)
52
54
  - [Packaging the CLI with Build Agents](#packaging-the-cli-with-build-agents)
@@ -174,6 +176,24 @@ Pressing `Ctrl+C` causes the CLI to attempt to stop the test gracefully.
174
176
  neoload stop # Sends the stop signal to the test and waits until it ends.
175
177
  ```
176
178
 
179
+ ## CheckVU an as-code project
180
+ This command runs a CheckVU on an as-code project: it executes a single virtual user to verify that the project runs. It is meant to support fast iteration on as-code projects (generate -> checkvu -> fix).
181
+
182
+ It delegates to a standalone headless CheckVU JAR and streams the JAR's output and exit code directly.
183
+
184
+ ```
185
+ Usage: neoload checkvu [OPTIONS] PROJECT_FILE
186
+ Help: neoload checkvu --help
187
+ neoload checkvu default.yaml
188
+ neoload checkvu -u myUser default.yaml
189
+ ```
190
+ - `PROJECT_FILE` is a path to an as-code yaml file. The CLI validates it against the as-code schema first (same as `neoload validate`), using `-s, --as-code-schema` to override the default schema.
191
+ - `-e, --engine-jar <path-or-url>` resolves the CheckVU JAR: a local file path or a download URL. If omitted, a previously cached JAR is reused, otherwise a default URL is used to download the latest JAR.
192
+ - `-j, --java` selects the java executable; by default `JAVA_HOME/bin/java` then `java` on the PATH. Java 21+ is required and verified before running.
193
+ - `-w, --work-dir <path>` sets the directory used for engine files and logs. Defaults to a temporary directory deleted afterwards unless `--keep-temp-work-dir` is set; a directory you supply yourself is never deleted.
194
+ - `--app-proxy`, `--app-proxy-username` and `--app-proxy-bypass` configure the proxy used for application traffic. The proxy password is set with `NEOLOAD_CHECK_VU_APP_PROXY_PASSWORD` environment variable instead so it never shows up in the process list or CI logs.
195
+ - `--controller-properties` and `--load-generator-properties` are advanced options to merge a `.properties` file into the JAR's embedded `controller.properties` / `agent.properties`.
196
+
177
197
  ## Reporting
178
198
 
179
199
  The NeoLoad CLI provides basic support for viewing and exporting test results.
@@ -355,6 +375,40 @@ Help: neoload config --help
355
375
  ```
356
376
  The configuration lets you customize the CLI's behavior. For now, it is only used by the `docker` command (see above).
357
377
 
378
+ ## Examples
379
+
380
+ ### As-Code Demo Project
381
+
382
+ [`examples/as-code-demo`](examples/as-code-demo) contains a NeoLoad As-Code YAML project that works out-of-the-box:
383
+ no NeoLoad Web project, no manual scenario setup - just point NeoLoad at
384
+ [`default.yaml`](examples/as-code-demo/default.yaml) and run.
385
+
386
+ Target: [Tricentis Demo Web Shop](https://demowebshop.tricentis.com/) (nopCommerce demo).
387
+
388
+ The `BuyAsGuest` user path walks through a typical guest purchase:
389
+
390
+ 1. Open the shop home page
391
+ 2. Browse a product category
392
+ 3. Add a product to the cart (quantity randomised per iteration via a variable)
393
+ 4. View the cart
394
+ 5. Check out as a guest
395
+ 6. View product details
396
+
397
+ It uses two variables (`product_id`, `quantity`) and a single population (`GuestShoppers`)
398
+
399
+ Run CheckVU against the project:
400
+ ```
401
+ neoload checkvu examples/as-code-demo/default.yaml
402
+ ```
403
+
404
+ Run the full test:
405
+ ```
406
+ neoload login $NLW_TOKEN \
407
+ test-settings --zone defaultzone --lgs 1 createorpatch DemoWebShopTest \
408
+ project --path examples/as-code-demo/default.yaml upload DemoWebShopTest \
409
+ run --scenario DemoWebShop
410
+ ```
411
+
358
412
  ## Continuous Testing Examples
359
413
  The main goal of the NeoLoad CLI is to standardize how load tests are executed across development, non-prod, and production environments.
360
414
  The instructions above can be run from a contributor workstation, but they can also be easily translated to various continuous build and deployment platforms. Examples are provided for:
@@ -0,0 +1,140 @@
1
+ # =============================================================================
2
+ # NeoLoad As-Code demo project - Tricentis Demo Web Shop
3
+ # -----------------------------------------------------------------------------
4
+ # Target : https://demowebshop.tricentis.com/ (nopCommerce demo)
5
+ # Scenario: add a product to the cart -> checkout as guest -> view details
6
+ #
7
+ # Out-of-the-box usage (from the repo root, via neoload-cli):
8
+ # Run CheckVU against the project:
9
+ # neoload checkvu examples/as-code-demo/default.yaml
10
+ # Run the full test:
11
+ # neoload login $NLW_TOKEN \
12
+ # test-settings --zone defaultzone --lgs 1 createorpatch DemoWebShopTest \
13
+ # project --path examples/as-code-demo/default.yaml upload DemoWebShopTest \
14
+ # run --scenario DemoWebShop
15
+ #
16
+ # =============================================================================
17
+ name: DemoWebShop
18
+
19
+ # --- Server under test -------------------------------------------------------
20
+ servers:
21
+ - name: demowebshop
22
+ host: demowebshop.tricentis.com
23
+ scheme: https
24
+ port: 443
25
+
26
+ # --- Variables -------------------------------
27
+ variables:
28
+ # Product added to the cart. "13" = "Computing and Internet" book in the demo shop.
29
+ - constant:
30
+ name: product_id
31
+ value: "13"
32
+ # Quantity added to the cart, randomised per iteration.
33
+ - random_number:
34
+ name: quantity
35
+ description: Number of items added to the cart
36
+ min: 1
37
+ max: 3
38
+ change_policy: each_iteration
39
+
40
+ # --- User path ---------------------------------------------------------------
41
+ user_paths:
42
+ - name: BuyAsGuest
43
+ description: Browse the shop, add a product, check out as a guest and view details
44
+
45
+ actions:
46
+ steps:
47
+
48
+ # 1) Open the shop home page ------------------------------------------------
49
+ - transaction:
50
+ name: 01_Home
51
+ steps:
52
+ - request:
53
+ server: demowebshop
54
+ url: /
55
+ assertions:
56
+ - contains: Tricentis Demo Web Shop
57
+ - think_time: 3s
58
+
59
+ # 2) Browse a category and open a product ----------------------------------
60
+ - transaction:
61
+ name: 02_Browse
62
+ steps:
63
+ - request:
64
+ server: demowebshop
65
+ url: /books
66
+ assertions:
67
+ - contains: Books
68
+ - think_time: 2s
69
+
70
+ # 3) Add the product to the cart (AJAX POST) -------------------------------
71
+ - transaction:
72
+ name: 03_AddToCart
73
+ steps:
74
+ - request:
75
+ server: demowebshop
76
+ url: /addproducttocart/catalog/${product_id}/1/${quantity}
77
+ method: POST
78
+ headers:
79
+ - name: X-Requested-With
80
+ value: XMLHttpRequest
81
+ assertions:
82
+ - contains: success
83
+ - think_time: 2s
84
+
85
+ # 4) View the cart ---------------------------------------------------------
86
+ - transaction:
87
+ name: 04_ViewCart
88
+ steps:
89
+ - request:
90
+ server: demowebshop
91
+ url: /cart
92
+ assertions:
93
+ - contains: Shopping cart
94
+ - think_time: 2s
95
+
96
+ # 5) Checkout as guest -----------------------------------------------------
97
+ - transaction:
98
+ name: 05_CheckoutAsGuest
99
+ steps:
100
+ - request:
101
+ server: demowebshop
102
+ url: /login/checkoutasguest?returnUrl=%2Fcart
103
+ method: POST
104
+ headers:
105
+ - name: Content-Type
106
+ value: application/x-www-form-urlencoded
107
+ - request:
108
+ server: demowebshop
109
+ url: /onepagecheckout
110
+ assertions:
111
+ - contains: Checkout
112
+ - think_time: 3s
113
+
114
+ # 6) View product details --------------------------------------------------
115
+ - transaction:
116
+ name: 06_ViewDetails
117
+ steps:
118
+ - request:
119
+ server: demowebshop
120
+ url: /computing-and-internet
121
+ assertions:
122
+ - contains: Computing and Internet
123
+ - think_time: 2s
124
+
125
+ # --- Population -----------------------------------
126
+ populations:
127
+ - name: GuestShoppers
128
+ user_paths:
129
+ - name: BuyAsGuest
130
+
131
+ # --- Scenario (used for the full test run) ------------------------------------
132
+ scenarios:
133
+ - name: DemoWebShop
134
+ description: Light constant load used for the manual test run on cloud/on-site LG
135
+ populations:
136
+ - name: GuestShoppers
137
+ constant_load:
138
+ users: 5
139
+ rampup: 30s
140
+ duration: 5m
@@ -0,0 +1,2 @@
1
+ __all__ = ["checkvu", "config", "docker", "fastfail", "login", "logout", "logs_url", "project", "run", "status", "stop", "test_results", "test_settings",
2
+ "validate", "wait", "workspaces", "zones", "report"]
@@ -0,0 +1,98 @@
1
+ import os
2
+ import sys
3
+
4
+ import click
5
+
6
+ from neoload_cli_lib import checkvu_runner, cli_exception
7
+ import neoload_cli_lib.schema_validation as schema_validation
8
+ from neoload_cli_lib.schema_validation import __default_schema_url
9
+
10
+ __yaml_extensions = (".yaml", ".yml")
11
+
12
+ @click.command()
13
+ @click.option('-e', '--engine-jar',
14
+ help="CheckVU engine JAR to run: a local file, for air-gapped or pinned setups, or a download URL. "
15
+ "Defaults to the cached JAR, otherwise the release URL for this version.",
16
+ metavar="PATH|URL")
17
+ @click.option('-j', '--java', help="Path to the java executable to use. "
18
+ "Defaults to JAVA_HOME/bin/java, then java on the PATH.", metavar="PATH")
19
+ @click.option('-u', '--user-path', help="Run only the specified user path. If omitted, all user paths in the file "
20
+ "are executed sequentially. An unknown name fails and lists the user paths "
21
+ "found in the file.", metavar="NAME")
22
+ @click.option('-s', '--as-code-schema', default=__default_schema_url, show_default=True,
23
+ help="NeoLoad as-code schema (URL or local path) to validate PROJECT_FILE "
24
+ "against. Defaults to the schema published for this release on Github.",
25
+ metavar="PATH|URL")
26
+ @click.option('--ssl-cert', default="",
27
+ help="Path to SSL certificate or write False to disable certificate checking. "
28
+ "Used both for schema validation and the JAR download.")
29
+ @click.option('--controller-properties',
30
+ help="Advanced. Path to controller.properties file merged additively into the Controller "
31
+ "configuration; only the keys you set are overridden, other embedded values are kept.",
32
+ metavar="PATH")
33
+ @click.option('--load-generator-properties',
34
+ help="Advanced. Path to agent.properties file merged additively into the Load Generator "
35
+ "configuration; only the keys you set are overridden.",
36
+ metavar="PATH")
37
+ @click.option('--app-proxy',
38
+ help="Proxy used to reach the tested applications, as host:port (e.g. myproxy.corp:8080). "
39
+ "Applies to both HTTP and HTTPS application traffic (User Path validation / Load Generator "
40
+ "traffic). Not used for NeoLoad Web API calls. CheckVU CLI download proxy uses the standard "
41
+ "HTTPS_PROXY, HTTP_PROXY and NO_PROXY variables instead.",
42
+ metavar="HOST:PORT")
43
+ @click.option('--app-proxy-username',
44
+ help="Username for --app-proxy authentication (optional). The password is read from environment "
45
+ "variable NEOLOAD_CHECK_VU_APP_PROXY_PASSWORD; there is no flag for it, so it is never "
46
+ "exposed in the process list or CI logs.",
47
+ metavar="USERNAME")
48
+ @click.option('--app-proxy-bypass',
49
+ help="Comma-separated hosts that bypass --app-proxy (e.g. localhost,internal.corp).",
50
+ metavar="HOSTS")
51
+ @click.option('-w', '--work-dir',
52
+ help="Directory for engine scratch files and logs. Defaults to a temporary directory. "
53
+ "A directory you supply is never deleted.",
54
+ metavar="PATH")
55
+ @click.option('--keep-temp-work-dir', is_flag=True, default=False,
56
+ help="Keep the temporary work directory after the run instead of deleting it. "
57
+ "Equivalent to setting CHECKVU_CLI_KEEP_TEMP_WORK_DIR=1. "
58
+ "Has no effect when --work-dir is already set, since that directory is never auto-deleted.")
59
+ @click.argument('project_file')
60
+ def cli(engine_jar, java, user_path, as_code_schema, ssl_cert,
61
+ controller_properties, load_generator_properties,
62
+ app_proxy, app_proxy_username, app_proxy_bypass, work_dir, keep_temp_work_dir,
63
+ project_file):
64
+ """ Validate the User Paths of a NeoLoad as-code Project locally.
65
+
66
+ Runs each User Path once against the application and reports whether
67
+ it completes without blocking errors. This is not a load test: no
68
+ Population, no Scenario, no Result. Exits 0 when every User Path passes, 1
69
+ otherwise, and always writes a JSON output.
70
+
71
+ PROJECT_FILE is the as-code Project YAML file. Its parent directory is the
72
+ Project root; colocated assets such as CSV files must live under that
73
+ root.
74
+ """
75
+ if not project_file.lower().endswith(__yaml_extensions):
76
+ raise cli_exception.CliException("Project file must be a yaml (\".yaml\", \".yml\") file: " + project_file)
77
+ if not os.path.isfile(project_file):
78
+ raise cli_exception.CliException("Project file not found: " + project_file)
79
+ print(schema_validation.validate_path(project_file, as_code_schema, ssl_cert), flush=True)
80
+
81
+ java_executable = checkvu_runner.resolve_java(java)
82
+ checkvu_runner.check_java_version(java_executable)
83
+
84
+ resolved_jar = checkvu_runner.resolve_jar(engine_jar, ssl_cert)
85
+
86
+ command = checkvu_runner.build_command(
87
+ java_executable, resolved_jar, project_file,
88
+ user_path=user_path,
89
+ controller_properties=controller_properties,
90
+ load_generator_properties=load_generator_properties,
91
+ app_proxy=app_proxy,
92
+ app_proxy_username=app_proxy_username,
93
+ app_proxy_bypass=app_proxy_bypass,
94
+ work_dir=work_dir,
95
+ keep_temp_work_dir=keep_temp_work_dir,
96
+ )
97
+ exit_code = checkvu_runner.run_checkvu(command)
98
+ sys.exit(exit_code)
@@ -0,0 +1,19 @@
1
+ import click
2
+ import neoload_cli_lib.schema_validation as schema_validation
3
+ from neoload_cli_lib.schema_validation import __default_schema_url
4
+
5
+ @click.command()
6
+ @click.option('-s', '--as-code-schema', default=None,
7
+ help="NeoLoad as-code schema (URL or local path) to validate FILE against. "
8
+ "Defaults to the schema published for this release on Github.",
9
+ metavar="PATH|URL")
10
+ @click.option('--schema-url', 'schema_url', default=None, hidden=True,
11
+ help="Deprecated alias for --as-code-schema, kept for backward compatibility.")
12
+ @click.option('--refresh', is_flag=True, help="THIS OPTION IS NOW USELESS", hidden=True)
13
+ @click.option('--ssl-cert', default="", help="Path to SSL certificate or write False to disable certificate checking")
14
+ @click.argument('file')
15
+ def cli(file, refresh, as_code_schema, schema_url, ssl_cert):
16
+ """Verify that the yaml FILE matches the neoload as-code file format"""
17
+ # -s/--as-code-schema (new) takes priority over --schema-url (deprecated alias)
18
+ resolved_schema = as_code_schema or schema_url or __default_schema_url
19
+ print(schema_validation.validate_path(file, resolved_schema, ssl_cert))
@@ -0,0 +1,189 @@
1
+ import os
2
+ import re
3
+ import shutil
4
+ import subprocess
5
+ import sys
6
+
7
+ from neoload_cli_lib import cli_exception, paths
8
+
9
+ MIN_JAVA_VERSION = 21
10
+
11
+ # Default download URL pointing at the "latest" CheckVU JAR
12
+ # TODO: set this once we have public jar url
13
+ # use --engine-jar for now
14
+ DEFAULT_JAR_URL = ""
15
+
16
+ CACHE_DIR_NAME = "checkvu"
17
+ CACHE_JAR_NAME = "neoload-checkvu-cli.jar"
18
+
19
+ __java_version_pattern = re.compile(r'version "(\d+)(?:\.(\d+))?')
20
+
21
+
22
+ def get_cache_dir():
23
+ return os.path.join(paths.get_config_dir(), CACHE_DIR_NAME)
24
+
25
+
26
+ def get_cached_jar_path():
27
+ return os.path.join(get_cache_dir(), CACHE_JAR_NAME)
28
+
29
+
30
+ def resolve_java(java_option=None):
31
+ """Return the path to a usable java executable, raising if none is found."""
32
+ if java_option:
33
+ return java_option
34
+ java_home = os.environ.get("JAVA_HOME")
35
+ if java_home:
36
+ candidate = os.path.join(java_home, "bin", "java")
37
+ resolved = shutil.which(candidate) or (candidate if os.path.isfile(candidate) else None)
38
+ if resolved:
39
+ return resolved
40
+ found = shutil.which("java")
41
+ if found:
42
+ return found
43
+ raise cli_exception.CliException(
44
+ "No Java runtime found. CheckVU requires Java {0} or later.\n"
45
+ "Install a JDK {0}+ and either add it to your PATH, set JAVA_HOME, "
46
+ "or pass --java <path-to-java>.".format(MIN_JAVA_VERSION))
47
+
48
+
49
+ def parse_java_major_version(version_output):
50
+ """Extract the major Java version from `java -version` output, or None."""
51
+ match = __java_version_pattern.search(version_output)
52
+ if match is None:
53
+ return None
54
+ major = int(match.group(1))
55
+ # Legacy versions 1.x -> x
56
+ if major == 1 and match.group(2) is not None:
57
+ return int(match.group(2))
58
+ return major
59
+
60
+
61
+ def check_java_version(java):
62
+ """Runs `java -version` and enforces the minimum supported major version.
63
+ `java -version` writes to stderr, so we merge stderr into stdout to capture it.
64
+ """
65
+ try:
66
+ completed = subprocess.run(
67
+ [java, "-version"],
68
+ stdout=subprocess.PIPE,
69
+ stderr=subprocess.STDOUT,
70
+ universal_newlines=True)
71
+ except OSError as err:
72
+ raise cli_exception.CliException(
73
+ "Unable to run '{0}': {1}\n"
74
+ "Install a JDK {2}+ and either add it to your PATH, set JAVA_HOME, "
75
+ "or pass --java <path-to-java>.".format(java, str(err), MIN_JAVA_VERSION))
76
+
77
+ output = completed.stdout or ""
78
+ major = parse_java_major_version(output)
79
+ if major is None:
80
+ raise cli_exception.CliException(
81
+ "Could not determine the Java version from '{0} -version':\n{1}".format(java, output.strip()))
82
+ if major < MIN_JAVA_VERSION:
83
+ raise cli_exception.CliException(
84
+ "CheckVU requires Java {0} or later, but '{1}' reports major version {2}.\n"
85
+ "Install a JDK {0}+ and either add it to your PATH, set JAVA_HOME, "
86
+ "or pass --java <path-to-java>.".format(MIN_JAVA_VERSION, java, major))
87
+ return major
88
+
89
+ def is_url(spec):
90
+ return spec is not None and '://' in spec
91
+
92
+
93
+ # TODO cache invalidation according to project version ?
94
+ def resolve_jar(engine_jar=None, ssl_cert=''):
95
+ """Resolves the CheckVU fat JAR from --engine-jar (a local file, or a download URL).
96
+ Resolution order:
97
+ 1. --engine-jar
98
+ 2. cached JAR if exists
99
+ 3. DEFAULT_JAR_URL -> download + cache
100
+ 4. error
101
+ """
102
+ cache_path = get_cached_jar_path()
103
+
104
+ if engine_jar:
105
+ if is_url(engine_jar):
106
+ return download_jar(engine_jar, cache_path, ssl_cert)
107
+ if not os.path.isfile(engine_jar):
108
+ raise cli_exception.CliException("CheckVU JAR not found at '{0}'.".format(engine_jar))
109
+ return engine_jar
110
+
111
+ if os.path.isfile(cache_path):
112
+ return cache_path
113
+
114
+ if DEFAULT_JAR_URL:
115
+ return download_jar(DEFAULT_JAR_URL, cache_path, ssl_cert)
116
+
117
+ raise cli_exception.CliException(
118
+ "No CheckVU JAR available. Provide one with --engine-jar <path-to-neoload-checkvu-cli.jar|download-url>.\n")
119
+
120
+
121
+ def download_jar(url, destination, ssl_cert=''):
122
+ """Download the CheckVU JAR to the cache, showing a progress bar when interactive."""
123
+ import requests
124
+ from tqdm import tqdm
125
+ from neoload_cli_lib import tools
126
+
127
+ verify = tools.ssl_cert_to_verify(ssl_cert)
128
+ os.makedirs(os.path.dirname(destination), exist_ok=True)
129
+ partial_destination = destination + ".part"
130
+ print("Downloading JAR from " + url + "\n")
131
+ try:
132
+ with requests.get(url, stream=True, verify=verify) as response:
133
+ response.raise_for_status()
134
+ total_bytes = int(response.headers.get("content-length", 0))
135
+ progress_bar = None
136
+ if tools.is_user_interactive():
137
+ progress_bar = tqdm(desc=CACHE_JAR_NAME, total=total_bytes, unit="B",
138
+ unit_scale=True, leave=False, dynamic_ncols=True)
139
+ with open(partial_destination, "wb") as stream:
140
+ for chunk in response.iter_content(chunk_size=1024 * 64):
141
+ if chunk:
142
+ stream.write(chunk)
143
+ if progress_bar is not None:
144
+ progress_bar.update(len(chunk))
145
+ if progress_bar is not None:
146
+ progress_bar.close()
147
+ os.replace(partial_destination, destination)
148
+ except Exception as err:
149
+ if os.path.isfile(partial_destination):
150
+ os.remove(partial_destination)
151
+ raise cli_exception.CliException(
152
+ "Failed to download the CheckVU JAR from '{0}':\n{1}".format(url, str(err)))
153
+ return destination
154
+
155
+
156
+ def build_command(java, jar, project_file, user_path=None,
157
+ controller_properties=None, load_generator_properties=None,
158
+ app_proxy=None, app_proxy_username=None, app_proxy_bypass=None,
159
+ work_dir=None, keep_temp_work_dir=False):
160
+ command = [java, "-jar", jar]
161
+ if user_path:
162
+ command.extend(["--user-path", user_path])
163
+ if controller_properties:
164
+ command.extend(["--controller-properties", controller_properties])
165
+ if load_generator_properties:
166
+ command.extend(["--load-generator-properties", load_generator_properties])
167
+ if app_proxy:
168
+ command.extend(["--app-proxy", app_proxy])
169
+ if app_proxy_username:
170
+ command.extend(["--app-proxy-username", app_proxy_username])
171
+ if app_proxy_bypass:
172
+ command.extend(["--app-proxy-bypass", app_proxy_bypass])
173
+ if work_dir:
174
+ command.extend(["--work-dir", work_dir])
175
+ if keep_temp_work_dir:
176
+ command.append("--keep-temp-work-dir")
177
+ command.append(project_file)
178
+ return command
179
+
180
+
181
+ def run_checkvu(command):
182
+ """Run the JAR, inheriting stdio so the CLI output is the JAR output, and return its exit code."""
183
+ sys.stdout.flush()
184
+ sys.stderr.flush()
185
+ try:
186
+ completed = subprocess.run(command, stdout=sys.stdout, stderr=sys.stderr, stdin=sys.stdin)
187
+ except OSError as err:
188
+ raise cli_exception.CliException("Failed to run CheckVU: {0}".format(str(err)))
189
+ return completed.returncode
@@ -307,3 +307,21 @@ def get_json_schema_by_spec(schema_spec, ssl_cert):
307
307
  raise bad_as_code_exception.BadAsCodeSchemaException('Could not load schema from provided file spec: %s' % schema_spec)
308
308
 
309
309
  return json_schema_spec
310
+
311
+
312
+ def validate_path(file, schema_url, ssl_cert=''):
313
+ """Validates an as-code yaml file against the schema from NLCLI_FORCE_SCHEMA
314
+ or downloaded from given URL or from the defautl URL."""
315
+ force_schema = os.environ.get('NLCLI_FORCE_SCHEMA')
316
+ if force_schema is not None and len(force_schema) > 0:
317
+ schema_url = force_schema
318
+
319
+ path = os.path.abspath(file)
320
+ try:
321
+ if os.path.isdir(path):
322
+ validate_yaml_dir(path, schema_url, ssl_cert)
323
+ return 'All yaml files underneath the path provided are valid.'
324
+ validate_yaml(file, schema_url, ssl_cert)
325
+ return 'Yaml file is valid.'
326
+ except Exception as err:
327
+ raise cli_exception.CliException(str(err))
@@ -0,0 +1 @@
1
+ __version__ = "1.3.19.dev2"