From a3c009f812ce27a6ce27ed71738055481a8e65e9 Mon Sep 17 00:00:00 2001 From: amanda Date: Tue, 4 Aug 2020 16:30:03 +0100 Subject: [PATCH 01/26] Initial mistral removal from st2 --- CHANGELOG.rst | 3 + Makefile | 77 +- conf/mistral.dev/README.md | 4 - conf/mistral.dev/logging.conf | 32 - conf/mistral.dev/mistral.dev.conf | 9 - conf/mistral.dev/policy.json | 58 - conf/mistral.dev/wf_trace_logging.conf | 62 - .../chains/invoke_mistral_with_jinja.yaml | 12 - .../actions/chains/mistral_examples.yaml | 14 - .../actions/invoke_mistral_with_jinja.yaml | 10 - .../actions/mistral-ask-basic.meta.yaml | 7 - .../actions/mistral-ask-parent.meta.yaml | 8 - ...al-basic-two-tasks-with-notifications.yaml | 16 - contrib/examples/actions/mistral-basic.yaml | 14 - .../examples/actions/mistral-branching.yaml | 15 - contrib/examples/actions/mistral-env-var.yaml | 7 - .../actions/mistral-error-bad-action.yaml | 7 - .../mistral-error-bad-task-transition.yaml | 7 - .../actions/mistral-error-bad-wf-arg.yaml | 12 - .../actions/mistral-error-bad-with-items.yaml | 7 - .../mistral-handle-error-task-default.yaml | 12 - .../actions/mistral-handle-error.yaml | 12 - .../actions/mistral-handle-retry.yaml | 12 - .../actions/mistral-jinja-branching.yaml | 15 - .../actions/mistral-jinja-env-var.yaml | 7 - .../mistral-jinja-repeat-with-items.yaml | 13 - ...al-jinja-st2kv-system-scope-encrypted.yaml | 9 - .../mistral-jinja-st2kv-system-scope.yaml | 9 - .../mistral-jinja-workbook-complex.yaml | 21 - contrib/examples/actions/mistral-join.yaml | 7 - .../actions/mistral-repeat-with-items.yaml | 13 - contrib/examples/actions/mistral-repeat.yaml | 14 - .../actions/mistral-reverse-basic.yaml | 18 - .../actions/mistral-reverse-requires.yaml | 15 - .../actions/mistral-streaming-demo.meta.yaml | 15 - ...istral-test-cancel-subworkflow-action.yaml | 14 - ...mistral-test-cancel-subworkflow-chain.yaml | 14 - .../examples/actions/mistral-test-cancel.yaml | 14 - .../mistral-test-func-from-json-string.yaml | 11 - .../mistral-test-func-from-yaml-string.yaml | 11 - .../mistral-test-func-json-escape.yaml | 11 - .../mistral-test-func-jsonpath-query.yaml | 14 - .../mistral-test-func-regex-match.yaml | 14 - .../mistral-test-func-regex-replace.yaml | 17 - .../mistral-test-func-regex-search.yaml | 14 - .../mistral-test-func-regex-substring.yaml | 14 - .../actions/mistral-test-func-to-complex.yaml | 11 - ...-test-func-to-human-time-from-seconds.yaml | 11 - .../mistral-test-func-to-json-string.yaml | 11 - .../mistral-test-func-to-yaml-string.yaml | 11 - .../actions/mistral-test-func-use-none.yaml | 11 - .../mistral-test-func-version-bump-major.yaml | 11 - .../mistral-test-func-version-bump-minor.yaml | 11 - .../mistral-test-func-version-bump-patch.yaml | 11 - .../mistral-test-func-version-compare.yaml | 14 - .../mistral-test-func-version-equal.yaml | 14 - .../mistral-test-func-version-less-than.yaml | 14 - .../mistral-test-func-version-match.yaml | 14 - .../mistral-test-func-version-more-than.yaml | 14 - ...mistral-test-func-version-strip-patch.yaml | 11 - .../actions/mistral-test-jinja-bad-expr.yaml | 7 - .../mistral-test-jinja-bad-publish.yaml | 7 - ...tral-test-jinja-bad-subworkflow-input.yaml | 12 - ...istral-test-jinja-bad-task-transition.yaml | 7 - .../mistral-test-jinja-bad-with-items.yaml | 7 - ...-pause-before-task-subworkflow-action.yaml | 11 - ...ause-before-task-subworkflow-workbook.yaml | 15 - .../mistral-test-pause-before-task.yaml | 11 - ...-test-pause-resume-subworkflow-action.yaml | 14 - ...l-test-pause-resume-subworkflow-chain.yaml | 14 - ...est-pause-resume-subworkflow-workbook.yaml | 18 - .../actions/mistral-test-pause-resume.yaml | 14 - ...mistral-test-rerun-subflow-with-items.yaml | 15 - .../actions/mistral-test-rerun-subflow.yaml | 15 - .../mistral-test-rerun-with-items.yaml | 11 - .../examples/actions/mistral-test-rerun.yaml | 11 - .../actions/mistral-test-yaql-bad-expr.yaml | 7 - .../mistral-test-yaql-bad-publish.yaml | 7 - ...stral-test-yaql-bad-subworkflow-input.yaml | 12 - ...mistral-test-yaql-bad-task-transition.yaml | 7 - .../mistral-test-yaql-bad-with-items.yaml | 7 - .../mistral-with-items-concurrency.yaml | 14 - .../actions/mistral-workbook-basic.yaml | 11 - .../actions/mistral-workbook-complex.yaml | 21 - .../mistral-workbook-multiple-subflows.yaml | 12 - .../actions/mistral-workbook-subflows.yaml | 14 - .../mistral-yaql-st2kv-system-scope.yaml | 9 - .../mistral-yaql-st2kv-user-scope.yaml | 9 - .../actions/mistral_examples.meta.yaml | 13 - .../actions/workflows/mistral-ask-basic.yaml | 26 - .../actions/workflows/mistral-ask-parent.yaml | 10 - ...al-basic-two-tasks-with-notifications.yaml | 18 - .../actions/workflows/mistral-basic.yaml | 16 - .../actions/workflows/mistral-branching.yaml | 38 - .../actions/workflows/mistral-env-var.yaml | 15 - .../mistral-handle-error-task-default.yaml | 32 - .../workflows/mistral-handle-error.yaml | 27 - .../workflows/mistral-handle-retry.yaml | 50 - .../workflows/mistral-jinja-branching.yaml | 32 - .../workflows/mistral-jinja-env-var.yaml | 16 - .../mistral-jinja-repeat-with-items.yaml | 17 - ...al-jinja-st2kv-system-scope-encrypted.yaml | 14 - .../mistral-jinja-st2kv-system-scope.yaml | 14 - .../mistral-jinja-workbook-complex.yaml | 102 -- .../actions/workflows/mistral-join.yaml | 38 - .../workflows/mistral-repeat-with-items.yaml | 15 - .../actions/workflows/mistral-repeat.yaml | 16 - .../workflows/mistral-reverse-basic.yaml | 16 - .../workflows/mistral-reverse-requires.yaml | 41 - .../workflows/mistral-streaming-demo.yaml | 63 - .../mistral-with-items-concurrency.yaml | 21 - .../workflows/mistral-workbook-basic.yaml | 16 - .../workflows/mistral-workbook-complex.yaml | 95 -- .../mistral-workbook-multiple-subflows.yaml | 65 - .../workflows/mistral-workbook-subflows.yaml | 30 - .../mistral-yaql-st2kv-system-scope.yaml | 12 - .../mistral-yaql-st2kv-user-scope.yaml | 12 - .../tests/mistral-error-bad-action.yaml | 8 - .../mistral-error-bad-task-transition.yaml | 12 - .../tests/mistral-error-bad-wf-arg.yaml | 18 - .../tests/mistral-error-bad-with-items.yaml | 10 - ...istral-test-cancel-subworkflow-action.yaml | 20 - ...mistral-test-cancel-subworkflow-chain.yaml | 20 - .../workflows/tests/mistral-test-cancel.yaml | 22 - .../mistral-test-func-from-json-string.yaml | 16 - .../mistral-test-func-from-yaml-string.yaml | 16 - .../tests/mistral-test-func-json-escape.yaml | 17 - .../mistral-test-func-jsonpath-query.yaml | 18 - .../tests/mistral-test-func-regex-match.yaml | 18 - .../mistral-test-func-regex-replace.yaml | 19 - .../tests/mistral-test-func-regex-search.yaml | 18 - .../mistral-test-func-regex-substring.yaml | 26 - .../tests/mistral-test-func-to-complex.yaml | 16 - ...-test-func-to-human-time-from-seconds.yaml | 17 - .../mistral-test-func-to-json-string.yaml | 16 - .../mistral-test-func-to-yaml-string.yaml | 16 - .../tests/mistral-test-func-use-none.yaml | 29 - .../mistral-test-func-version-bump-major.yaml | 17 - .../mistral-test-func-version-bump-minor.yaml | 17 - .../mistral-test-func-version-bump-patch.yaml | 17 - .../mistral-test-func-version-compare.yaml | 18 - .../mistral-test-func-version-equal.yaml | 18 - .../mistral-test-func-version-less-than.yaml | 18 - .../mistral-test-func-version-match.yaml | 18 - .../mistral-test-func-version-more-than.yaml | 18 - ...mistral-test-func-version-strip-patch.yaml | 17 - .../tests/mistral-test-jinja-bad-expr.yaml | 10 - .../tests/mistral-test-jinja-bad-publish.yaml | 12 - ...tral-test-jinja-bad-subworkflow-input.yaml | 18 - ...istral-test-jinja-bad-task-transition.yaml | 12 - .../mistral-test-jinja-bad-with-items.yaml | 8 - ...-pause-before-task-subworkflow-action.yaml | 18 - ...ause-before-task-subworkflow-workbook.yaml | 39 - .../tests/mistral-test-pause-before-task.yaml | 21 - ...-test-pause-resume-subworkflow-action.yaml | 20 - ...l-test-pause-resume-subworkflow-chain.yaml | 20 - ...est-pause-resume-subworkflow-workbook.yaml | 42 - .../tests/mistral-test-pause-resume.yaml | 22 - ...mistral-test-rerun-subflow-with-items.yaml | 26 - .../tests/mistral-test-rerun-subflow.yaml | 25 - .../tests/mistral-test-rerun-with-items.yaml | 13 - .../workflows/tests/mistral-test-rerun.yaml | 12 - .../tests/mistral-test-yaql-bad-expr.yaml | 10 - .../tests/mistral-test-yaql-bad-publish.yaml | 12 - ...stral-test-yaql-bad-subworkflow-input.yaml | 18 - ...mistral-test-yaql-bad-task-transition.yaml | 12 - .../mistral-test-yaql-bad-with-items.yaml | 8 - contrib/runners/mistral_v2/MANIFEST.in | 11 - .../runners/mistral_v2/callback/__init__.py | 0 contrib/runners/mistral_v2/dist_utils.py | 168 --- .../runners/mistral_v2/in-requirements.txt | 0 .../runners/mistral_v2/mistral_v2/__init__.py | 15 - .../runners/mistral_v2/mistral_v2/callback.py | 140 -- .../mistral_v2/mistral_v2/mistral_v2.py | 563 -------- .../runners/mistral_v2/mistral_v2/query.py | 333 ----- .../runners/mistral_v2/mistral_v2/runner.yaml | 24 - contrib/runners/mistral_v2/query/__init__.py | 0 contrib/runners/mistral_v2/requirements.txt | 8 - contrib/runners/mistral_v2/runner.yaml | 1 - contrib/runners/mistral_v2/setup.py | 61 - .../mistral_v2/tests/integration/__init__.py | 0 .../runners/mistral_v2/tests/unit/__init__.py | 0 .../tests/unit/test_mistral_utils.py | 62 - .../mistral_v2/tests/unit/test_mistral_v2.py | 969 ------------- .../tests/unit/test_mistral_v2_auth.py | 269 ---- .../tests/unit/test_mistral_v2_callback.py | 539 ------- .../tests/unit/test_mistral_v2_cancel.py | 306 ---- .../unit/test_mistral_v2_pause_and_resume.py | 473 ------- .../tests/unit/test_mistral_v2_policy.py | 274 ---- .../tests/unit/test_mistral_v2_querier.py | 1261 ----------------- .../tests/unit/test_mistral_v2_rerun.py | 596 -------- scripts/travis/build.sh | 2 - scripts/travis/setup-mistral.sh | 192 --- .../controllers/exp/test_validator_mistral.py | 306 ---- st2common/st2common/util/workflow/__init__.py | 0 st2common/st2common/util/workflow/mistral.py | 281 ---- .../validators/workflow/mistral/__init__.py | 0 .../validators/workflow/mistral/v2.py | 123 -- .../unit/test_util_mistral_dsl_transform.py | 194 --- .../tests/unit/test_validator_mistral.py | 312 ---- .../integration/fixtures/configs/mistral.conf | 5 - st2tests/integration/mistral/__init__.py | 0 st2tests/integration/mistral/base.py | 122 -- st2tests/integration/mistral/test_errors.py | 115 -- st2tests/integration/mistral/test_examples.py | 106 -- st2tests/integration/mistral/test_filters.py | 391 ----- st2tests/integration/mistral/test_st2kv.py | 105 -- st2tests/integration/mistral/test_wiring.py | 129 -- .../integration/mistral/test_wiring_cancel.py | 277 ---- .../mistral/test_wiring_pause_resume.py | 273 ---- .../integration/mistral/test_wiring_rerun.py | 215 --- st2tests/st2tests/config.py | 1 - .../conf/st2.tests.api.audit_log_level.conf | 2 - .../conf/st2.tests.api.debug_log_level.conf | 2 - .../conf/st2.tests.api.info_log_level.conf | 2 - .../conf/st2.tests.api.system_debug_true.conf | 2 - ...s.api.system_debug_true_logging_debug.conf | 2 - .../st2tests/fixtures/conf/st2.tests.conf | 2 - .../generic/liveactions/liveaction2.yaml | 10 - .../generic/workflows/wb_invalid_syntax.yaml | 72 - .../generic/workflows/wb_invalid_yaql.yaml | 73 - .../generic/workflows/wb_post_xform.yaml | 81 -- .../generic/workflows/wb_pre_xform.yaml | 73 - .../wf_has_jinja_st2kv_post_xform.yaml | 49 - .../wf_has_jinja_st2kv_pre_xform.yaml | 40 - .../workflows/wf_has_unexpected_param.yaml | 13 - .../generic/workflows/wf_invalid_syntax.yaml | 19 - .../generic/workflows/wf_invalid_yaql.yaml | 20 - .../wf_jinja_mixed_context_ref1.yaml | 20 - .../wf_jinja_mixed_context_ref2.yaml | 20 - .../workflows/wf_missing_required_param.yaml | 12 - .../generic/workflows/wf_post_xform.yaml | 29 - .../generic/workflows/wf_pre_xform.yaml | 20 - .../mistral_tests/actions/workbook_v2.yaml | 14 - .../workbook_v2_call_workflow_action.yaml | 14 - .../actions/workbook_v2_many_workflows.yaml | 17 - ...workbook_v2_many_workflows_no_default.yaml | 14 - .../actions/workbook_v2_name_mismatch.yaml | 14 - .../mistral_tests/actions/workflow_v2.yaml | 14 - .../workflow_v2_call_workflow_action.yaml | 14 - .../actions/workflow_v2_many_workflows.yaml | 14 - .../actions/workflow_v2_name_mismatch.yaml | 14 - .../actions/workflow_v2_reverse.yaml | 19 - .../actions/workflows/workbook_v2.yaml | 25 - .../workbook_v2_call_workflow_action.yaml | 16 - .../workflows/workbook_v2_many_workflows.yaml | 38 - ...workbook_v2_many_workflows_no_default.yaml | 49 - .../actions/workflows/workflow_v2.yaml | 22 - .../workflow_v2_call_workflow_action.yaml | 13 - .../workflows/workflow_v2_many_workflows.yaml | 43 - .../workflows/workflow_v2_reverse.yaml | 21 - .../workflows/xformed_workbook_v2.yaml | 29 - ...rmed_workbook_v2_call_workflow_action.yaml | 18 - .../xformed_workbook_v2_many_workflows.yaml | 42 - ...workbook_v2_many_workflows_no_default.yaml | 53 - .../workflows/xformed_workflow_v2.yaml | 26 - ...rmed_workflow_v2_call_workflow_action.yaml | 15 - .../xformed_workflow_v2_many_workflows.yaml | 51 - .../xformed_workflow_v2_reverse.yaml | 25 - .../fixtures/packs/mistral_tests/pack.yaml | 6 - .../policies/cancel_on_concurrency.yaml | 10 - .../cancel_on_concurrency_by_attr.yaml | 12 - tools/db_cleanup.sh | 11 - tools/launchdev.sh | 122 -- tools/setup_mistral_db.sh | 90 -- tools/submit-per-service-metrics-to-statsd | 7 +- tools/upgrade-mistral-wf-0.8 | 78 - tox.ini | 20 +- 268 files changed, 12 insertions(+), 13740 deletions(-) delete mode 100644 conf/mistral.dev/README.md delete mode 100755 conf/mistral.dev/logging.conf delete mode 100644 conf/mistral.dev/mistral.dev.conf delete mode 100644 conf/mistral.dev/policy.json delete mode 100755 conf/mistral.dev/wf_trace_logging.conf delete mode 100644 contrib/examples/actions/chains/invoke_mistral_with_jinja.yaml delete mode 100644 contrib/examples/actions/chains/mistral_examples.yaml delete mode 100644 contrib/examples/actions/invoke_mistral_with_jinja.yaml delete mode 100644 contrib/examples/actions/mistral-ask-basic.meta.yaml delete mode 100644 contrib/examples/actions/mistral-ask-parent.meta.yaml delete mode 100644 contrib/examples/actions/mistral-basic-two-tasks-with-notifications.yaml delete mode 100644 contrib/examples/actions/mistral-basic.yaml delete mode 100644 contrib/examples/actions/mistral-branching.yaml delete mode 100644 contrib/examples/actions/mistral-env-var.yaml delete mode 100644 contrib/examples/actions/mistral-error-bad-action.yaml delete mode 100644 contrib/examples/actions/mistral-error-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/mistral-error-bad-wf-arg.yaml delete mode 100644 contrib/examples/actions/mistral-error-bad-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-handle-error-task-default.yaml delete mode 100644 contrib/examples/actions/mistral-handle-error.yaml delete mode 100644 contrib/examples/actions/mistral-handle-retry.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-branching.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-env-var.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-repeat-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-st2kv-system-scope-encrypted.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-st2kv-system-scope.yaml delete mode 100644 contrib/examples/actions/mistral-jinja-workbook-complex.yaml delete mode 100644 contrib/examples/actions/mistral-join.yaml delete mode 100644 contrib/examples/actions/mistral-repeat-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-repeat.yaml delete mode 100644 contrib/examples/actions/mistral-reverse-basic.yaml delete mode 100644 contrib/examples/actions/mistral-reverse-requires.yaml delete mode 100644 contrib/examples/actions/mistral-streaming-demo.meta.yaml delete mode 100644 contrib/examples/actions/mistral-test-cancel-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/mistral-test-cancel-subworkflow-chain.yaml delete mode 100644 contrib/examples/actions/mistral-test-cancel.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-from-json-string.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-from-yaml-string.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-json-escape.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-jsonpath-query.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-regex-match.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-regex-replace.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-regex-search.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-regex-substring.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-to-complex.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-to-human-time-from-seconds.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-to-json-string.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-to-yaml-string.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-use-none.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-bump-major.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-bump-minor.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-bump-patch.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-compare.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-equal.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-less-than.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-match.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-more-than.yaml delete mode 100644 contrib/examples/actions/mistral-test-func-version-strip-patch.yaml delete mode 100644 contrib/examples/actions/mistral-test-jinja-bad-expr.yaml delete mode 100644 contrib/examples/actions/mistral-test-jinja-bad-publish.yaml delete mode 100644 contrib/examples/actions/mistral-test-jinja-bad-subworkflow-input.yaml delete mode 100644 contrib/examples/actions/mistral-test-jinja-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/mistral-test-jinja-bad-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-before-task-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-before-task-subworkflow-workbook.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-before-task.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-resume-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-resume-subworkflow-chain.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-resume-subworkflow-workbook.yaml delete mode 100644 contrib/examples/actions/mistral-test-pause-resume.yaml delete mode 100644 contrib/examples/actions/mistral-test-rerun-subflow-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-test-rerun-subflow.yaml delete mode 100644 contrib/examples/actions/mistral-test-rerun-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-test-rerun.yaml delete mode 100644 contrib/examples/actions/mistral-test-yaql-bad-expr.yaml delete mode 100644 contrib/examples/actions/mistral-test-yaql-bad-publish.yaml delete mode 100644 contrib/examples/actions/mistral-test-yaql-bad-subworkflow-input.yaml delete mode 100644 contrib/examples/actions/mistral-test-yaql-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/mistral-test-yaql-bad-with-items.yaml delete mode 100644 contrib/examples/actions/mistral-with-items-concurrency.yaml delete mode 100644 contrib/examples/actions/mistral-workbook-basic.yaml delete mode 100644 contrib/examples/actions/mistral-workbook-complex.yaml delete mode 100644 contrib/examples/actions/mistral-workbook-multiple-subflows.yaml delete mode 100644 contrib/examples/actions/mistral-workbook-subflows.yaml delete mode 100644 contrib/examples/actions/mistral-yaql-st2kv-system-scope.yaml delete mode 100644 contrib/examples/actions/mistral-yaql-st2kv-user-scope.yaml delete mode 100644 contrib/examples/actions/mistral_examples.meta.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-ask-basic.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-ask-parent.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-basic-two-tasks-with-notifications.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-basic.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-branching.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-env-var.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-handle-error-task-default.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-handle-error.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-handle-retry.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-branching.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-env-var.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-repeat-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope-encrypted.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-jinja-workbook-complex.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-join.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-repeat-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-repeat.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-reverse-basic.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-reverse-requires.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-streaming-demo.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-with-items-concurrency.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-workbook-basic.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-workbook-complex.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-workbook-multiple-subflows.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-workbook-subflows.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-yaql-st2kv-system-scope.yaml delete mode 100644 contrib/examples/actions/workflows/mistral-yaql-st2kv-user-scope.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-error-bad-action.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-error-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-error-bad-wf-arg.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-error-bad-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-chain.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-cancel.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-from-json-string.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-from-yaml-string.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-json-escape.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-jsonpath-query.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-regex-match.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-regex-replace.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-regex-search.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-regex-substring.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-to-complex.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-to-human-time-from-seconds.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-to-json-string.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-to-yaml-string.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-use-none.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-major.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-minor.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-patch.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-compare.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-equal.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-less-than.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-match.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-more-than.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-func-version-strip-patch.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-expr.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-publish.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-subworkflow-input.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-workbook.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-before-task.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-action.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-chain.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-workbook.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-pause-resume.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-rerun-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-rerun.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-expr.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-publish.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-subworkflow-input.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-task-transition.yaml delete mode 100644 contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-with-items.yaml delete mode 100644 contrib/runners/mistral_v2/MANIFEST.in delete mode 100644 contrib/runners/mistral_v2/callback/__init__.py delete mode 100644 contrib/runners/mistral_v2/dist_utils.py delete mode 100644 contrib/runners/mistral_v2/in-requirements.txt delete mode 100644 contrib/runners/mistral_v2/mistral_v2/__init__.py delete mode 100644 contrib/runners/mistral_v2/mistral_v2/callback.py delete mode 100644 contrib/runners/mistral_v2/mistral_v2/mistral_v2.py delete mode 100644 contrib/runners/mistral_v2/mistral_v2/query.py delete mode 100644 contrib/runners/mistral_v2/mistral_v2/runner.yaml delete mode 100644 contrib/runners/mistral_v2/query/__init__.py delete mode 100644 contrib/runners/mistral_v2/requirements.txt delete mode 120000 contrib/runners/mistral_v2/runner.yaml delete mode 100644 contrib/runners/mistral_v2/setup.py delete mode 100644 contrib/runners/mistral_v2/tests/integration/__init__.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/__init__.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_utils.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_auth.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_callback.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_cancel.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_pause_and_resume.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_policy.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_querier.py delete mode 100644 contrib/runners/mistral_v2/tests/unit/test_mistral_v2_rerun.py delete mode 100755 scripts/travis/setup-mistral.sh delete mode 100644 st2api/tests/unit/controllers/exp/test_validator_mistral.py delete mode 100644 st2common/st2common/util/workflow/__init__.py delete mode 100644 st2common/st2common/util/workflow/mistral.py delete mode 100644 st2common/st2common/validators/workflow/mistral/__init__.py delete mode 100644 st2common/st2common/validators/workflow/mistral/v2.py delete mode 100644 st2common/tests/unit/test_util_mistral_dsl_transform.py delete mode 100644 st2common/tests/unit/test_validator_mistral.py delete mode 100644 st2debug/tests/integration/fixtures/configs/mistral.conf delete mode 100644 st2tests/integration/mistral/__init__.py delete mode 100644 st2tests/integration/mistral/base.py delete mode 100644 st2tests/integration/mistral/test_errors.py delete mode 100644 st2tests/integration/mistral/test_examples.py delete mode 100644 st2tests/integration/mistral/test_filters.py delete mode 100644 st2tests/integration/mistral/test_st2kv.py delete mode 100644 st2tests/integration/mistral/test_wiring.py delete mode 100644 st2tests/integration/mistral/test_wiring_cancel.py delete mode 100644 st2tests/integration/mistral/test_wiring_pause_resume.py delete mode 100644 st2tests/integration/mistral/test_wiring_rerun.py delete mode 100644 st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wb_invalid_syntax.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wb_invalid_yaql.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wb_post_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wb_pre_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_post_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_pre_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_has_unexpected_param.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_invalid_syntax.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_invalid_yaql.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref1.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref2.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_missing_required_param.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_post_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/generic/workflows/wf_pre_xform.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows_no_default.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_name_mismatch.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_name_mismatch.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_reverse.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows_no_default.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_reverse.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows_no_default.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_call_workflow_action.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_many_workflows.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_reverse.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/pack.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency.yaml delete mode 100644 st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency_by_attr.yaml delete mode 100755 tools/setup_mistral_db.sh delete mode 100755 tools/upgrade-mistral-wf-0.8 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 570f52d1f9..2f523180f6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -68,6 +68,9 @@ Changed Removed ~~~~~~~ +* Removed ``Mistral`` + + Contributed by Amanda McGuinness (@amanda11 Ammeon Solutions) * Removed ``CentOS 6``/``RHEL 6`` support #4984 Contributed by Amanda McGuinness (@amanda11 Ammeon Solutions) diff --git a/Makefile b/Makefile index 164245151f..e6113e8e60 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,6 @@ COMPONENTS_RUNNERS := $(wildcard contrib/runners/*) COMPONENTS_WITHOUT_ST2TESTS := $(shell ls -a | grep ^st2 | grep -v .egg-info | grep -v st2tests | grep -v st2exporter) COMPONENTS_WITH_RUNNERS := $(COMPONENTS) $(COMPONENTS_RUNNERS) -COMPONENTS_WITH_RUNNERS_WITHOUT_MISTRAL_RUNNER := $(foreach component,$(filter-out contrib/runners/mistral_v2,$(COMPONENTS_WITH_RUNNERS)),$(component)) COMPONENTS_TEST_DIRS := $(wildcard st2*/tests) $(wildcard contrib/runners/*/tests) @@ -43,12 +42,11 @@ space_char := space_char += COMPONENT_PYTHONPATH = $(subst $(space_char),:,$(realpath $(COMPONENTS_WITH_RUNNERS))) COMPONENTS_TEST := $(foreach component,$(filter-out $(COMPONENT_SPECIFIC_TESTS),$(COMPONENTS_WITH_RUNNERS)),$(component)) -COMPONENTS_TEST_WITHOUT_MISTRAL_RUNNER := $(foreach component,$(filter-out $(COMPONENT_SPECIFIC_TESTS),$(COMPONENTS_WITH_RUNNERS_WITHOUT_MISTRAL_RUNNER)),$(component)) COMPONENTS_TEST_COMMA := $(subst $(slash),$(dot),$(subst $(space_char),$(comma),$(COMPONENTS_TEST))) COMPONENTS_TEST_MODULES := $(subst $(slash),$(dot),$(COMPONENTS_TEST_DIRS)) COMPONENTS_TEST_MODULES_COMMA := $(subst $(space_char),$(comma),$(COMPONENTS_TEST_MODULES)) -COVERAGE_GLOBS := .coverage.unit.* .coverage.integration.* .coverage.mistral.* +COVERAGE_GLOBS := .coverage.unit.* .coverage.integration.* COVERAGE_GLOBS_QUOTED := $(foreach glob,$(COVERAGE_GLOBS),'$(glob)') REQUIREMENTS := test-requirements.txt requirements.txt @@ -114,8 +112,6 @@ play: @echo @echo COMPONENTS_WITH_RUNNERS=$(COMPONENTS_WITH_RUNNERS) @echo - @echo COMPONENTS_WITH_RUNNERS_WITHOUT_MISTRAL_RUNNER=$(COMPONENTS_WITH_RUNNERS_WITHOUT_MISTRAL_RUNNER) - @echo @echo COMPONENTS_TEST=$(COMPONENTS_TEST) @echo @echo COMPONENTS_TEST_COMMA=$(COMPONENTS_TEST_COMMA) @@ -126,8 +122,6 @@ play: @echo @echo COMPONENTS_TEST_MODULES_COMMA=$(COMPONENTS_TEST_MODULES_COMMA) @echo - @echo COMPONENTS_TEST_WITHOUT_MISTRAL_RUNNER=$(COMPONENTS_TEST_WITHOUT_MISTRAL_RUNNER) - @echo @echo COMPONENT_PYTHONPATH=$(COMPONENT_PYTHONPATH) @echo @echo TRAVIS_PULL_REQUEST=$(TRAVIS_PULL_REQUEST) @@ -455,16 +449,6 @@ compilepy3: @mongo --eval "rs.initiate()" @sleep 15 -.PHONY: .cleanmysql -.cleanmysql: - @echo "==================== cleanmysql ====================" - @echo "----- Dropping all Mistral MYSQL databases -----" - @mysql -uroot -pStackStorm -e "DROP DATABASE IF EXISTS mistral" - @mysql -uroot -pStackStorm -e "CREATE DATABASE mistral" - @mysql -uroot -pStackStorm -e "GRANT ALL PRIVILEGES ON mistral.* TO 'mistral'@'127.0.0.1' IDENTIFIED BY 'StackStorm'" - @mysql -uroot -pStackStorm -e "FLUSH PRIVILEGES" - @/opt/openstack/mistral/.venv/bin/python /opt/openstack/mistral/tools/sync_db.py --config-file /etc/mistral/mistral.conf - .PHONY: .cleanrabbitmq .cleanrabbitmq: @echo "==================== cleanrabbitmq ====================" @@ -479,7 +463,7 @@ compilepy3: @echo "Removing all coverage results directories" @echo rm -rf .coverage $(COVERAGE_GLOBS) \ - .coverage.unit .coverage.integration .coverage.mistral + .coverage.unit .coverage.integration .PHONY: distclean distclean: clean @@ -663,7 +647,7 @@ endif @echo @echo "----- Dropping st2-test db -----" @mongo st2-test --eval "db.dropDatabase();" - for component in $(COMPONENTS_TEST_WITHOUT_MISTRAL_RUNNER); do\ + for component in $(COMPONENTS_TEST); do\ echo "==========================================================="; \ echo "Running tests in" $$component; \ echo "-----------------------------------------------------------"; \ @@ -814,43 +798,8 @@ endif .PHONY: .itests-coverage-html .itests-coverage-html: .integration-tests-coverage-html -.PHONY: mistral-itests -mistral-itests: requirements .mistral-itests - -.PHONY: .mistral-itests -.mistral-itests: - @echo - @echo "==================== MISTRAL integration tests ====================" - @echo "The tests assume both st2 and mistral are running on 127.0.0.1." - @echo - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v st2tests/integration/mistral || exit 1; - -.PHONY: .run-mistral-itests-coverage -ifdef INCLUDE_TESTS_IN_COVERAGE -.run-mistral-itests-coverage: NOSE_COVERAGE_PACKAGES := $(NOSE_COVERAGE_PACKAGES),st2tests.mistral.integration -endif -.run-mistral-itests-coverage: - @echo - @echo "==================== MISTRAL integration tests with coverage ====================" - @echo "The tests assume both st2 and mistral are running on 127.0.0.1." - @echo - . $(VIRTUALENV_DIR)/bin/activate; \ - COVERAGE_FILE=.coverage.mistral.integration \ - nosetests $(NOSE_OPTS) -s -v $(NOSE_COVERAGE_FLAGS) \ - $(NOSE_COVERAGE_PACKAGES) \ - st2tests/integration/mistral || exit 1; - -.coverage.mistral.integration: - if [ ! -e .coverage.mistral.integration ]; then \ - make .run-mistral-itests-coverage; \ - fi - -.PHONY: .mistral-itests-coverage-html -.mistral-itests-coverage-html: .coverage.mistral.integration - . $(VIRTUALENV_DIR)/bin/activate; COVERAGE_FILE=.coverage.mistral.integration coverage html - .PHONY: .coverage-combine -.coverage-combine: .run-unit-tests-coverage .run-integration-tests-coverage .run-mistral-itests-coverage +.coverage-combine: .run-unit-tests-coverage .run-integration-tests-coverage . $(VIRTUALENV_DIR)/bin/activate; coverage combine $(COVERAGE_GLOBS) # This is a real target, but we need to do our own make trickery in case some @@ -992,7 +941,7 @@ debs: .PHONY: ci -ci: ci-checks ci-unit ci-integration ci-mistral ci-packs-tests +ci: ci-checks ci-unit ci-integration ci-packs-tests .PHONY: ci-checks ci-checks: compile .generated-files-check .pylint .flake8 check-requirements check-sdist-requirements .st2client-dependencies-check .st2common-circular-dependencies-check circle-lint-api-spec .rst-check .st2client-install-check check-python-packages @@ -1067,15 +1016,6 @@ ci-py3-integration: requirements .ci-prepare-integration .ci-py3-integration .PHONY: ci-unit ci-unit: .unit-tests-coverage-html -.PHONY: ci-unit-nightly -ci-unit-nightly: - # NOTE: We run mistral runner checks only as part of a nightly build to speed up - # non nightly builds (Mistral will be deprecated in the future) - @echo - @echo "============== ci-unit-nightly ==============" - @echo - . $(VIRTUALENV_DIR)/bin/activate; nosetests $(NOSE_OPTS) -s -v contrib/runners/mistral_v2/tests/unit - .PHONY: .ci-prepare-integration .ci-prepare-integration: sudo -E ./scripts/travis/prepare-integration.sh @@ -1086,13 +1026,6 @@ ci-integration: .ci-prepare-integration .itests-coverage-html .PHONY: ci-runners ci-runners: .ci-prepare-integration .runners-itests-coverage-html -.PHONY: .ci-prepare-mistral -.ci-prepare-mistral: - sudo -E ./scripts/travis/setup-mistral.sh - -.PHONY: ci-mistral -ci-mistral: .ci-prepare-integration .ci-prepare-mistral .mistral-itests-coverage-html - .PHONY: ci-orquesta ci-orquesta: .ci-prepare-integration .orquesta-itests-coverage-html diff --git a/conf/mistral.dev/README.md b/conf/mistral.dev/README.md deleted file mode 100644 index 9162916ca2..0000000000 --- a/conf/mistral.dev/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# FOR DEVELOPMENT PURPOSES ONLY - -These configuration files are for development purposes only. -For a proper Mistral configuration, please review [StackStorm](https://docs.stackstorm.com/index.html) and [Mistral](https://docs.openstack.org/mistral/latest/) documentation. diff --git a/conf/mistral.dev/logging.conf b/conf/mistral.dev/logging.conf deleted file mode 100755 index f2c7000dc2..0000000000 --- a/conf/mistral.dev/logging.conf +++ /dev/null @@ -1,32 +0,0 @@ -[loggers] -keys=root - -[handlers] -keys=consoleHandler, fileHandler - -[formatters] -keys=verboseFormatter, simpleFormatter - -[logger_root] -level=INFO -handlers=consoleHandler, fileHandler - -[handler_consoleHandler] -class=StreamHandler -level=INFO -formatter=simpleFormatter -args=(sys.stdout,) - -[handler_fileHandler] -class=FileHandler -level=INFO -formatter=verboseFormatter -args=("/var/log/mistral/mistral.log",) - -[formatter_verboseFormatter] -format=%(asctime)s %(thread)s %(levelname)s %(module)s [-] %(message)s -datefmt= - -[formatter_simpleFormatter] -format=%(asctime)s %(levelname)s [-] %(message)s -datefmt= diff --git a/conf/mistral.dev/mistral.dev.conf b/conf/mistral.dev/mistral.dev.conf deleted file mode 100644 index 0751aab079..0000000000 --- a/conf/mistral.dev/mistral.dev.conf +++ /dev/null @@ -1,9 +0,0 @@ -[DEFAULT] -transport_url = rabbit://guest:guest@127.0.0.1:5672 - -[database] -connection = postgresql://mistral:StackStorm@localhost/mistral -max_pool_size = 50 - -[pecan] -auth_enable = false diff --git a/conf/mistral.dev/policy.json b/conf/mistral.dev/policy.json deleted file mode 100644 index c5df702af3..0000000000 --- a/conf/mistral.dev/policy.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "admin_only": "is_admin:True", - "admin_or_owner": "is_admin:True or project_id:%(project_id)s", - "default": "rule:admin_or_owner", - - "action_executions:delete": "rule:admin_or_owner", - "action_execution:create": "rule:admin_or_owner", - "action_executions:get": "rule:admin_or_owner", - "action_executions:list": "rule:admin_or_owner", - "action_executions:update": "rule:admin_or_owner", - - "actions:create": "rule:admin_or_owner", - "actions:delete": "rule:admin_or_owner", - "actions:get": "rule:admin_or_owner", - "actions:list": "rule:admin_or_owner", - "actions:update": "rule:admin_or_owner", - - "cron_triggers:create": "rule:admin_or_owner", - "cron_triggers:delete": "rule:admin_or_owner", - "cron_triggers:get": "rule:admin_or_owner", - "cron_triggers:list": "rule:admin_or_owner", - - "environments:create": "rule:admin_or_owner", - "environments:delete": "rule:admin_or_owner", - "environments:get": "rule:admin_or_owner", - "environments:list": "rule:admin_or_owner", - "environments:update": "rule:admin_or_owner", - - "executions:create": "rule:admin_or_owner", - "executions:delete": "rule:admin_or_owner", - "executions:get": "rule:admin_or_owner", - "executions:list": "rule:admin_or_owner", - "executions:update": "rule:admin_or_owner", - - "members:create": "rule:admin_or_owner", - "members:delete": "rule:admin_or_owner", - "members:get": "rule:admin_or_owner", - "members:list": "rule:admin_or_owner", - "members:update": "rule:admin_or_owner", - - "services:list": "rule:admin_or_owner", - - "tasks:get": "rule:admin_or_owner", - "tasks:list": "rule:admin_or_owner", - "tasks:update": "rule:admin_or_owner", - - "workbooks:create": "rule:admin_or_owner", - "workbooks:delete": "rule:admin_or_owner", - "workbooks:get": "rule:admin_or_owner", - "workbooks:list": "rule:admin_or_owner", - "workbooks:update": "rule:admin_or_owner", - - "workflows:create": "rule:admin_or_owner", - "workflows:delete": "rule:admin_or_owner", - "workflows:get": "rule:admin_or_owner", - "workflows:list": "rule:admin_or_owner", - "workflows:update": "rule:admin_or_owner" -} diff --git a/conf/mistral.dev/wf_trace_logging.conf b/conf/mistral.dev/wf_trace_logging.conf deleted file mode 100755 index 6d4be9e012..0000000000 --- a/conf/mistral.dev/wf_trace_logging.conf +++ /dev/null @@ -1,62 +0,0 @@ -[loggers] -keys=workflow_trace,profiler_trace,root - -[handlers] -keys=consoleHandler, wfTraceFileHandler, profilerFileHandler, fileHandler - -[formatters] -keys=wfFormatter, profilerFormatter, simpleFormatter, verboseFormatter - -[logger_workflow_trace] -level=INFO -handlers=consoleHandler, wfTraceFileHandler -qualname=workflow_trace - -[logger_profiler_trace] -level=INFO -handlers=profilerFileHandler -qualname=profiler_trace - -[logger_root] -level=INFO -handlers=fileHandler - -[handler_fileHandler] -class=FileHandler -level=INFO -formatter=verboseFormatter -args=("/var/log/mistral/mistral.log",) - -[handler_consoleHandler] -class=StreamHandler -level=INFO -formatter=simpleFormatter -args=(sys.stdout,) - -[handler_wfTraceFileHandler] -class=FileHandler -level=INFO -formatter=wfFormatter -args=("/var/log/mistral/mistral_wf_trace.log",) - -[handler_profilerFileHandler] -class=FileHandler -level=INFO -formatter=profilerFormatter -args=("/var/log/mistral/mistral_osprofile.log",) - -[formatter_verboseFormatter] -format=%(asctime)s %(thread)s %(levelname)s %(module)s [-] %(message)s -datefmt= - -[formatter_simpleFormatter] -format=%(asctime)s %(levelname)s [-] %(message)s -datefmt= - -[formatter_wfFormatter] -format=%(asctime)s WF [-] %(message)s -datefmt= - -[formatter_profilerFormatter] -format=%(message)s -datefmt= diff --git a/contrib/examples/actions/chains/invoke_mistral_with_jinja.yaml b/contrib/examples/actions/chains/invoke_mistral_with_jinja.yaml deleted file mode 100644 index 154bbb067c..0000000000 --- a/contrib/examples/actions/chains/invoke_mistral_with_jinja.yaml +++ /dev/null @@ -1,12 +0,0 @@ -chain: - - - name: task1 - ref: examples.mistral-basic - params: - cmd: "{{cmd}}" - on-success: task2 - - - name: task2 - ref: examples.mistral-basic - parameters: - cmd: "{{cmd}}" diff --git a/contrib/examples/actions/chains/mistral_examples.yaml b/contrib/examples/actions/chains/mistral_examples.yaml deleted file mode 100644 index d2fcf7a4df..0000000000 --- a/contrib/examples/actions/chains/mistral_examples.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- - chain: - - - name: "mistral-basic" - ref: "examples.mistral-basic" - parameters: - cmd: "hostname" - on-success: "mistral-workbook-complex" - - - name: "mistral-workbook-complex" - ref: "examples.mistral-workbook-complex" - parameters: - vm_name: "fake-host-1" - default: "mistral-basic" diff --git a/contrib/examples/actions/invoke_mistral_with_jinja.yaml b/contrib/examples/actions/invoke_mistral_with_jinja.yaml deleted file mode 100644 index 89135fccb8..0000000000 --- a/contrib/examples/actions/invoke_mistral_with_jinja.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: invoke-mistral-with-jinja -description: Example to invoke a Mistral workflow from an Action Chain -runner_type: action-chain -entry_point: chains/invoke_mistral_with_jinja.yaml -enabled: true -parameters: - cmd: - type: string - required: true diff --git a/contrib/examples/actions/mistral-ask-basic.meta.yaml b/contrib/examples/actions/mistral-ask-basic.meta.yaml deleted file mode 100644 index 6650f86908..0000000000 --- a/contrib/examples/actions/mistral-ask-basic.meta.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: A basic Mistral workflow illustrating the use of Inquiries -enabled: true -entry_point: workflows/mistral-ask-basic.yaml -name: mistral-ask-basic -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-ask-parent.meta.yaml b/contrib/examples/actions/mistral-ask-parent.meta.yaml deleted file mode 100644 index 28cb6a68c2..0000000000 --- a/contrib/examples/actions/mistral-ask-parent.meta.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -description: > - Workflow for demonstrating "ask" functionality -enabled: true -entry_point: workflows/mistral-ask-parent.yaml -name: mistral-ask-parent -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-basic-two-tasks-with-notifications.yaml b/contrib/examples/actions/mistral-basic-two-tasks-with-notifications.yaml deleted file mode 100644 index 5a8cfe1cbd..0000000000 --- a/contrib/examples/actions/mistral-basic-two-tasks-with-notifications.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: mistral-basic-two-tasks-with-notifications -pack: examples -description: Run mistral workflow with two tasks. -runner_type: mistral-v2 -entry_point: workflows/mistral-basic-two-tasks-with-notifications.yaml -enabled: true -parameters: - skip_notify: - default: - - "task2" -notify: - on-complete: - message: "@channel: Action succeeded." - routes: - - "slack" diff --git a/contrib/examples/actions/mistral-basic.yaml b/contrib/examples/actions/mistral-basic.yaml deleted file mode 100644 index a5dfe0f0d7..0000000000 --- a/contrib/examples/actions/mistral-basic.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Run a local linux command -enabled: true -runner_type: mistral-v2 -entry_point: workflows/mistral-basic.yaml -name: mistral-basic -pack: examples -parameters: - cmd: - required: true - type: string - timeout: - type: integer - default: 60 diff --git a/contrib/examples/actions/mistral-branching.yaml b/contrib/examples/actions/mistral-branching.yaml deleted file mode 100644 index d02150808c..0000000000 --- a/contrib/examples/actions/mistral-branching.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: Demonstrate how to use condition to select branch of execution. -enabled: true -entry_point: workflows/mistral-branching.yaml -name: mistral-branching -pack: examples -parameters: - which: - type: string - required: true - enum: - - a - - b - - c -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-env-var.yaml b/contrib/examples/actions/mistral-env-var.yaml deleted file mode 100644 index 359573271e..0000000000 --- a/contrib/examples/actions/mistral-env-var.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: Example to return workflow's environment variable -enabled: true -entry_point: workflows/mistral-env-var.yaml -name: mistral-env-var -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-error-bad-action.yaml b/contrib/examples/actions/mistral-error-bad-action.yaml deleted file mode 100644 index 10fb65e03c..0000000000 --- a/contrib/examples/actions/mistral-error-bad-action.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: A sample workflow for testing error handling if action does not exist. -enabled: true -entry_point: workflows/tests/mistral-error-bad-action.yaml -name: mistral-error-bad-action -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-error-bad-task-transition.yaml b/contrib/examples/actions/mistral-error-bad-task-transition.yaml deleted file mode 100644 index e5623ea73f..0000000000 --- a/contrib/examples/actions/mistral-error-bad-task-transition.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: A sample workflow used to test bad task transition statement. -enabled: true -entry_point: workflows/tests/mistral-error-bad-task-transition.yaml -name: mistral-error-bad-task-transition -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-error-bad-wf-arg.yaml b/contrib/examples/actions/mistral-error-bad-wf-arg.yaml deleted file mode 100644 index 75bac1a861..0000000000 --- a/contrib/examples/actions/mistral-error-bad-wf-arg.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: A sample workflow for testing bad input passed to subworkflow. -enabled: true -entry_point: workflows/tests/mistral-error-bad-wf-arg.yaml -name: mistral-error-bad-wf-arg -pack: examples -runner_type: mistral-v2 -parameters: - workflow: - default: examples.mistral-error-bad-wf-arg.wf1 - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-error-bad-with-items.yaml b/contrib/examples/actions/mistral-error-bad-with-items.yaml deleted file mode 100644 index a60ed4e88a..0000000000 --- a/contrib/examples/actions/mistral-error-bad-with-items.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: A sample workflow for testing bad input to with-items statement. -enabled: true -entry_point: workflows/tests/mistral-error-bad-with-items.yaml -name: mistral-error-bad-with-items -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-handle-error-task-default.yaml b/contrib/examples/actions/mistral-handle-error-task-default.yaml deleted file mode 100644 index d6c3c629a3..0000000000 --- a/contrib/examples/actions/mistral-handle-error-task-default.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: Workflow example for error handling. -enabled: true -entry_point: workflows/mistral-handle-error-task-default.yaml -name: mistral-handle-error-task-default -pack: examples -parameters: - cmd: - default: foobar - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-handle-error.yaml b/contrib/examples/actions/mistral-handle-error.yaml deleted file mode 100644 index 257f97ba0a..0000000000 --- a/contrib/examples/actions/mistral-handle-error.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: Workflow example for error handling. -enabled: true -entry_point: workflows/mistral-handle-error.yaml -name: mistral-handle-error -pack: examples -parameters: - cmd: - default: foobar - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-handle-retry.yaml b/contrib/examples/actions/mistral-handle-retry.yaml deleted file mode 100644 index 4769bd07a7..0000000000 --- a/contrib/examples/actions/mistral-handle-retry.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: Workflow example for error, rollback, and retry. -enabled: true -entry_point: workflows/mistral-handle-retry.yaml -name: mistral-handle-retry -pack: examples -parameters: - workflow: - default: examples.mistral-handle-retry.main - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-branching.yaml b/contrib/examples/actions/mistral-jinja-branching.yaml deleted file mode 100644 index 3d652d9e09..0000000000 --- a/contrib/examples/actions/mistral-jinja-branching.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: Demonstrate how to use condition to select branch of execution. -enabled: true -entry_point: workflows/mistral-jinja-branching.yaml -name: mistral-jinja-branching -pack: examples -parameters: - which: - type: string - required: true - enum: - - a - - b - - c -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-env-var.yaml b/contrib/examples/actions/mistral-jinja-env-var.yaml deleted file mode 100644 index 1dfc3f828e..0000000000 --- a/contrib/examples/actions/mistral-jinja-env-var.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: Example to return workflow's environment variable -enabled: true -entry_point: workflows/mistral-jinja-env-var.yaml -name: mistral-jinja-env-var -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-repeat-with-items.yaml b/contrib/examples/actions/mistral-jinja-repeat-with-items.yaml deleted file mode 100644 index b6d5ca85db..0000000000 --- a/contrib/examples/actions/mistral-jinja-repeat-with-items.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -description: Run several linux commands in a single task. -enabled: true -entry_point: workflows/mistral-jinja-repeat-with-items.yaml -name: mistral-jinja-repeat-with-items -pack: examples -parameters: - cmds: - items: - type: string - minItems: 1 - type: array -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-st2kv-system-scope-encrypted.yaml b/contrib/examples/actions/mistral-jinja-st2kv-system-scope-encrypted.yaml deleted file mode 100644 index 1aa57fb1c1..0000000000 --- a/contrib/examples/actions/mistral-jinja-st2kv-system-scope-encrypted.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: > - A sample workflow that accesses st2kv via jinja - to get an encrypted system scope kvp from st2. -enabled: true -entry_point: workflows/mistral-jinja-st2kv-system-scope-encrypted.yaml -name: mistral-jinja-st2kv-system-scope-encrypted -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-st2kv-system-scope.yaml b/contrib/examples/actions/mistral-jinja-st2kv-system-scope.yaml deleted file mode 100644 index abd7333471..0000000000 --- a/contrib/examples/actions/mistral-jinja-st2kv-system-scope.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: > - A sample workflow that accesses st2kv via jinja - to get a system scope kvp from st2. -enabled: true -entry_point: workflows/mistral-jinja-st2kv-system-scope.yaml -name: mistral-jinja-st2kv-system-scope -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-jinja-workbook-complex.yaml b/contrib/examples/actions/mistral-jinja-workbook-complex.yaml deleted file mode 100644 index 2fd8ed8c02..0000000000 --- a/contrib/examples/actions/mistral-jinja-workbook-complex.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -description: Run a series of simulated actions. -enabled: true -entry_point: workflows/mistral-jinja-workbook-complex.yaml -name: mistral-jinja-workbook-complex -pack: examples -parameters: - cpu_cores: - default: 1 - type: integer - memory_mb: - default: 1024 - type: integer - vm_name: - required: true - type: string - workflow: - default: examples.mistral-jinja-workbook-complex.main - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-join.yaml b/contrib/examples/actions/mistral-join.yaml deleted file mode 100644 index c5f98be101..0000000000 --- a/contrib/examples/actions/mistral-join.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: Demonstrate how to join multiple parallel branches. -enabled: true -entry_point: workflows/mistral-join.yaml -name: mistral-join -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-repeat-with-items.yaml b/contrib/examples/actions/mistral-repeat-with-items.yaml deleted file mode 100644 index 0382f8992f..0000000000 --- a/contrib/examples/actions/mistral-repeat-with-items.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -description: Run several linux commands in a single task. -enabled: true -entry_point: workflows/mistral-repeat-with-items.yaml -name: mistral-repeat-with-items -pack: examples -parameters: - cmds: - items: - type: string - minItems: 1 - type: array -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-repeat.yaml b/contrib/examples/actions/mistral-repeat.yaml deleted file mode 100644 index dc102ce094..0000000000 --- a/contrib/examples/actions/mistral-repeat.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Repeat a local linux command for given number of times. -enabled: true -entry_point: workflows/mistral-repeat.yaml -name: mistral-repeat -pack: examples -parameters: - cmd: - required: true - type: string - count: - default: 3 - type: integer -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-reverse-basic.yaml b/contrib/examples/actions/mistral-reverse-basic.yaml deleted file mode 100644 index f1f8fec3f8..0000000000 --- a/contrib/examples/actions/mistral-reverse-basic.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -description: Run a local linux command -enabled: true -runner_type: mistral-v2 -entry_point: workflows/mistral-reverse-basic.yaml -name: mistral-reverse-basic -pack: examples -parameters: - cmd: - required: true - type: string - timeout: - type: integer - default: 60 - task_name: - immutable: true - default: task1 - type: string diff --git a/contrib/examples/actions/mistral-reverse-requires.yaml b/contrib/examples/actions/mistral-reverse-requires.yaml deleted file mode 100644 index 87eaa335dd..0000000000 --- a/contrib/examples/actions/mistral-reverse-requires.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -description: Demonstrate parallel branches via requires in reverse workflow. -enabled: true -runner_type: mistral-v2 -entry_point: workflows/mistral-reverse-requires.yaml -name: mistral-reverse-requires -pack: examples -parameters: - question: - required: true - type: string - task_name: - immutable: true - default: e - type: string diff --git a/contrib/examples/actions/mistral-streaming-demo.meta.yaml b/contrib/examples/actions/mistral-streaming-demo.meta.yaml deleted file mode 100644 index 0e2b3ccfc2..0000000000 --- a/contrib/examples/actions/mistral-streaming-demo.meta.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: "mistral-streaming-demo" -description: "Action output streaming functionality demo for Mistral workflows." -runner_type: "mistral-v2" -entry_point: "workflows/mistral-streaming-demo.yaml" -enabled: true -parameters: - count: - type: "integer" - required: true - default: 5 - sleep_delay: - type: "number" - required: true - default: 0.2 diff --git a/contrib/examples/actions/mistral-test-cancel-subworkflow-action.yaml b/contrib/examples/actions/mistral-test-cancel-subworkflow-action.yaml deleted file mode 100644 index c3826821ba..0000000000 --- a/contrib/examples/actions/mistral-test-cancel-subworkflow-action.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-cancel-subworkflow-action -description: A sample workflow used to test the cascading cancel of subworkflow action. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-cancel-subworkflow-action.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-cancel-subworkflow-chain.yaml b/contrib/examples/actions/mistral-test-cancel-subworkflow-chain.yaml deleted file mode 100644 index c35eca4d1e..0000000000 --- a/contrib/examples/actions/mistral-test-cancel-subworkflow-chain.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-cancel-subworkflow-chain -description: A sample workflow used to test the cascading cancellation of subchain. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-cancel-subworkflow-chain.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-cancel.yaml b/contrib/examples/actions/mistral-test-cancel.yaml deleted file mode 100644 index f530334bb9..0000000000 --- a/contrib/examples/actions/mistral-test-cancel.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-cancel -description: A sample workflow used to test the cancel feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-cancel.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-func-from-json-string.yaml b/contrib/examples/actions/mistral-test-func-from-json-string.yaml deleted file mode 100644 index 1f2224e911..0000000000 --- a/contrib/examples/actions/mistral-test-func-from-json-string.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-from-json-string -description: Example for using the custom filter "from_json_string" -enabled: true -entry_point: workflows/tests/mistral-test-func-from-json-string.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_str: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-from-yaml-string.yaml b/contrib/examples/actions/mistral-test-func-from-yaml-string.yaml deleted file mode 100644 index eac973e044..0000000000 --- a/contrib/examples/actions/mistral-test-func-from-yaml-string.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-from-yaml-string -description: Example for using the custom filter "from_yaml_string" -enabled: true -entry_point: workflows/tests/mistral-test-func-from-yaml-string.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_str: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-json-escape.yaml b/contrib/examples/actions/mistral-test-func-json-escape.yaml deleted file mode 100644 index 4973e06916..0000000000 --- a/contrib/examples/actions/mistral-test-func-json-escape.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-json-escape -description: Test json_escape custom filter in mistral -enabled: true -entry_point: workflows/tests/mistral-test-func-json-escape.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_str: - type: "string" - required: true diff --git a/contrib/examples/actions/mistral-test-func-jsonpath-query.yaml b/contrib/examples/actions/mistral-test-func-jsonpath-query.yaml deleted file mode 100644 index 53be88d3d3..0000000000 --- a/contrib/examples/actions/mistral-test-func-jsonpath-query.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-jsonpath-query -description: Test jsonpath_query custom filter in mistral -enabled: true -entry_point: workflows/tests/mistral-test-func-jsonpath-query.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_obj: - type: object - required: true - input_query: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-func-regex-match.yaml b/contrib/examples/actions/mistral-test-func-regex-match.yaml deleted file mode 100644 index 564390b0d9..0000000000 --- a/contrib/examples/actions/mistral-test-func-regex-match.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-regex-match -description: Test regex_match custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-regex-match.yaml -pack: examples -parameters: - input_str: - required: true - type: string - regex_pattern: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-regex-replace.yaml b/contrib/examples/actions/mistral-test-func-regex-replace.yaml deleted file mode 100644 index 1b5f3c7a3b..0000000000 --- a/contrib/examples/actions/mistral-test-func-regex-replace.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: mistral-test-func-regex-replace -description: Test regex_replace custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-regex-replace.yaml -pack: examples -parameters: - input_str: - required: true - type: string - regex_pattern: - required: true - type: string - replacement_str: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-regex-search.yaml b/contrib/examples/actions/mistral-test-func-regex-search.yaml deleted file mode 100644 index 27ac831cfb..0000000000 --- a/contrib/examples/actions/mistral-test-func-regex-search.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-regex-search -description: Test regex_search custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-regex-search.yaml -pack: examples -parameters: - input_str: - required: true - type: string - regex_pattern: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-regex-substring.yaml b/contrib/examples/actions/mistral-test-func-regex-substring.yaml deleted file mode 100644 index d745c1f38f..0000000000 --- a/contrib/examples/actions/mistral-test-func-regex-substring.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-regex-substring -description: Test regex_substring custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-regex-substring.yaml -pack: examples -parameters: - input_str: - required: true - type: string - regex_pattern: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-to-complex.yaml b/contrib/examples/actions/mistral-test-func-to-complex.yaml deleted file mode 100644 index 12e3b42850..0000000000 --- a/contrib/examples/actions/mistral-test-func-to-complex.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-to-complex -description: Example for using the custom filter "to_complex" -enabled: true -entry_point: workflows/tests/mistral-test-func-to-complex.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_obj: - required: true - type: object diff --git a/contrib/examples/actions/mistral-test-func-to-human-time-from-seconds.yaml b/contrib/examples/actions/mistral-test-func-to-human-time-from-seconds.yaml deleted file mode 100644 index 1ee00e0efb..0000000000 --- a/contrib/examples/actions/mistral-test-func-to-human-time-from-seconds.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-to-human-time-from-seconds -description: Test to_human_time_from_seconds custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-to-human-time-from-seconds.yaml -pack: examples -parameters: - seconds: - required: true - type: integer diff --git a/contrib/examples/actions/mistral-test-func-to-json-string.yaml b/contrib/examples/actions/mistral-test-func-to-json-string.yaml deleted file mode 100644 index 9fb083d171..0000000000 --- a/contrib/examples/actions/mistral-test-func-to-json-string.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-to-json-string -description: Example for using the custom filter "to_json_string" -enabled: true -entry_point: workflows/tests/mistral-test-func-to-json-string.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_obj: - required: true - type: object diff --git a/contrib/examples/actions/mistral-test-func-to-yaml-string.yaml b/contrib/examples/actions/mistral-test-func-to-yaml-string.yaml deleted file mode 100644 index 1c12fe684a..0000000000 --- a/contrib/examples/actions/mistral-test-func-to-yaml-string.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-to-yaml-string -description: Example for using the custom filter "to_yaml_string" -enabled: true -entry_point: workflows/tests/mistral-test-func-to-yaml-string.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_obj: - required: true - type: object diff --git a/contrib/examples/actions/mistral-test-func-use-none.yaml b/contrib/examples/actions/mistral-test-func-use-none.yaml deleted file mode 100644 index 471c64d5ec..0000000000 --- a/contrib/examples/actions/mistral-test-func-use-none.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-use-none -description: Example for using the custom filter "use_none" -enabled: true -entry_point: workflows/tests/mistral-test-func-use-none.yaml -pack: examples -runner_type: mistral-v2 -parameters: - input_str: - type: "string" - required: true diff --git a/contrib/examples/actions/mistral-test-func-version-bump-major.yaml b/contrib/examples/actions/mistral-test-func-version-bump-major.yaml deleted file mode 100644 index 1915e322cd..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-bump-major.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-version-bump-major -description: Test version_bump_major custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-bump-major.yaml -pack: examples -parameters: - version: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-bump-minor.yaml b/contrib/examples/actions/mistral-test-func-version-bump-minor.yaml deleted file mode 100644 index 3a9d1f9e06..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-bump-minor.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-version-bump-minor -description: Test version_bump_minor custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-bump-minor.yaml -pack: examples -parameters: - version: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-bump-patch.yaml b/contrib/examples/actions/mistral-test-func-version-bump-patch.yaml deleted file mode 100644 index 19265c5f6d..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-bump-patch.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-version-bump-patch -description: Test version_bump_patch custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-bump-patch.yaml -pack: examples -parameters: - version: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-compare.yaml b/contrib/examples/actions/mistral-test-func-version-compare.yaml deleted file mode 100644 index 4e30cbae4d..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-compare.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-version-compare -description: Test version_compare custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-compare.yaml -pack: examples -parameters: - version_a: - required: true - type: string - version_b: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-equal.yaml b/contrib/examples/actions/mistral-test-func-version-equal.yaml deleted file mode 100644 index 25968b6482..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-equal.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-version-equal -description: Test version_equal custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-equal.yaml -pack: examples -parameters: - version_a: - required: true - type: string - version_b: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-less-than.yaml b/contrib/examples/actions/mistral-test-func-version-less-than.yaml deleted file mode 100644 index 594f99c979..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-less-than.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-version-less-than -description: Test version_less_than custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-less-than.yaml -pack: examples -parameters: - version_a: - required: true - type: string - version_b: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-match.yaml b/contrib/examples/actions/mistral-test-func-version-match.yaml deleted file mode 100644 index 96cd5d2b7a..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-match.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-version-match -description: Test version_match custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-match.yaml -pack: examples -parameters: - version_a: - required: true - type: string - version_b: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-more-than.yaml b/contrib/examples/actions/mistral-test-func-version-more-than.yaml deleted file mode 100644 index 4057c643a4..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-more-than.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-func-version-more-than -description: Test version_more_than custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-more-than.yaml -pack: examples -parameters: - version_a: - required: true - type: string - version_b: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-func-version-strip-patch.yaml b/contrib/examples/actions/mistral-test-func-version-strip-patch.yaml deleted file mode 100644 index d4cac0b361..0000000000 --- a/contrib/examples/actions/mistral-test-func-version-strip-patch.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-func-version-strip-patch -description: Test version_strip_patch custom filter in mistral -enabled: true -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-func-version-strip-patch.yaml -pack: examples -parameters: - version: - required: true - type: string diff --git a/contrib/examples/actions/mistral-test-jinja-bad-expr.yaml b/contrib/examples/actions/mistral-test-jinja-bad-expr.yaml deleted file mode 100644 index aef5be94f0..0000000000 --- a/contrib/examples/actions/mistral-test-jinja-bad-expr.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-jinja-bad-expr -pack: examples -description: A basic workflow for testing Jinja evaluation error. -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-jinja-bad-expr.yaml -enabled: true diff --git a/contrib/examples/actions/mistral-test-jinja-bad-publish.yaml b/contrib/examples/actions/mistral-test-jinja-bad-publish.yaml deleted file mode 100644 index fefd38129f..0000000000 --- a/contrib/examples/actions/mistral-test-jinja-bad-publish.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-jinja-bad-publish -pack: examples -description: A basic workflow for testing Jinja evaluation error. -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-jinja-bad-publish.yaml -enabled: true diff --git a/contrib/examples/actions/mistral-test-jinja-bad-subworkflow-input.yaml b/contrib/examples/actions/mistral-test-jinja-bad-subworkflow-input.yaml deleted file mode 100644 index 7c71a31d2c..0000000000 --- a/contrib/examples/actions/mistral-test-jinja-bad-subworkflow-input.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: mistral-test-jinja-bad-subworkflow-input -pack: examples -description: A sample workflow for testing bad input passed to subworkflow. -enabled: true -entry_point: workflows/tests/mistral-test-jinja-bad-subworkflow-input.yaml -runner_type: mistral-v2 -parameters: - workflow: - default: examples.mistral-test-jinja-bad-subworkflow-input.wf1 - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-jinja-bad-task-transition.yaml b/contrib/examples/actions/mistral-test-jinja-bad-task-transition.yaml deleted file mode 100644 index 57a55b287f..0000000000 --- a/contrib/examples/actions/mistral-test-jinja-bad-task-transition.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-jinja-bad-task-transition -pack: examples -description: A sample workflow used to test bad task transition statement. -enabled: true -entry_point: workflows/tests/mistral-test-jinja-bad-task-transition.yaml -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-test-jinja-bad-with-items.yaml b/contrib/examples/actions/mistral-test-jinja-bad-with-items.yaml deleted file mode 100644 index 419932ecf3..0000000000 --- a/contrib/examples/actions/mistral-test-jinja-bad-with-items.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-jinja-bad-with-items -pack: examples -description: A sample workflow for testing bad input to with-items statement. -enabled: true -entry_point: workflows/tests/mistral-test-jinja-bad-with-items.yaml -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-action.yaml b/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-action.yaml deleted file mode 100644 index 748b097cc6..0000000000 --- a/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-action.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-pause-before-task-subworkflow-action -description: A sample workflow used to test the cascading pause and resume of subworkflow action. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-before-task-subworkflow-action.yaml -enabled: true -parameters: - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-workbook.yaml b/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-workbook.yaml deleted file mode 100644 index 0312b45382..0000000000 --- a/contrib/examples/actions/mistral-test-pause-before-task-subworkflow-workbook.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: mistral-test-pause-before-task-subworkflow-workbook -description: A sample workbook used to test the cascading pause and resume of subworkflow. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-before-task-subworkflow-workbook.yaml -enabled: true -parameters: - message: - type: string - required: true - workflow: - default: examples.mistral-test-pause-before-task-subworkflow-workbook.main - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-pause-before-task.yaml b/contrib/examples/actions/mistral-test-pause-before-task.yaml deleted file mode 100644 index bf6e2036d3..0000000000 --- a/contrib/examples/actions/mistral-test-pause-before-task.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-pause-before-task -description: A sample workflow used to test auto pause specified in the task. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-before-task.yaml -enabled: true -parameters: - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-action.yaml b/contrib/examples/actions/mistral-test-pause-resume-subworkflow-action.yaml deleted file mode 100644 index 63259f8887..0000000000 --- a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-action.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-pause-resume-subworkflow-action -description: A sample workflow used to test the cascading pause and resume of subworkflow action. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-resume-subworkflow-action.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-chain.yaml b/contrib/examples/actions/mistral-test-pause-resume-subworkflow-chain.yaml deleted file mode 100644 index 892ff254eb..0000000000 --- a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-chain.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-pause-resume-subworkflow-chain -description: A sample workflow used to test the cascading pause and resume of subchain. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-resume-subworkflow-chain.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-workbook.yaml b/contrib/examples/actions/mistral-test-pause-resume-subworkflow-workbook.yaml deleted file mode 100644 index 05741d47da..0000000000 --- a/contrib/examples/actions/mistral-test-pause-resume-subworkflow-workbook.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: mistral-test-pause-resume-subworkflow-workbook -description: A sample workbook used to test the cascading pause and resume of subworkflow. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-resume-subworkflow-workbook.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true - workflow: - default: examples.mistral-test-pause-resume-subworkflow-workbook.main - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-pause-resume.yaml b/contrib/examples/actions/mistral-test-pause-resume.yaml deleted file mode 100644 index d590dbb4aa..0000000000 --- a/contrib/examples/actions/mistral-test-pause-resume.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: mistral-test-pause-resume -description: A sample workflow used to test the pause and resume feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-pause-resume.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - message: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-rerun-subflow-with-items.yaml b/contrib/examples/actions/mistral-test-rerun-subflow-with-items.yaml deleted file mode 100644 index c7ffd41b51..0000000000 --- a/contrib/examples/actions/mistral-test-rerun-subflow-with-items.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: mistral-test-rerun-subflow-with-items -description: A sample workflow used to test the rerun feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-rerun-subflow-with-items.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - workflow: - default: examples.mistral-test-rerun-subflow-with-items.main - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-rerun-subflow.yaml b/contrib/examples/actions/mistral-test-rerun-subflow.yaml deleted file mode 100644 index 235e39e346..0000000000 --- a/contrib/examples/actions/mistral-test-rerun-subflow.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -name: mistral-test-rerun-subflow -description: A sample workflow used to test the rerun feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-rerun-subflow.yaml -enabled: true -parameters: - tempfile: - type: string - required: true - workflow: - default: examples.mistral-test-rerun-subflow.main - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-rerun-with-items.yaml b/contrib/examples/actions/mistral-test-rerun-with-items.yaml deleted file mode 100644 index c27c5418f8..0000000000 --- a/contrib/examples/actions/mistral-test-rerun-with-items.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-rerun-with-items -description: A sample workflow used to test the rerun feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-rerun-with-items.yaml -enabled: true -parameters: - tempfile: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-rerun.yaml b/contrib/examples/actions/mistral-test-rerun.yaml deleted file mode 100644 index c030ae9b9a..0000000000 --- a/contrib/examples/actions/mistral-test-rerun.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: mistral-test-rerun -description: A sample workflow used to test the rerun feature. -pack: examples -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-rerun.yaml -enabled: true -parameters: - tempfile: - type: string - required: true diff --git a/contrib/examples/actions/mistral-test-yaql-bad-expr.yaml b/contrib/examples/actions/mistral-test-yaql-bad-expr.yaml deleted file mode 100644 index 21cf422b2c..0000000000 --- a/contrib/examples/actions/mistral-test-yaql-bad-expr.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-yaql-bad-expr -pack: examples -description: A basic workflow for testing YAQL evaluation error. -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-yaql-bad-expr.yaml -enabled: true diff --git a/contrib/examples/actions/mistral-test-yaql-bad-publish.yaml b/contrib/examples/actions/mistral-test-yaql-bad-publish.yaml deleted file mode 100644 index e6f1f3a089..0000000000 --- a/contrib/examples/actions/mistral-test-yaql-bad-publish.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-yaql-bad-publish -pack: examples -description: A basic workflow for testing YAQL evaluation error. -runner_type: mistral-v2 -entry_point: workflows/tests/mistral-test-yaql-bad-publish.yaml -enabled: true diff --git a/contrib/examples/actions/mistral-test-yaql-bad-subworkflow-input.yaml b/contrib/examples/actions/mistral-test-yaql-bad-subworkflow-input.yaml deleted file mode 100644 index d9e2c6535a..0000000000 --- a/contrib/examples/actions/mistral-test-yaql-bad-subworkflow-input.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: mistral-test-yaql-bad-subworkflow-input -pack: examples -description: A sample workflow for testing bad input passed to subworkflow. -enabled: true -entry_point: workflows/tests/mistral-test-yaql-bad-subworkflow-input.yaml -runner_type: mistral-v2 -parameters: - workflow: - default: examples.mistral-test-yaql-bad-subworkflow-input.wf1 - immutable: true - type: string diff --git a/contrib/examples/actions/mistral-test-yaql-bad-task-transition.yaml b/contrib/examples/actions/mistral-test-yaql-bad-task-transition.yaml deleted file mode 100644 index 94539285e0..0000000000 --- a/contrib/examples/actions/mistral-test-yaql-bad-task-transition.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-yaql-bad-task-transition -pack: examples -description: A sample workflow used to test bad task transition statement. -enabled: true -entry_point: workflows/tests/mistral-test-yaql-bad-task-transition.yaml -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-test-yaql-bad-with-items.yaml b/contrib/examples/actions/mistral-test-yaql-bad-with-items.yaml deleted file mode 100644 index fe70e2bd0d..0000000000 --- a/contrib/examples/actions/mistral-test-yaql-bad-with-items.yaml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: mistral-test-yaql-bad-with-items -pack: examples -description: A sample workflow for testing bad input to with-items statement. -enabled: true -entry_point: workflows/tests/mistral-test-yaql-bad-with-items.yaml -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-with-items-concurrency.yaml b/contrib/examples/actions/mistral-with-items-concurrency.yaml deleted file mode 100644 index ceaa492a4f..0000000000 --- a/contrib/examples/actions/mistral-with-items-concurrency.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Repeat a local linux command for given number of times. -enabled: true -entry_point: workflows/mistral-with-items-concurrency.yaml -name: mistral-with-items-concurrency -pack: examples -parameters: - cmd: - required: true - type: string - count: - default: 6 - type: integer -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-workbook-basic.yaml b/contrib/examples/actions/mistral-workbook-basic.yaml deleted file mode 100644 index a69ce5029f..0000000000 --- a/contrib/examples/actions/mistral-workbook-basic.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -description: Run a local linux command -enabled: true -entry_point: workflows/mistral-workbook-basic.yaml -name: mistral-workbook-basic -pack: examples -parameters: - cmd: - required: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-workbook-complex.yaml b/contrib/examples/actions/mistral-workbook-complex.yaml deleted file mode 100644 index cbbdd00802..0000000000 --- a/contrib/examples/actions/mistral-workbook-complex.yaml +++ /dev/null @@ -1,21 +0,0 @@ ---- -description: Run a series of simulated actions. -enabled: true -entry_point: workflows/mistral-workbook-complex.yaml -name: mistral-workbook-complex -pack: examples -parameters: - cpu_cores: - default: 1 - type: integer - memory_mb: - default: 1024 - type: integer - vm_name: - required: true - type: string - workflow: - default: examples.mistral-workbook-complex.main - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-workbook-multiple-subflows.yaml b/contrib/examples/actions/mistral-workbook-multiple-subflows.yaml deleted file mode 100644 index c71629e3a2..0000000000 --- a/contrib/examples/actions/mistral-workbook-multiple-subflows.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -description: Run a series of subflows to illustrate some uncommon cases. -enabled: true -entry_point: workflows/mistral-workbook-multiple-subflows.yaml -name: mistral-workbook-multiple-subflows -pack: examples -parameters: - workflow: - default: examples.mistral-workbook-multiple-subflows.main - immutable: true - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-workbook-subflows.yaml b/contrib/examples/actions/mistral-workbook-subflows.yaml deleted file mode 100644 index dc8b4581c4..0000000000 --- a/contrib/examples/actions/mistral-workbook-subflows.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Test the output for a series of mistral-basic workflows. -enabled: true -entry_point: workflows/mistral-workbook-subflows.yaml -name: mistral-workbook-subflows -pack: examples -parameters: - adjective: - default: awesome - type: string - subject: - default: StackStorm - type: string -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-yaql-st2kv-system-scope.yaml b/contrib/examples/actions/mistral-yaql-st2kv-system-scope.yaml deleted file mode 100644 index e0385fc3ba..0000000000 --- a/contrib/examples/actions/mistral-yaql-st2kv-system-scope.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: > - A sample workflow that uses the YAQL function - st2kv to get a system scope kvp from st2. -enabled: true -entry_point: workflows/mistral-yaql-st2kv-system-scope.yaml -name: mistral-yaql-st2kv-system-scope -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral-yaql-st2kv-user-scope.yaml b/contrib/examples/actions/mistral-yaql-st2kv-user-scope.yaml deleted file mode 100644 index 2062061f09..0000000000 --- a/contrib/examples/actions/mistral-yaql-st2kv-user-scope.yaml +++ /dev/null @@ -1,9 +0,0 @@ ---- -description: > - A sample workflow that uses the YAQL function - st2kv to get a user scope kvp from st2. -enabled: true -entry_point: workflows/mistral-yaql-st2kv-user-scope.yaml -name: mistral-yaql-st2kv-user-scope -pack: examples -runner_type: mistral-v2 diff --git a/contrib/examples/actions/mistral_examples.meta.yaml b/contrib/examples/actions/mistral_examples.meta.yaml deleted file mode 100644 index cae8faa711..0000000000 --- a/contrib/examples/actions/mistral_examples.meta.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# Action definition metadata -name: "mistral_examples" -description: "Run selected Mistral examples" - -# `runner_type` has value `action-chain` to identify that action is an ActionChain. -runner_type: "action-chain" - -# `entry_point` path to the ActionChain definition file, relative to the pack's action directory. -entry_point: "chains/mistral_examples.yaml" - -enabled: true -parameters: {} diff --git a/contrib/examples/actions/workflows/mistral-ask-basic.yaml b/contrib/examples/actions/workflows/mistral-ask-basic.yaml deleted file mode 100644 index de84f691c0..0000000000 --- a/contrib/examples/actions/workflows/mistral-ask-basic.yaml +++ /dev/null @@ -1,26 +0,0 @@ -version: '2.0' - -examples.mistral-ask-basic: - description: A basic Mistral workflow illustrating the use of Inquiries - type: direct - output: - result: <% task(task1).result.response %> - tasks: - task1: - action: core.ask - input: - route: developers - schema: - type: object - properties: - secondfactor: - type: string - description: Please enter second factor for authenticating to "foo" service - required: True - on-success: - - task2 - - task2: - action: core.local - input: - cmd: echo "We can now authenticate to 'foo' service with <% task(task1).result.response.secondfactor %>" diff --git a/contrib/examples/actions/workflows/mistral-ask-parent.yaml b/contrib/examples/actions/workflows/mistral-ask-parent.yaml deleted file mode 100644 index 8b125066e1..0000000000 --- a/contrib/examples/actions/workflows/mistral-ask-parent.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: '2.0' - -examples.mistral-ask-parent: - description: A workflow for testing core.ask's ability to pause nested workflows - type: direct - output: - result: <% task(task1).result.result %> - tasks: - task1: - action: examples.mistral-ask-basic diff --git a/contrib/examples/actions/workflows/mistral-basic-two-tasks-with-notifications.yaml b/contrib/examples/actions/workflows/mistral-basic-two-tasks-with-notifications.yaml deleted file mode 100644 index 71a11f3d2f..0000000000 --- a/contrib/examples/actions/workflows/mistral-basic-two-tasks-with-notifications.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-basic-two-tasks-with-notifications: - description: A basic workflow that runs two Linux commands (one in each task). - type: direct - output: - stdout: <% $.stdout %> - tasks: - task1: - action: core.local cmd="echo task1" - publish: - stdout: <% task(task1).result.stdout %> - stderr: <% task(task1).result.stderr %> - task2: - action: core.local cmd="echo task2" - publish: - stdout: <% task(task2).result.stdout %> - stderr: <% task(task2).result.stderr %> diff --git a/contrib/examples/actions/workflows/mistral-basic.yaml b/contrib/examples/actions/workflows/mistral-basic.yaml deleted file mode 100644 index 03f662514e..0000000000 --- a/contrib/examples/actions/workflows/mistral-basic.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-basic: - description: A basic workflow that runs an arbitrary linux command. - type: direct - input: - - cmd - - timeout - output: - stdout: <% $.stdout %> - tasks: - task1: - action: core.local cmd=<% $.cmd %> timeout=<% $.timeout %> - publish: - stdout: <% task(task1).result.stdout %> - stderr: <% task(task1).result.stderr %> diff --git a/contrib/examples/actions/workflows/mistral-branching.yaml b/contrib/examples/actions/workflows/mistral-branching.yaml deleted file mode 100644 index 01f03a4e98..0000000000 --- a/contrib/examples/actions/workflows/mistral-branching.yaml +++ /dev/null @@ -1,38 +0,0 @@ -version: '2.0' - -examples.mistral-branching: - description: > - A sample workflow that demonstrates how to use conditions - to determine which path in the workflow to take. - type: direct - input: - - which - tasks: - t1: - action: core.local - input: - cmd: "printf <% $.which %>" - publish: - path: <% task(t1).result.stdout %> - on-success: - - a: <% $.path = 'a' %> - - b: <% $.path = 'b' %> - - c: <% not $.path in list(a, b) %> - a: - action: core.local - input: - cmd: "echo 'Took path A.'" - publish: - stdout: <% task(a).result.stdout %> - b: - action: core.local - input: - cmd: "echo 'Took path B.'" - publish: - stdout: <% task(b).result.stdout %> - c: - action: core.local - input: - cmd: "echo 'Took path C.'" - publish: - stdout: <% task(c).result.stdout %> diff --git a/contrib/examples/actions/workflows/mistral-env-var.yaml b/contrib/examples/actions/workflows/mistral-env-var.yaml deleted file mode 100644 index e33c5bf19e..0000000000 --- a/contrib/examples/actions/workflows/mistral-env-var.yaml +++ /dev/null @@ -1,15 +0,0 @@ -version: '2.0' - -examples.mistral-env-var: - description: A basic workflow that illustrates how to get the workflow's env vars. - type: direct - output: - env: <% env() %> - url: <% $.url %> - tasks: - task1: - action: core.local - input: - cmd: echo http://127.0.0.1:9101/executions/<% env().st2_execution_id %> - publish: - url: <% task(task1).result.stdout %> diff --git a/contrib/examples/actions/workflows/mistral-handle-error-task-default.yaml b/contrib/examples/actions/workflows/mistral-handle-error-task-default.yaml deleted file mode 100644 index 10fbda6d9f..0000000000 --- a/contrib/examples/actions/workflows/mistral-handle-error-task-default.yaml +++ /dev/null @@ -1,32 +0,0 @@ -version: '2.0' - -examples.mistral-handle-error-task-default: - description: > - A workflow example that illustrates default error handling. By default when any - task fails, the notify_on_error task will be executed and the workflow will - transition to the failed state. - type: direct - input: - - cmd - vars: - error_handled: False - - task-defaults: - on-error: - - handle_error - - tasks: - task1: - action: core.local cmd=<% $.cmd %> - publish: - stdout: <% task(task1).result.stdout %> - - # Default exception handler - handle_error: - action: core.local - input: - cmd: "printf 'EPIC FAIL!'" - publish: - error_handled: True - on-complete: - - fail diff --git a/contrib/examples/actions/workflows/mistral-handle-error.yaml b/contrib/examples/actions/workflows/mistral-handle-error.yaml deleted file mode 100644 index 9162432505..0000000000 --- a/contrib/examples/actions/workflows/mistral-handle-error.yaml +++ /dev/null @@ -1,27 +0,0 @@ -version: '2.0' - -examples.mistral-handle-error: - description: > - A workflow example that illustrates error handling. By default when any task fails, - the notify_on_error task will be executed and the workflow will transition to the - failed state. - type: direct - input: - - cmd - vars: - error_handled: False - tasks: - task1: - action: core.local cmd=<% $.cmd %> - publish: - stdout: <% task(task1).result.stdout %> - on-error: - - handle_error - handle_error: - action: core.local - input: - cmd: "printf '<% task(task1).result.stderr %>'" - publish: - error_handled: True - on-complete: - - fail diff --git a/contrib/examples/actions/workflows/mistral-handle-retry.yaml b/contrib/examples/actions/workflows/mistral-handle-retry.yaml deleted file mode 100644 index 58e235d6d3..0000000000 --- a/contrib/examples/actions/workflows/mistral-handle-retry.yaml +++ /dev/null @@ -1,50 +0,0 @@ -version: '2.0' -name: examples.mistral-handle-retry -description: > - A sample workflow that demonstrates how to handle rollback and retry on error. - In this example, the workflow will error and then continue to retry until the file - /tmp/done exists. A parallel task will wait for some time before creating the - file. When completed, /tmp/done will be deleted. - -workflows: - - main: - type: direct - tasks: - init: - action: core.local cmd="rm -f /tmp/done" - on-success: - - create-file - - test-error-undo-retry - create-file: - action: core.local cmd="touch /tmp/done" - wait-before: 10 - test-error-undo-retry: - workflow: work - retry: - count: 30 - delay: 1 - on-success: - - delete-file - delete-file: - action: core.local cmd="rm -f /tmp/done" - - work: - type: direct - tasks: - do: - action: core.local - input: - cmd: > - echo 'Do something useful here.'; - if [ ! -e '/tmp/done' ]; then exit 1; fi - on-error: - - undo - undo: - action: core.local - input: - cmd: "echo 'Define rollback tasks here.'" - on-complete: - - throw - throw: - action: std.fail diff --git a/contrib/examples/actions/workflows/mistral-jinja-branching.yaml b/contrib/examples/actions/workflows/mistral-jinja-branching.yaml deleted file mode 100644 index ea0df7d98f..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-branching.yaml +++ /dev/null @@ -1,32 +0,0 @@ -version: '2.0' - -examples.mistral-jinja-branching: - description: > - A sample workflow that demonstrates how to use conditions - to determine which path in the workflow to take. - type: direct - input: - - which - tasks: - t1: - action: core.local - input: - cmd: "echo {{ _.which }}" - publish: - path: "{{ task('t1').result.stdout }}" - on-success: - - a: "{{ _.path == 'a' }}" - - b: "{{ _.path == 'b' }}" - - c: "{{ not _.path in ['a', 'b'] }}" - a: - action: core.local - input: - cmd: "echo 'Took path A.'" - b: - action: core.local - input: - cmd: "echo 'Took path B.'" - c: - action: core.local - input: - cmd: "echo 'Took path C.'" diff --git a/contrib/examples/actions/workflows/mistral-jinja-env-var.yaml b/contrib/examples/actions/workflows/mistral-jinja-env-var.yaml deleted file mode 100644 index 01f135a446..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-env-var.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-jinja-env-var: - description: A basic workflow that illustrates how to get the workflow's env vars. - type: direct - output: - env: "{{ env() }}" - url: "{{ _.url }}" - tasks: - task1: - action: core.local - input: - cmd: "echo http://127.0.0.1:9101/executions/{{ env().st2_execution_id }}" - publish: - url: "{{ task('task1').result.stdout }}" - ctx: "{{ env()['__actions']['st2.action']['st2_context'] }}" diff --git a/contrib/examples/actions/workflows/mistral-jinja-repeat-with-items.yaml b/contrib/examples/actions/workflows/mistral-jinja-repeat-with-items.yaml deleted file mode 100644 index afdb9c6f9a..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-repeat-with-items.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-jinja-repeat-with-items: - description: > - A sample workflow that demonstrates how to repeat a task - multiple times with different inputs. - type: direct - input: - - cmds - tasks: - repeat: - with-items: "cmd in {{ _.cmds }}" - action: core.local - input: - cmd: "{{ _.cmd }}" - publish: - result: "{{ task('repeat').result | map(attribute='stdout') | list }}" diff --git a/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope-encrypted.yaml b/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope-encrypted.yaml deleted file mode 100644 index 19d30fc4f5..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope-encrypted.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: '2.0' - -examples.mistral-jinja-st2kv-system-scope-encrypted: - vars: - foobar: unspecified - tasks: - task1: - action: core.local - input: - cmd: echo "{{ st2kv('system.foobar', decrypt=True) }}" - publish: - foobar: <% task(task1).result.stdout %> - on-complete: - - fail: <% $.foobar != foobar %> diff --git a/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope.yaml b/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope.yaml deleted file mode 100644 index e3c0edf5b4..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-st2kv-system-scope.yaml +++ /dev/null @@ -1,14 +0,0 @@ -version: '2.0' - -examples.mistral-jinja-st2kv-system-scope: - vars: - foobar: unspecified - tasks: - task1: - action: core.local - input: - cmd: 'echo "{{ st2kv.system.foobar }}"' - publish: - foobar: <% task(task1).result.stdout %> - on-complete: - - fail: <% $.foobar != foobar %> diff --git a/contrib/examples/actions/workflows/mistral-jinja-workbook-complex.yaml b/contrib/examples/actions/workflows/mistral-jinja-workbook-complex.yaml deleted file mode 100644 index 491a3277f8..0000000000 --- a/contrib/examples/actions/workflows/mistral-jinja-workbook-complex.yaml +++ /dev/null @@ -1,102 +0,0 @@ -version: "2.0" -name: examples.mistral-jinja-workbook-complex -description: > - A sample workflow that demonstrates nested workflows, - forks, join, and use of jinja expressions. - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - output: - vm_id: '{{ _.vm_id }}' - ip: '{{ _.ip }}' - tasks: - register_dns: - action: core.local - input: - cmd: "sleep 1; printf 'Registering {{ _.vm_name }}...'" - publish: - ip: "10.1.23.98" - status_message: "DNS for {{ _.vm_name }} is registered." - on-success: - - configure_vm - - notify - create_vm: - wait-before: 1 - workflow: create_vm - input: - name: '{{ _.vm_name }}' - cpu_cores: '{{ _.cpu_cores }}' - memory_mb: '{{ _.memory_mb }}' - publish: - vm_id: "{{ task('create_vm').result.vm_id }}" - status_message: "VM {{ _.vm_name }} is created." - on-success: - - configure_vm - - notify - configure_vm: - join: all - workflow: configure_vm - input: - vm_id: '{{ _.vm_id }}' - ip: '{{ _.ip }}' - publish: - status_message: "VM {{ _.vm_name }} is reconfigured." - on-success: - - close_request - - notify - close_request: - action: std.noop - publish: - status_message: "VM request is fulfilled." - on-success: - - notify - notify: - action: core.local - input: - cmd: "printf '{{ _.status_message }}'" - - create_vm: - type: direct - input: - - name - - cpu_cores - - memory_mb - output: - vm_id: '{{ _.vm_id }}' - tasks: - create: - action: core.local - input: - cmd: "printf 'vm6789'; sleep 5" - publish: - vm_id: "{{ task('create').result.stdout }}" - - configure_vm: - type: direct - input: - - vm_id - - ip - vars: - apps: - - 'super mario brothers' - - 'zelda' - - 'donkey kong' - tasks: - add_disks: - action: core.local - input: - cmd: "sleep 1; printf 'disks created'" - add_nics: - action: core.local - input: - cmd: "sleep 1; printf 'nics created'" - install_apps: - action: core.local - input: - cmd: "sleep 1; {% for app in _.apps %}printf '{{ app }} is installed.\n'; {% endfor %}" diff --git a/contrib/examples/actions/workflows/mistral-join.yaml b/contrib/examples/actions/workflows/mistral-join.yaml deleted file mode 100644 index efc1332173..0000000000 --- a/contrib/examples/actions/workflows/mistral-join.yaml +++ /dev/null @@ -1,38 +0,0 @@ -version: '2.0' - -examples.mistral-join: - description: > - A sample workflow that demonstrates how to join parallel branches. - type: direct - tasks: - a: - action: core.local - input: - cmd: "echo 'a'" - on-success: - - b - - c - - d - b: - action: core.local - input: - cmd: "echo 'b'" - on-success: - - e - c: - action: core.local - input: - cmd: "echo 'c'" - on-success: - - e - d: - action: core.local - input: - cmd: "echo 'd'" - on-success: - - e - e: - join: all - action: core.local - input: - cmd: "echo 'e'" diff --git a/contrib/examples/actions/workflows/mistral-repeat-with-items.yaml b/contrib/examples/actions/workflows/mistral-repeat-with-items.yaml deleted file mode 100644 index ab9de5ab04..0000000000 --- a/contrib/examples/actions/workflows/mistral-repeat-with-items.yaml +++ /dev/null @@ -1,15 +0,0 @@ -version: '2.0' - -examples.mistral-repeat-with-items: - description: > - A sample workflow that demonstrates how to repeat a task - multiple times with different inputs. - type: direct - input: - - cmds - tasks: - repeat: - with-items: cmd in <% $.cmds %> - action: core.local cmd=<% $.cmd %> - publish: - result: <% task(repeat).result.select($.stdout) %> diff --git a/contrib/examples/actions/workflows/mistral-repeat.yaml b/contrib/examples/actions/workflows/mistral-repeat.yaml deleted file mode 100644 index 17ca53c34f..0000000000 --- a/contrib/examples/actions/workflows/mistral-repeat.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-repeat: - description: > - A sample workflow that demonstrates how to repeat a task - x number of times with the same inputs. - type: direct - input: - - cmd - - count - tasks: - repeat: - with-items: i in <% list(range(0, $.count)) %> - action: core.local cmd=<% $.cmd %> - publish: - result: <% task(repeat).result.select($.stdout) %> diff --git a/contrib/examples/actions/workflows/mistral-reverse-basic.yaml b/contrib/examples/actions/workflows/mistral-reverse-basic.yaml deleted file mode 100644 index 0ae50eff56..0000000000 --- a/contrib/examples/actions/workflows/mistral-reverse-basic.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-reverse-basic: - description: A basic reverse workflow that runs an arbitrary linux command. - type: reverse - input: - - cmd - - timeout - output: - stdout: <% $.stdout %> - tasks: - task1: - action: core.local cmd=<% $.cmd %> timeout=<% $.timeout %> - publish: - stdout: <% task(task1).result.stdout %> - stderr: <% task(task1).result.stderr %> diff --git a/contrib/examples/actions/workflows/mistral-reverse-requires.yaml b/contrib/examples/actions/workflows/mistral-reverse-requires.yaml deleted file mode 100644 index fddb7f2f9c..0000000000 --- a/contrib/examples/actions/workflows/mistral-reverse-requires.yaml +++ /dev/null @@ -1,41 +0,0 @@ -version: '2.0' - -examples.mistral-reverse-requires: - description: > - A sample workflow that demonstrates how to make parallel branches - with the requires key in a reverse workflow. - This is examples.mistral-join in a reverse workflow. - type: reverse - input: - - question - output: - answer: <% $.foo + $.bar %> - tasks: - a: - action: core.local - input: - cmd: "echo '{{ _.question }}'" - publish: - foo: 40 - b: - requires: [a] - action: core.local - input: - cmd: "echo 'b'" - c: - requires: [a] - action: core.local - input: - cmd: "echo 'c'" - d: - requires: [a] - action: core.local - input: - cmd: "echo 'd'" - e: - requires: [b, c, d] - action: core.local - input: - cmd: "echo 'Deep Thought'" - publish: - bar: 2 diff --git a/contrib/examples/actions/workflows/mistral-streaming-demo.yaml b/contrib/examples/actions/workflows/mistral-streaming-demo.yaml deleted file mode 100644 index cef225ffd4..0000000000 --- a/contrib/examples/actions/workflows/mistral-streaming-demo.yaml +++ /dev/null @@ -1,63 +0,0 @@ -version: '2.0' - -examples.mistral-streaming-demo: - description: A workflow which demonstrates action output streaming functionality. - type: direct - input: - - count - - sleep_delay - tasks: - task1: - action: core.local - input: - cmd: "echo 'Task 1'" - on-success: "task2" - task2: - action: examples.local_command_runner_print_to_stdout_and_stderr - input: - count: "{{ _.count }}" - sleep_delay: "{{ _.sleep_delay }}" - on-success: "task3" - task3: - action: core.local - input: - cmd: "echo 'Task 3'" - on-success: "task4" - task4: - action: examples.local_script_runner_print_to_stdout_and_stderr - input: - count: "{{ _.count }}" - sleep_delay: "{{ _.sleep_delay }}" - on-success: "task5" - task5: - action: core.local - input: - cmd: "echo 'Task 5'" - on-success: "task6" - task6: - action: examples.python_runner_print_to_stdout_and_stderr - input: - count: "{{ _.count }}" - sleep_delay: "{{ _.sleep_delay }}" - on-success: "task7" - task7: - action: core.local - input: - cmd: "echo 'Task 7'" - on-success: "task8" - task8: - action: examples.remote_command_runner_print_to_stdout_and_stderr - input: - count: "{{ _.count }}" - sleep_delay: "{{ _.sleep_delay }}" - on-success: "task9" - task9: - action: core.local - input: - cmd: "echo 'Task 9'" - on-success: "task10" - task10: - action: examples.remote_script_runner_print_to_stdout_and_stderr - input: - count: "{{ _.count }}" - sleep_delay: "{{ _.sleep_delay }}" diff --git a/contrib/examples/actions/workflows/mistral-with-items-concurrency.yaml b/contrib/examples/actions/workflows/mistral-with-items-concurrency.yaml deleted file mode 100644 index c7098da81d..0000000000 --- a/contrib/examples/actions/workflows/mistral-with-items-concurrency.yaml +++ /dev/null @@ -1,21 +0,0 @@ -version: '2.0' - -examples.mistral-with-items-concurrency: - description: > - A sample workflow that demonstrates how to set the concurrency option - in with-items to throttle the number of action executions that get - run simultaneously. Currently in this release, the concurrency option - does not work with YAQL expression. - type: direct - input: - - cmd - - count - tasks: - repeat: - with-items: i in <% list(range(0, $.count)) %> - concurrency: 2 - action: core.local - input: - cmd: "<% $.cmd %>; sleep 3" - publish: - result: <% task(repeat).result.select($.stdout) %> diff --git a/contrib/examples/actions/workflows/mistral-workbook-basic.yaml b/contrib/examples/actions/workflows/mistral-workbook-basic.yaml deleted file mode 100644 index 737fc99668..0000000000 --- a/contrib/examples/actions/workflows/mistral-workbook-basic.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' -name: examples.mistral-workbook-basic -description: The sample workflow as examples.mistral-basic but written as a workbook definition. -workflows: - demo: - type: direct - input: - - cmd - output: - stdout: <% $.stdout %> - tasks: - task1: - action: core.local cmd=<% $.cmd %> - publish: - stdout: <% task(task1).result.stdout %> - stderr: <% task(task1).result.stderr %> diff --git a/contrib/examples/actions/workflows/mistral-workbook-complex.yaml b/contrib/examples/actions/workflows/mistral-workbook-complex.yaml deleted file mode 100644 index adc30000cd..0000000000 --- a/contrib/examples/actions/workflows/mistral-workbook-complex.yaml +++ /dev/null @@ -1,95 +0,0 @@ -version: "2.0" -name: examples.mistral-workbook-complex -description: A sample workflow that demonstrates nested workflows, forks, and join. - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - output: - vm_id: <% $.vm_id %> - ip: <% $.ip %> - tasks: - register_dns: - action: core.local - input: - cmd: "sleep 1; printf 'Registering <% $.vm_name %>...'" - publish: - ip: "10.1.23.99" - status_message: "DNS for <% $.vm_name %> is registered." - on-success: - - configure_vm - - notify - create_vm: - wait-before: 1 - workflow: create_vm - input: - name: <% $.vm_name %> - cpu_cores: <% $.cpu_cores %> - memory_mb: <% $.memory_mb %> - publish: - vm_id: <% task(create_vm).result.vm_id %> - status_message: "VM <% $.vm_name %> is created." - on-success: - - configure_vm - - notify - configure_vm: - join: all - workflow: configure_vm - input: - vm_id: <% $.vm_id %> - ip: <% $.ip %> - publish: - status_message: "VM <% $.vm_name %> is reconfigured." - on-success: - - close_request - - notify - close_request: - action: std.noop - publish: - status_message: "VM request is fulfilled." - on-success: - - notify - notify: - action: core.local - input: - cmd: "printf '<% $.status_message %>'" - - create_vm: - type: direct - input: - - name - - cpu_cores - - memory_mb - output: - vm_id: <% $.vm_id %> - tasks: - create: - action: core.local - input: - cmd: "printf 'vm1234'; sleep 5" - publish: - vm_id: <% task(create).result.stdout %> - - configure_vm: - type: direct - input: - - vm_id - - ip - tasks: - add_disks: - action: core.local - input: - cmd: "sleep 1; printf 'disks created'" - add_nics: - action: core.local - input: - cmd: "sleep 1; printf 'nics created'" - install_apps: - action: core.local - input: - cmd: "sleep 1; printf 'apps installed'" diff --git a/contrib/examples/actions/workflows/mistral-workbook-multiple-subflows.yaml b/contrib/examples/actions/workflows/mistral-workbook-multiple-subflows.yaml deleted file mode 100644 index 5a28ac09cd..0000000000 --- a/contrib/examples/actions/workflows/mistral-workbook-multiple-subflows.yaml +++ /dev/null @@ -1,65 +0,0 @@ -version: "2.0" -name: "examples.mistral-workbook-multiple-subflows" - -workflows: - - main: - type: direct - output: - report: <% $.report %> - state: <% $.state %> - tasks: - call_internal_workflow: - workflow: wf1 - input: - v1: ok - publish: - report: <% task(call_internal_workflow).result.report %> - on-success: - - call_internal_workflow_multiple_tasks - call_internal_workflow_multiple_tasks: - workflow: wf2 - input: - v1: good - v2: excellent - on-success: - - call_external_workflow - call_external_workflow: - action: examples.mistral-basic - input: - cmd: "echo 'external workflow ok'" - publish: - state: <% task(call_external_workflow).result.stdout %> - on-success: - - call_action_chain - call_action_chain: - action: examples.echochain - - wf1: - type: direct - input: - - v1 - output: - report: <% $.report %> - tasks: - t1: - action: core.local - input: - cmd: "echo 'task1 <% $.v1 %>'; sleep 1" - publish: - report: <% task(t1).result.stdout %> - - wf2: - type: direct - input: - - v1 - - v2 - tasks: - t1: - action: core.local - input: - cmd: "echo 'task2 <% $.v1 %>'; sleep 1" - t2: - action: core.local - input: - cmd: "echo 'task3 <% $.v2 %>'; sleep 2" diff --git a/contrib/examples/actions/workflows/mistral-workbook-subflows.yaml b/contrib/examples/actions/workflows/mistral-workbook-subflows.yaml deleted file mode 100644 index 78eabbc455..0000000000 --- a/contrib/examples/actions/workflows/mistral-workbook-subflows.yaml +++ /dev/null @@ -1,30 +0,0 @@ -version: "2.0" -name: "examples.mistral-workbook-subflows" - -workflows: - - main: - type: direct - input: - - subject - - adjective - output: - tagline: "<% $.printed_subject %> is <% $.printed_adjective %>!" - task-defaults: - on-error: - - fail - tasks: - print_subject: - action: examples.mistral-basic - input: - cmd: "printf '<% $.subject %>'" - publish: - printed_subject: <% task(print_subject).result.stdout %> - on-success: - - print_adjective - print_adjective: - action: examples.mistral-basic - input: - cmd: "printf '<% $.adjective %>'" - publish: - printed_adjective: <% task(print_adjective).result.stdout %> diff --git a/contrib/examples/actions/workflows/mistral-yaql-st2kv-system-scope.yaml b/contrib/examples/actions/workflows/mistral-yaql-st2kv-system-scope.yaml deleted file mode 100644 index 278caaee7f..0000000000 --- a/contrib/examples/actions/workflows/mistral-yaql-st2kv-system-scope.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-yaql-st2kv-system-scope: - vars: - foobar: unspecified - tasks: - task1: - action: std.noop - publish: - foobar: <% st2kv('system.foobar', decrypt => true) %> - on-complete: - - fail: <% $.foobar != foobar %> diff --git a/contrib/examples/actions/workflows/mistral-yaql-st2kv-user-scope.yaml b/contrib/examples/actions/workflows/mistral-yaql-st2kv-user-scope.yaml deleted file mode 100644 index de05be64c2..0000000000 --- a/contrib/examples/actions/workflows/mistral-yaql-st2kv-user-scope.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-yaql-st2kv-user-scope: - vars: - polo: unspecified - tasks: - task1: - action: std.noop - publish: - polo: <% st2kv('marco', decrypt => true) %> - on-complete: - - fail: <% $.polo != polo %> diff --git a/contrib/examples/actions/workflows/tests/mistral-error-bad-action.yaml b/contrib/examples/actions/workflows/tests/mistral-error-bad-action.yaml deleted file mode 100644 index 316f1a7468..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-error-bad-action.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: '2.0' - -examples.mistral-error-bad-action: - description: A sample workflow for testing error handling if action does not exist. - type: direct - tasks: - task1: - action: core.foobar diff --git a/contrib/examples/actions/workflows/tests/mistral-error-bad-task-transition.yaml b/contrib/examples/actions/workflows/tests/mistral-error-bad-task-transition.yaml deleted file mode 100644 index 2d903c0971..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-error-bad-task-transition.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-error-bad-task-transition: - description: A sample workflow used to test bad task transition statement. - type: direct - tasks: - task1: - action: std.noop - on-success: - - task3 - task2: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-error-bad-wf-arg.yaml b/contrib/examples/actions/workflows/tests/mistral-error-bad-wf-arg.yaml deleted file mode 100644 index a4de565aa2..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-error-bad-wf-arg.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' -name: examples.mistral-error-bad-wf-arg -description: A sample workflow used to test invalid input passed to subworkflow. -workflows: - wf1: - type: direct - tasks: - task1: - workflow: wf2 - input: - var2: foobar - wf2: - type: direct - input: - - var1 - tasks: - task1: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-error-bad-with-items.yaml b/contrib/examples/actions/workflows/tests/mistral-error-bad-with-items.yaml deleted file mode 100644 index 51b1eff3f4..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-error-bad-with-items.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: '2.0' -examples.mistral-error-bad-with-items: - description: A sample workflow for testing bad input to with-items statement. - type: direct - input: - - items: foobar - tasks: - task1: - with-items: i in <% $.items %> - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-action.yaml b/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-action.yaml deleted file mode 100644 index 234f111468..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-action.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -examples.mistral-test-cancel-subworkflow-action: - description: A sample workflow used to test the cascading cancellation of subworkflow action. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: examples.mistral-test-cancel - input: - tempfile: <% $.tempfile %> - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-chain.yaml b/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-chain.yaml deleted file mode 100644 index a744847eb2..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-cancel-subworkflow-chain.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -examples.mistral-test-cancel-subworkflow-chain: - description: A sample workflow used to test the cascading cancellation of subchain. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: examples.chain-test-cancel - input: - tempfile: <% $.tempfile %> - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-cancel.yaml b/contrib/examples/actions/workflows/tests/mistral-test-cancel.yaml deleted file mode 100644 index 22546f1fb2..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-cancel.yaml +++ /dev/null @@ -1,22 +0,0 @@ -version: '2.0' - -examples.mistral-test-cancel: - description: A sample workflow used to test the cancellation feature. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: core.local - input: - cmd: "while [ -e '<% $.tempfile %>' ]; do sleep 0.1; done" - timeout: 300 - publish: - var1: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.var1 %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-from-json-string.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-from-json-string.yaml deleted file mode 100644 index 860b6fc077..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-from-json-string.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-from-json-string: - description: A workflow for testing from_json_string custom filter in mistral - type: direct - input: - - input_str - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - task1: - action: std.noop - publish: - result_jinja: "{{ from_json_string(_.input_str) }}" - result_yaql: '<% from_json_string($.input_str) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-from-yaml-string.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-from-yaml-string.yaml deleted file mode 100644 index af45f2e233..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-from-yaml-string.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-from-yaml-string: - description: A workflow for testing from_yaml_string custom filter in mistral - type: direct - input: - - input_str - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - task1: - action: std.noop - publish: - result_jinja: "{{ from_yaml_string(_.input_str) }}" - result_yaql: '<% from_yaml_string($.input_str) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-json-escape.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-json-escape.yaml deleted file mode 100644 index ca18132396..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-json-escape.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-json-escape: - description: A workflow for testing json_escape custom filter in mistral - type: direct - input: - - input_str - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task2: - action: std.noop - publish: - result_jinja: '[{"title": "{{ json_escape(_.input_str) }}"}]' - result_yaql: '[{"title": "<% json_escape($.input_str) %>"}]' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-jsonpath-query.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-jsonpath-query.yaml deleted file mode 100644 index 9d2002664d..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-jsonpath-query.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-jsonpath-query: - description: A workflow for testing jsonpath_query custom filter in mistral - type: direct - input: - - input_obj - - input_query - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task2: - action: std.noop - publish: - result_jinja: '{{ jsonpath_query(_.input_obj, _.input_query) }}' - result_yaql: '<% jsonpath_query($.input_obj, $.input_query) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-match.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-regex-match.yaml deleted file mode 100644 index d0777b73bb..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-match.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-regex-match: - description: A workflow for testing regex_match custom filter in mistral - type: direct - input: - - input_str - - regex_pattern - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ regex_match(_.input_str, _.regex_pattern) }}' - result_yaql: '<% regex_match($.input_str, $.regex_pattern) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-replace.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-regex-replace.yaml deleted file mode 100644 index 7230dad0fd..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-replace.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-regex-replace: - description: A workflow for testing regex_replace custom filter in mistral - type: direct - input: - - input_str - - regex_pattern - - replacement_str - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ regex_replace(_.input_str, _.regex_pattern, _.replacement_str) }}' - result_yaql: '<% regex_replace($.input_str, $.regex_pattern, $.replacement_str) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-search.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-regex-search.yaml deleted file mode 100644 index 2c4704ab58..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-search.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-regex-search: - description: A workflow for testing regex_search custom filter in mistral - type: direct - input: - - input_str - - regex_pattern - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ regex_search(_.input_str, _.regex_pattern) }}' - result_yaql: '<% regex_search($.input_str, $.regex_pattern) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-substring.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-regex-substring.yaml deleted file mode 100644 index cca4afe7c7..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-regex-substring.yaml +++ /dev/null @@ -1,26 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-regex-substring: - description: A workflow for testing regex_substring custom filter in mistral - type: direct - input: - - input_str - - regex_pattern - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - result_jinja_index_1: <% $.result_jinja_index_1 %> - result_yaql_index_1: <% $.result_yaql_index_1 %> - tasks: - - task1: - action: std.noop - publish: - - # By default, first found match is extracted - result_jinja: '{{ regex_substring(_.input_str, _.regex_pattern) }}' - result_yaql: '<% regex_substring($.input_str, $.regex_pattern) %>' - - # Optionally, you can specify an index to extract, if multiple are found - result_jinja_index_1: '{{ regex_substring(_.input_str, _.regex_pattern, 1) }}' - result_yaql_index_1: '<% regex_substring($.input_str, $.regex_pattern, 1) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-to-complex.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-to-complex.yaml deleted file mode 100644 index a3d71ae2dd..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-to-complex.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-to-complex: - description: A workflow for testing to_complex custom filter in mistral - type: direct - input: - - input_obj - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - task1: - action: std.noop - publish: - result_jinja: "{{ to_complex(_.input_obj) }}" - result_yaql: '<% to_complex($.input_obj) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-to-human-time-from-seconds.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-to-human-time-from-seconds.yaml deleted file mode 100644 index 09224b94fd..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-to-human-time-from-seconds.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-to-human-time-from-seconds: - description: A workflow for testing to_human_time_from_seconds custom filter in mistral - type: direct - input: - - seconds - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ to_human_time_from_seconds(_.seconds) }}' - result_yaql: '<% to_human_time_from_seconds($.seconds) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-to-json-string.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-to-json-string.yaml deleted file mode 100644 index 5333e47477..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-to-json-string.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-to-json-string: - description: A workflow for testing to_json_string custom filter in mistral - type: direct - input: - - input_obj - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - task1: - action: std.noop - publish: - result_jinja: "{{ to_json_string(_.input_obj) }}" - result_yaql: '<% to_json_string($.input_obj) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-to-yaml-string.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-to-yaml-string.yaml deleted file mode 100644 index 7016feb220..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-to-yaml-string.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-to-yaml-string: - description: A workflow for testing to_yaml_string custom filter in mistral - type: direct - input: - - input_obj - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - task1: - action: std.noop - publish: - result_jinja: "{{ to_yaml_string(_.input_obj) }}" - result_yaql: '<% to_yaml_string($.input_obj) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-use-none.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-use-none.yaml deleted file mode 100644 index afb2e76552..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-use-none.yaml +++ /dev/null @@ -1,29 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-use-none: - description: A workflow for testing use_none custom filter in mistral - type: direct - vars: - none_input: null - input: - - input_str - output: - none_result_jinja: <% $.result_jinja %> - none_result_yaql: <% $.result_yaql %> - str_result_jinja: <% $.str_result_jinja %> - str_result_yaql: <% $.str_result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ use_none(_.none_input) }}' - result_yaql: '<% use_none($.none_input) %>' - on-complete: - - task2 - - task2: - action: std.noop - publish: - str_result_jinja: '{{ use_none(_.input_str) }}' - str_result_yaql: '<% use_none($.input_str) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-major.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-major.yaml deleted file mode 100644 index c3d2da4d25..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-major.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-bump-major: - description: A workflow for testing version_bump_major custom filter in mistral - type: direct - input: - - version - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_bump_major(_.version) }}' - result_yaql: '<% version_bump_major($.version) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-minor.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-minor.yaml deleted file mode 100644 index 92b0e55e2e..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-minor.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-bump-minor: - description: A workflow for testing version_bump_minor custom filter in mistral - type: direct - input: - - version - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_bump_minor(_.version) }}' - result_yaql: '<% version_bump_minor($.version) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-patch.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-patch.yaml deleted file mode 100644 index f64e568a54..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-bump-patch.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-bump-patch: - description: A workflow for testing version_bump_patch custom filter in mistral - type: direct - input: - - version - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_bump_patch(_.version) }}' - result_yaql: '<% version_bump_patch($.version) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-compare.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-compare.yaml deleted file mode 100644 index a961547b0e..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-compare.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-compare: - description: A workflow for testing version_compare custom filter in mistral - type: direct - input: - - version_a - - version_b - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_compare(_.version_a, _.version_b) }}' - result_yaql: '<% version_compare($.version_a, $.version_b) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-equal.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-equal.yaml deleted file mode 100644 index 49b8bb8118..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-equal.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-equal: - description: A workflow for testing version_equal custom filter in mistral - type: direct - input: - - version_a - - version_b - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_equal(_.version_a, _.version_b )}}' - result_yaql: '<% version_equal($.version_a, $.version_b) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-less-than.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-less-than.yaml deleted file mode 100644 index 3934a115af..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-less-than.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-less-than: - description: A workflow for testing version_less_than custom filter in mistral - type: direct - input: - - version_a - - version_b - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_less_than( _.version_a, _.version_b) }}' - result_yaql: '<% version_less_than($.version_a, $.version_b) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-match.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-match.yaml deleted file mode 100644 index b074c0f12f..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-match.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-match: - description: A workflow for testing version_match custom filter in mistral - type: direct - input: - - version_a - - version_b - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_match(_.version_a, _.version_b) }}' - result_yaql: '<% version_match($.version_a, $.version_b) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-more-than.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-more-than.yaml deleted file mode 100644 index 879f91df51..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-more-than.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-more-than: - description: A workflow for testing version_more_than custom filter in mistral - type: direct - input: - - version_a - - version_b - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_more_than(_.version_a, _.version_b) }}' - result_yaql: '<% version_more_than($.version_a, $.version_b) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-func-version-strip-patch.yaml b/contrib/examples/actions/workflows/tests/mistral-test-func-version-strip-patch.yaml deleted file mode 100644 index 16337e839b..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-func-version-strip-patch.yaml +++ /dev/null @@ -1,17 +0,0 @@ -version: '2.0' - -examples.mistral-test-func-version-strip-patch: - description: A workflow for testing version_strip_patch custom filter in mistral - type: direct - input: - - version - output: - result_jinja: <% $.result_jinja %> - result_yaql: <% $.result_yaql %> - tasks: - - task1: - action: std.noop - publish: - result_jinja: '{{ version_strip_patch(_.version) }}' - result_yaql: '<% version_strip_patch($.version) %>' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-expr.yaml b/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-expr.yaml deleted file mode 100644 index ca506db466..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-expr.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: '2.0' - -examples.mistral-test-jinja-bad-expr: - description: A basic workflow for testing Jinja evaluation error. The workflow should error properly. - type: direct - tasks: - task1: - action: core.local - input: - cmd: "echo {{ _.IDontExist }}" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-publish.yaml b/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-publish.yaml deleted file mode 100644 index 77df3412ca..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-publish.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-test-jinja-bad-publish: - description: A basic workflow for testing Jinja evaluation error. The workflow should error properly. - type: direct - tasks: - task1: - action: core.local - input: - cmd: "echo 'all your base are belong to us'" - publish: - var1: "{{ _.IDontExist }}" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-subworkflow-input.yaml b/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-subworkflow-input.yaml deleted file mode 100644 index dd5fdcb3d3..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-subworkflow-input.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' -name: examples.mistral-test-jinja-bad-subworkflow-input -description: A sample workflow used to test invalid input passed to subworkflow. -workflows: - wf1: - type: direct - tasks: - task1: - workflow: wf2 - input: - var1: "{{ _.foobar }}" - wf2: - type: direct - input: - - var1 - tasks: - task1: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-task-transition.yaml b/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-task-transition.yaml deleted file mode 100644 index 042368af92..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-task-transition.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-test-jinja-bad-task-transition: - description: A sample workflow used to test bad task transition statement. - type: direct - tasks: - task1: - action: std.noop - on-success: - - task2: "{{ _.foobar }}" - task2: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-with-items.yaml b/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-with-items.yaml deleted file mode 100644 index df7d76fe6d..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-jinja-bad-with-items.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: '2.0' -examples.mistral-test-jinja-bad-with-items: - description: A sample workflow for testing bad input to with-items statement. - type: direct - tasks: - task1: - with-items: "i in {{ _.foobar }}" - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-action.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-action.yaml deleted file mode 100644 index 092a0082dc..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-action.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' - -examples.mistral-test-pause-before-task-subworkflow-action: - description: A sample workflow used to test the cascading pause and resume of subworkflow action. - type: direct - input: - - message - tasks: - task1: - action: examples.mistral-test-pause-before-task - input: - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-workbook.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-workbook.yaml deleted file mode 100644 index e7dac70398..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task-subworkflow-workbook.yaml +++ /dev/null @@ -1,39 +0,0 @@ -version: "2.0" -name: examples.mistral-test-pause-before-task-subworkflow-workbook - -workflows: - - main: - type: direct - input: - - message - tasks: - task1: - workflow: wf1 - input: - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" - - wf1: - type: direct - input: - - message - tasks: - task1: - action: core.local - input: - cmd: echo "<% $.message %>" - publish: - var1: <% task(task1).result.stdout %> - on-success: - - task2 - task2: - pause-before: true - action: core.local - input: - cmd: echo "<% $.var1 %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task.yaml deleted file mode 100644 index 408ae8dd24..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-before-task.yaml +++ /dev/null @@ -1,21 +0,0 @@ -version: '2.0' - -examples.mistral-test-pause-before-task: - description: A sample workflow used to test auto pause specified in the task. - type: direct - input: - - message - tasks: - task1: - action: core.local - input: - cmd: echo "<% $.message %>" - publish: - var1: <% task(task1).result.stdout %> - on-success: - - task2 - task2: - pause-before: true - action: core.local - input: - cmd: echo "<% $.var1 %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-action.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-action.yaml deleted file mode 100644 index ef002421e8..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-action.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -examples.mistral-test-pause-resume-subworkflow-action: - description: A sample workflow used to test the cascading pause and resume of subworkflow action. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: examples.mistral-test-pause-resume - input: - tempfile: <% $.tempfile %> - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-chain.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-chain.yaml deleted file mode 100644 index 7669a84f4a..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-chain.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -examples.mistral-test-pause-resume-subworkflow-chain: - description: A sample workflow used to test the cascading pause and resume of subchain. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: examples.chain-test-pause-resume - input: - tempfile: <% $.tempfile %> - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-workbook.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-workbook.yaml deleted file mode 100644 index 25ff2617a7..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume-subworkflow-workbook.yaml +++ /dev/null @@ -1,42 +0,0 @@ -version: "2.0" -name: examples.mistral-test-pause-resume-subworkflow-workbook - -workflows: - - main: - type: direct - input: - - tempfile - - message - tasks: - task1: - workflow: wf1 - input: - tempfile: <% $.tempfile %> - message: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.message %>" - - wf1: - type: direct - input: - - tempfile - - message - tasks: - task1: - action: core.local - input: - cmd: "while [ -e '<% $.tempfile %>' ]; do sleep 0.1; done" - timeout: 300 - publish: - var1: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: echo "<% $.var1 %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume.yaml b/contrib/examples/actions/workflows/tests/mistral-test-pause-resume.yaml deleted file mode 100644 index 01a67ae671..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-pause-resume.yaml +++ /dev/null @@ -1,22 +0,0 @@ -version: '2.0' - -examples.mistral-test-pause-resume: - description: A sample workflow used to test the pause and resume feature. - type: direct - input: - - tempfile - - message - tasks: - task1: - action: core.local - input: - cmd: "while [ -e '<% $.tempfile %>' ]; do sleep 0.1; done" - timeout: 300 - publish: - var1: <% $.message %> - on-success: - - task2 - task2: - action: core.local - input: - cmd: 'echo "<% $.var1 %>"' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow-with-items.yaml b/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow-with-items.yaml deleted file mode 100644 index 97ca4680ae..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow-with-items.yaml +++ /dev/null @@ -1,26 +0,0 @@ -version: '2.0' -name: examples.mistral-test-rerun-subflow-with-items -description: A sample workflow used to test the rerun feature. - -workflows: - - main: - type: direct - input: - - tempfile - tasks: - task1: - workflow: subflow - input: - tempfile: <% $.tempfile %> - - subflow: - type: direct - input: - - tempfile - tasks: - task1: - with-items: i in [0, 1, 2, 3] - action: core.local - input: - cmd: 'x=`cat <% $.tempfile %>`; y=`echo "$x * <% $.i %> % 2" | bc`; exit `echo $y`' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow.yaml b/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow.yaml deleted file mode 100644 index 1fe2b33d40..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-rerun-subflow.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: '2.0' -name: examples.mistral-test-rerun-subflow -description: A sample workflow used to test the rerun feature. - -workflows: - - main: - type: direct - input: - - tempfile - tasks: - task1: - workflow: subflow - input: - tempfile: <% $.tempfile %> - - subflow: - type: direct - input: - - tempfile - tasks: - task1: - action: core.local - input: - cmd: "exit `cat <% $.tempfile %>`" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/mistral-test-rerun-with-items.yaml deleted file mode 100644 index 1c598720cc..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-rerun-with-items.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: '2.0' - -examples.mistral-test-rerun-with-items: - description: A sample workflow used to test the rerun feature. - type: direct - input: - - tempfile - tasks: - task1: - with-items: i in [0, 1, 2, 3] - action: core.local - input: - cmd: 'x=`cat <% $.tempfile %>`; y=`echo "$x * <% $.i %> % 2" | bc`; exit `echo $y`' diff --git a/contrib/examples/actions/workflows/tests/mistral-test-rerun.yaml b/contrib/examples/actions/workflows/tests/mistral-test-rerun.yaml deleted file mode 100644 index b3fbe45b7b..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-rerun.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-test-rerun: - description: A sample workflow used to test the rerun feature. - type: direct - input: - - tempfile - tasks: - task1: - action: core.local - input: - cmd: "exit `cat <% $.tempfile %>`" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-expr.yaml b/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-expr.yaml deleted file mode 100644 index c1cf2b3960..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-expr.yaml +++ /dev/null @@ -1,10 +0,0 @@ -version: '2.0' - -examples.mistral-test-yaql-bad-expr: - description: A basic workflow for testing YAQL evaluation error. The workflow should error properly. - type: direct - tasks: - task1: - action: core.local - input: - cmd: "echo <% $.IDontExist %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-publish.yaml b/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-publish.yaml deleted file mode 100644 index 374c526d5a..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-publish.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-test-yaql-bad-publish: - description: A basic workflow for testing YAQL evaluation error. The workflow should error properly. - type: direct - tasks: - task1: - action: core.local - input: - cmd: "echo 'all your base are belong to us'" - publish: - var1: "<% $.IDontExist %>" diff --git a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-subworkflow-input.yaml b/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-subworkflow-input.yaml deleted file mode 100644 index 913efc58f7..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-subworkflow-input.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: '2.0' -name: examples.mistral-test-yaql-bad-subworkflow-input -description: A sample workflow used to test invalid input passed to subworkflow. -workflows: - wf1: - type: direct - tasks: - task1: - workflow: wf2 - input: - var1: <% $.foobar %> - wf2: - type: direct - input: - - var1 - tasks: - task1: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-task-transition.yaml b/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-task-transition.yaml deleted file mode 100644 index f151467c25..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-task-transition.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -examples.mistral-test-yaql-bad-task-transition: - description: A sample workflow used to test bad task transition statement. - type: direct - tasks: - task1: - action: std.noop - on-success: - - task2: <% $.foobar %> - task2: - action: std.noop diff --git a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-with-items.yaml b/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-with-items.yaml deleted file mode 100644 index 5054e018aa..0000000000 --- a/contrib/examples/actions/workflows/tests/mistral-test-yaql-bad-with-items.yaml +++ /dev/null @@ -1,8 +0,0 @@ -version: '2.0' -examples.mistral-test-yaql-bad-with-items: - description: A sample workflow for testing bad input to with-items statement. - type: direct - tasks: - task1: - with-items: i in <% $.foobar %> - action: std.noop diff --git a/contrib/runners/mistral_v2/MANIFEST.in b/contrib/runners/mistral_v2/MANIFEST.in deleted file mode 100644 index 25ce80c091..0000000000 --- a/contrib/runners/mistral_v2/MANIFEST.in +++ /dev/null @@ -1,11 +0,0 @@ -# https://docs.python.org/2/distutils/sourcedist.html#commands -# Include all files under the source tree by default. -# Another behaviour can be used in the future though. -include __init__.py -include runner.yaml -include dist_utils.py -include requirements.txt -include README.rst -include CHANGELOG.rst -include LICENSE -global-exclude *.pyc diff --git a/contrib/runners/mistral_v2/callback/__init__.py b/contrib/runners/mistral_v2/callback/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/contrib/runners/mistral_v2/dist_utils.py b/contrib/runners/mistral_v2/dist_utils.py deleted file mode 100644 index b25d7998ae..0000000000 --- a/contrib/runners/mistral_v2/dist_utils.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -# NOTE: This file is auto-generated - DO NOT EDIT MANUALLY -# Instead modify scripts/dist_utils.py and run 'make .sdist-requirements' to -# update dist_utils.py files for all components - -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import os -import re -import sys - -from distutils.version import StrictVersion - -# NOTE: This script can't rely on any 3rd party dependency so we need to use this code here -# -# TODO: Why can't this script rely on 3rd party dependencies? Is it because it has to import -# from pip? -# -# TODO: Dear future developer, if you are back here fixing a bug with how we parse -# requirements files, please look into using the packaging package on PyPI: -# https://packaging.pypa.io/en/latest/requirements/ -# and specifying that in the `setup_requires` argument to `setuptools.setup()` -# for subpackages. -# At the very least we can vendorize some of their code instead of reimplementing -# each piece of their code every time our parsing breaks. -PY3 = sys.version_info[0] == 3 - -if PY3: - text_type = str -else: - text_type = unicode # NOQA - -GET_PIP = 'curl https://bootstrap.pypa.io/get-pip.py | python' - -__all__ = [ - 'check_pip_is_installed', - 'check_pip_version', - 'fetch_requirements', - 'apply_vagrant_workaround', - 'get_version_string', - 'parse_version_string' -] - - -def check_pip_is_installed(): - """ - Ensure that pip is installed. - """ - try: - import pip # NOQA - except ImportError as e: - print('Failed to import pip: %s' % (text_type(e))) - print('') - print('Download pip:\n%s' % (GET_PIP)) - sys.exit(1) - - return True - - -def check_pip_version(min_version='6.0.0'): - """ - Ensure that a minimum supported version of pip is installed. - """ - check_pip_is_installed() - - import pip - - if StrictVersion(pip.__version__) < StrictVersion(min_version): - print("Upgrade pip, your version '{0}' " - "is outdated. Minimum required version is '{1}':\n{2}".format(pip.__version__, - min_version, - GET_PIP)) - sys.exit(1) - - return True - - -def fetch_requirements(requirements_file_path): - """ - Return a list of requirements and links by parsing the provided requirements file. - """ - links = [] - reqs = [] - - def _get_link(line): - vcs_prefixes = ['git+', 'svn+', 'hg+', 'bzr+'] - - for vcs_prefix in vcs_prefixes: - if line.startswith(vcs_prefix) or line.startswith('-e %s' % (vcs_prefix)): - req_name = re.findall('.*#egg=(.+)([&|@]).*$', line) - - if not req_name: - req_name = re.findall('.*#egg=(.+?)$', line) - else: - req_name = req_name[0] - - if not req_name: - raise ValueError('Line "%s" is missing "#egg="' % (line)) - - link = line.replace('-e ', '').strip() - return link, req_name[0] - - return None, None - - with open(requirements_file_path, 'r') as fp: - for line in fp.readlines(): - line = line.strip() - - if line.startswith('#') or not line: - continue - - link, req_name = _get_link(line=line) - - if link: - links.append(link) - else: - req_name = line - - if ';' in req_name: - req_name = req_name.split(';')[0].strip() - - reqs.append(req_name) - - return (reqs, links) - - -def apply_vagrant_workaround(): - """ - Function which detects if the script is being executed inside vagrant and if it is, it deletes - "os.link" attribute. - Note: Without this workaround, setup.py sdist will fail when running inside a shared directory - (nfs / virtualbox shared folders). - """ - if os.environ.get('USER', None) == 'vagrant': - del os.link - - -def get_version_string(init_file): - """ - Read __version__ string for an init file. - """ - - with open(init_file, 'r') as fp: - content = fp.read() - version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", - content, re.M) - if version_match: - return version_match.group(1) - - raise RuntimeError('Unable to find version string in %s.' % (init_file)) - - -# alias for get_version_string -parse_version_string = get_version_string diff --git a/contrib/runners/mistral_v2/in-requirements.txt b/contrib/runners/mistral_v2/in-requirements.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/contrib/runners/mistral_v2/mistral_v2/__init__.py b/contrib/runners/mistral_v2/mistral_v2/__init__.py deleted file mode 100644 index d0382c39e3..0000000000 --- a/contrib/runners/mistral_v2/mistral_v2/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -__version__ = '3.3dev' diff --git a/contrib/runners/mistral_v2/mistral_v2/callback.py b/contrib/runners/mistral_v2/mistral_v2/callback.py deleted file mode 100644 index 645a876f59..0000000000 --- a/contrib/runners/mistral_v2/mistral_v2/callback.py +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import ast -import copy -import json -import re -import retrying -import six - -from oslo_config import cfg -from mistralclient.api import client as mistral - -from st2common.constants import action as action_constants -from st2common import log as logging -from st2common.callback import base as callback -from st2common.util.workflow import mistral as utils - - -LOG = logging.getLogger(__name__) - - -STATUS_MAP = { - action_constants.LIVEACTION_STATUS_REQUESTED: 'RUNNING', - action_constants.LIVEACTION_STATUS_SCHEDULED: 'RUNNING', - action_constants.LIVEACTION_STATUS_DELAYED: 'RUNNING', - action_constants.LIVEACTION_STATUS_RUNNING: 'RUNNING', - action_constants.LIVEACTION_STATUS_SUCCEEDED: 'SUCCESS', - action_constants.LIVEACTION_STATUS_FAILED: 'ERROR', - action_constants.LIVEACTION_STATUS_TIMED_OUT: 'ERROR', - action_constants.LIVEACTION_STATUS_ABANDONED: 'ERROR', - action_constants.LIVEACTION_STATUS_PENDING: 'PAUSED', - action_constants.LIVEACTION_STATUS_CANCELING: 'CANCELLED', - action_constants.LIVEACTION_STATUS_CANCELED: 'CANCELLED', - action_constants.LIVEACTION_STATUS_PAUSING: 'PAUSED', - action_constants.LIVEACTION_STATUS_PAUSED: 'PAUSED', - action_constants.LIVEACTION_STATUS_RESUMING: 'RUNNING' -} - -MISTRAL_ACCEPTED_STATES = copy.deepcopy(action_constants.LIVEACTION_COMPLETED_STATES) -MISTRAL_ACCEPTED_STATES += [action_constants.LIVEACTION_STATUS_PAUSED] - - -def get_instance(): - return MistralCallbackHandler - - -def get_action_execution_id_from_url(url): - match = re.search('(.+)/action_executions/(.+)', url) - if not match or len(match.groups()) != 2: - raise ValueError('Unable to extract the action execution ID ' - 'from the callback URL (%s).' % (url)) - - return match.group(2) - - -class MistralCallbackHandler(callback.AsyncActionExecutionCallbackHandler): - - @classmethod - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def _update_action_execution(cls, url, data): - action_execution_id = get_action_execution_id_from_url(url) - - LOG.info('Sending callback to %s with data %s.', url, data) - - client = mistral.client( - mistral_url=cfg.CONF.mistral.v2_base_url, - username=cfg.CONF.mistral.keystone_username, - api_key=cfg.CONF.mistral.keystone_password, - project_name=cfg.CONF.mistral.keystone_project_name, - auth_url=cfg.CONF.mistral.keystone_auth_url, - cacert=cfg.CONF.mistral.cacert, - insecure=cfg.CONF.mistral.insecure) - - client.action_executions.update(action_execution_id, **data) - - @classmethod - def _encode(cls, value): - if isinstance(value, dict): - return {k: cls._encode(v) for k, v in six.iteritems(value)} - elif isinstance(value, list): - return [cls._encode(item) for item in value] - elif isinstance(value, six.string_types) and not six.PY3: - try: - value = value.decode('utf-8') - except Exception: - LOG.exception('Unable to decode value to utf-8.') - - try: - value = value.encode('unicode_escape') - except Exception: - LOG.exception('Unable to unicode escape value.') - - return value - else: - return value - - @classmethod - def callback(cls, liveaction): - assert isinstance(liveaction.callback, dict) - assert 'url' in liveaction.callback - - url = liveaction.callback['url'] - status = liveaction.status - result = liveaction.result - - if status not in MISTRAL_ACCEPTED_STATES: - LOG.warning('Unable to callback %s because status "%s" is not supported.', url, status) - return - - try: - if isinstance(result, six.string_types) and len(result) > 0 and result[0] in ['{', '[']: - value = ast.literal_eval(result) - if type(value) in [dict, list]: - result = value - - result = cls._encode(result) - output = json.dumps(result) if type(result) in [dict, list] else str(result) - output = output.replace('\\\\\\\\u', '\\\\u') - data = {'state': STATUS_MAP[status], 'output': output} - - cls._update_action_execution(url, data) - except Exception as e: - LOG.exception(e) diff --git a/contrib/runners/mistral_v2/mistral_v2/mistral_v2.py b/contrib/runners/mistral_v2/mistral_v2/mistral_v2.py deleted file mode 100644 index 1813cd1b13..0000000000 --- a/contrib/runners/mistral_v2/mistral_v2/mistral_v2.py +++ /dev/null @@ -1,563 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import copy -import uuid - -import retrying -import six -import yaml -from mistralclient.api import client as mistral -from oslo_config import cfg - -from st2common.runners.base import PollingAsyncActionRunner -from st2common.runners.base import get_metadata as get_runner_metadata -from st2common.constants import action as action_constants -from st2common import log as logging -from st2common.models.api.notification import NotificationsHelper -from st2common.persistence.execution import ActionExecution -from st2common.persistence.liveaction import LiveAction -from st2common.services import action as action_service -from st2common.util import jinja -from st2common.util.workflow import mistral as utils -from st2common.util.url import get_url_without_trailing_slash -from st2common.util.api import get_full_public_api_url -from st2common.util.api import get_mistral_api_url - -__all__ = [ - 'MistralRunner', - - 'get_runner', - 'get_metadata' -] - - -LOG = logging.getLogger(__name__) - - -class MistralRunner(PollingAsyncActionRunner): - - url = get_url_without_trailing_slash(cfg.CONF.mistral.v2_base_url) - - def __init__(self, runner_id): - super(MistralRunner, self).__init__(runner_id=runner_id) - self._on_behalf_user = cfg.CONF.system_user.user - self._notify = None - self._skip_notify_tasks = [] - self._client = mistral.client( - mistral_url=self.url, - username=cfg.CONF.mistral.keystone_username, - api_key=cfg.CONF.mistral.keystone_password, - project_name=cfg.CONF.mistral.keystone_project_name, - auth_url=cfg.CONF.mistral.keystone_auth_url, - cacert=cfg.CONF.mistral.cacert, - insecure=cfg.CONF.mistral.insecure) - - @classmethod - def is_polling_enabled(cls): - return cfg.CONF.mistral.enable_polling - - @staticmethod - def get_workflow_definition(entry_point): - with open(entry_point, 'r') as def_file: - return def_file.read() - - def pre_run(self): - super(MistralRunner, self).pre_run() - - if getattr(self, 'liveaction', None): - self._notify = getattr(self.liveaction, 'notify', None) - self._skip_notify_tasks = self.runner_parameters.get('skip_notify', []) - - @staticmethod - def _check_name(action_ref, is_workbook, def_dict): - # If workbook, change the value of the "name" key. - if is_workbook: - if def_dict.get('name') != action_ref: - raise Exception('Name of the workbook must be the same as the ' - 'fully qualified action name "%s".' % action_ref) - # If workflow, change the key name of the workflow. - else: - workflow_name = [k for k, v in six.iteritems(def_dict) if k != 'version'][0] - if workflow_name != action_ref: - raise Exception('Name of the workflow must be the same as the ' - 'fully qualified action name "%s".' % action_ref) - - def _save_workbook(self, name, def_yaml): - # If the workbook is not found, the mistral client throws a generic API exception. - try: - # Update existing workbook. - wb = self._client.workbooks.get(name) - except: - # Delete if definition was previously a workflow. - # If not found, an API exception is thrown. - try: - self._client.workflows.delete(name) - except: - pass - - # Create the new workbook. - wb = self._client.workbooks.create(def_yaml) - - # Update the workbook definition. - # pylint: disable=no-member - if wb.definition != def_yaml: - self._client.workbooks.update(def_yaml) - - def _save_workflow(self, name, def_yaml): - # If the workflow is not found, the mistral client throws a generic API exception. - try: - # Update existing workbook. - wf = self._client.workflows.get(name) - except: - # Delete if definition was previously a workbook. - # If not found, an API exception is thrown. - try: - self._client.workbooks.delete(name) - except: - pass - - # Create the new workflow. - wf = self._client.workflows.create(def_yaml)[0] - - # Update the workflow definition. - # pylint: disable=no-member - if wf.definition != def_yaml: - self._client.workflows.update(def_yaml) - - def _find_default_workflow(self, def_dict): - num_workflows = len(list(def_dict['workflows'].keys())) - - if num_workflows > 1: - fully_qualified_wf_name = self.runner_parameters.get('workflow') - if not fully_qualified_wf_name: - raise ValueError('Workbook definition is detected. ' - 'Default workflow cannot be determined.') - - wf_name = fully_qualified_wf_name[fully_qualified_wf_name.rindex('.') + 1:] - if wf_name not in def_dict['workflows']: - raise ValueError('Unable to find the workflow "%s" in the workbook.' - % fully_qualified_wf_name) - - return fully_qualified_wf_name - elif num_workflows == 1: - return '%s.%s' % (def_dict['name'], list(def_dict['workflows'].keys())[0]) - else: - raise Exception('There are no workflows in the workbook.') - - def _construct_workflow_execution_options(self): - # This URL is used by Mistral to talk back to the API - api_url = get_mistral_api_url() - endpoint = api_url + '/actionexecutions' - - # This URL is available in the context and can be used by the users inside a workflow, - # similar to "ST2_ACTION_API_URL" environment variable available to actions - public_api_url = get_full_public_api_url() - - # Build context with additional information - parent_context = { - 'execution_id': self.execution_id - } - - if getattr(self.liveaction, 'context', None): - parent_context.update(self.liveaction.context) - - # Convert jinja expressions in the params of Action Chain under the parent context - # into raw block. If there is any jinja expressions, Mistral will try to evaulate - # the expression. If there is a local context reference, the evaluation will fail - # because the local context reference is out of scope. - chain_ctx = parent_context.get('chain') or {} - - for attr in ['params', 'parameters']: - chain_params_ctx = chain_ctx.get(attr) or {} - - for k, v in six.iteritems(chain_params_ctx): - parent_context['chain'][attr][k] = jinja.convert_jinja_to_raw_block(v) - - st2_execution_context = { - 'api_url': api_url, - 'endpoint': endpoint, - 'parent': parent_context, - 'notify': {}, - 'skip_notify_tasks': self._skip_notify_tasks - } - - # Include notification information - if self._notify: - notify_dict = NotificationsHelper.from_model(notify_model=self._notify) - st2_execution_context['notify'] = notify_dict - - if self.auth_token: - st2_execution_context['auth_token'] = self.auth_token.token - - options = { - 'env': { - 'st2_execution_id': self.execution_id, - 'st2_liveaction_id': self.liveaction_id, - 'st2_action_api_url': public_api_url, - '__actions': { - 'st2.action': { - 'st2_context': st2_execution_context - } - } - } - } - - if not self.is_polling_enabled(): - options['notify'] = [{'type': 'st2'}] - - # Only used on reverse type workflows - task_name = self.runner_parameters.get('task_name', None) - if task_name is not None: - options['task_name'] = task_name - - return options - - def _get_resume_options(self): - return self.context.get('re-run', {}) - - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def run(self, action_parameters): - resume_options = self._get_resume_options() - - tasks_to_reset = resume_options.get('reset', []) - - task_specs = { - task_name: {'reset': task_name in tasks_to_reset} - for task_name in resume_options.get('tasks', []) - } - - resume = self.rerun_ex_ref and task_specs - - if resume: - result = self.resume_workflow(ex_ref=self.rerun_ex_ref, task_specs=task_specs) - else: - result = self.start_workflow(action_parameters=action_parameters) - - return result - - def start_workflow(self, action_parameters): - # Test connection - self._client.workflows.list() - - # Setup inputs for the workflow execution. - inputs = self.runner_parameters.get('context', dict()) - inputs.update(action_parameters) - - # Get workbook/workflow definition from file. - def_yaml = self.get_workflow_definition(self.entry_point) - def_dict = yaml.safe_load(def_yaml) - is_workbook = ('workflows' in def_dict) - - if not is_workbook: - # Non-workbook definition containing multiple workflows is not supported. - if len([k for k, _ in six.iteritems(def_dict) if k != 'version']) != 1: - raise Exception('Workflow (not workbook) definition is detected. ' - 'Multiple workflows is not supported.') - - action_ref = '%s.%s' % (self.action.pack, self.action.name) - self._check_name(action_ref, is_workbook, def_dict) - def_dict_xformed = utils.transform_definition(def_dict) - def_yaml_xformed = yaml.safe_dump(def_dict_xformed, default_flow_style=False) - - # Construct additional options for the workflow execution - options = self._construct_workflow_execution_options() - - # Save workbook/workflow definition. - if is_workbook: - self._save_workbook(action_ref, def_yaml_xformed) - default_workflow = self._find_default_workflow(def_dict_xformed) - execution = self._client.executions.create(default_workflow, - workflow_input=inputs, - **options) - else: - self._save_workflow(action_ref, def_yaml_xformed) - execution = self._client.executions.create(action_ref, - workflow_input=inputs, - **options) - - status = action_constants.LIVEACTION_STATUS_RUNNING - partial_results = {'tasks': []} - - # pylint: disable=no-member - current_context = { - 'execution_id': str(execution.id), - 'workflow_name': execution.workflow_name - } - - exec_context = self.context - exec_context = self._build_mistral_context(exec_context, current_context) - LOG.info('Mistral query context is %s' % exec_context) - - return (status, partial_results, exec_context) - - def _get_tasks(self, wf_ex_id, full_task_name, task_name, executions): - task_exs = self._client.tasks.list(workflow_execution_id=wf_ex_id) - - if '.' in task_name: - dot_pos = task_name.index('.') - parent_task_name = task_name[:dot_pos] - task_name = task_name[dot_pos + 1:] - - parent_task_ids = [task.id for task in task_exs if task.name == parent_task_name] - - workflow_ex_ids = [wf_ex.id for wf_ex in executions - if (getattr(wf_ex, 'task_execution_id', None) and - wf_ex.task_execution_id in parent_task_ids)] - - tasks = {} - - for sub_wf_ex_id in workflow_ex_ids: - tasks.update(self._get_tasks(sub_wf_ex_id, full_task_name, task_name, executions)) - - return tasks - - # pylint: disable=no-member - tasks = { - full_task_name: task.to_dict() - for task in task_exs - if task.name == task_name and task.state == 'ERROR' - } - - return tasks - - def _update_workflow_env(self, wf_ex_id, env): - wf_ex = self._client.executions.update(str(wf_ex_id), None, env=env) - - for task_ex in self._client.tasks.list(workflow_execution_id=wf_ex.id): - for subwf_ex in self._client.executions.list(task_execution_id=task_ex.id): - self._update_workflow_env(subwf_ex.id, env) - - def resume_workflow(self, ex_ref, task_specs): - mistral_ctx = ex_ref.context.get('mistral', dict()) - - if not mistral_ctx.get('execution_id'): - raise Exception('Unable to rerun because mistral execution_id is missing.') - - execution = self._client.executions.get(mistral_ctx.get('execution_id')) - - # pylint: disable=no-member - if execution.state not in ['ERROR']: - raise Exception('Workflow execution is not in a rerunable state.') - - executions = self._client.executions.list() - - tasks = {} - - for task_name, task_spec in six.iteritems(task_specs): - tasks.update(self._get_tasks(execution.id, task_name, task_name, executions)) - - missing_tasks = list(set(task_specs.keys()) - set(tasks.keys())) - if missing_tasks: - raise Exception('Only tasks in error state can be rerun. Unable to identify ' - 'rerunable tasks: %s. Please make sure that the task name is correct ' - 'and the task is in rerunable state.' % ', '.join(missing_tasks)) - - # Construct additional options for the workflow execution - options = self._construct_workflow_execution_options() - - # Update workflow env recursively. - self._update_workflow_env(execution.id, options.get('env', None)) - - # Re-run task list. - for task_name, task_obj in six.iteritems(tasks): - # pylint: disable=unexpected-keyword-arg - self._client.tasks.rerun( - task_obj['id'], - reset=task_specs[task_name].get('reset', False), - env=options.get('env', None) - ) - - status = action_constants.LIVEACTION_STATUS_RUNNING - partial_results = {'tasks': []} - - # pylint: disable=no-member - current_context = { - 'execution_id': str(execution.id), - 'workflow_name': execution.workflow_name - } - - exec_context = self.context - exec_context = self._build_mistral_context(exec_context, current_context) - LOG.info('Mistral query context is %s' % exec_context) - - return (status, partial_results, exec_context) - - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def pause(self): - mistral_ctx = self.context.get('mistral', dict()) - - if not mistral_ctx.get('execution_id'): - raise Exception('Unable to pause because mistral execution_id is missing.') - - # Pause the main workflow execution. Any non-workflow tasks that are still - # running will be allowed to complete gracefully. - self._client.executions.update(mistral_ctx.get('execution_id'), 'PAUSED') - - # If workflow is executed under another parent workflow, pause the corresponding - # action execution for the task in the parent workflow. - if 'parent' in getattr(self, 'context', {}) and mistral_ctx.get('action_execution_id'): - mistral_action_ex_id = mistral_ctx.get('action_execution_id') - self._client.action_executions.update(mistral_action_ex_id, 'PAUSED') - - # Identify the list of action executions that are workflows and cascade pause. - for child_exec_id in self.execution.children: - child_exec = ActionExecution.get(id=child_exec_id, raise_exception=True) - if (child_exec.runner['name'] in action_constants.WORKFLOW_RUNNER_TYPES and - child_exec.status == action_constants.LIVEACTION_STATUS_RUNNING): - action_service.request_pause( - LiveAction.get(id=child_exec.liveaction['id']), - self.context.get('user', None) - ) - - status = ( - action_constants.LIVEACTION_STATUS_PAUSING - if action_service.is_children_active(self.liveaction.id) - else action_constants.LIVEACTION_STATUS_PAUSED - ) - - return ( - status, - self.liveaction.result, - self.liveaction.context - ) - - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def resume(self): - mistral_ctx = self.context.get('mistral', dict()) - - if not mistral_ctx.get('execution_id'): - raise Exception('Unable to resume because mistral execution_id is missing.') - - # If workflow is executed under another parent workflow, resume the corresponding - # action execution for the task in the parent workflow. - if 'parent' in getattr(self, 'context', {}) and mistral_ctx.get('action_execution_id'): - mistral_action_ex_id = mistral_ctx.get('action_execution_id') - self._client.action_executions.update(mistral_action_ex_id, 'RUNNING') - - # Pause the main workflow execution. Any non-workflow tasks that are still - # running will be allowed to complete gracefully. - self._client.executions.update(mistral_ctx.get('execution_id'), 'RUNNING') - - # Identify the list of action executions that are workflows and cascade resume. - for child_exec_id in self.execution.children: - child_exec = ActionExecution.get(id=child_exec_id, raise_exception=True) - if (child_exec.runner['name'] in action_constants.WORKFLOW_RUNNER_TYPES and - child_exec.status == action_constants.LIVEACTION_STATUS_PAUSED): - action_service.request_resume( - LiveAction.get(id=child_exec.liveaction['id']), - self.context.get('user', None) - ) - - return ( - action_constants.LIVEACTION_STATUS_RUNNING, - self.execution.result, - self.execution.context - ) - - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def cancel(self): - mistral_ctx = self.context.get('mistral', dict()) - - if not mistral_ctx.get('execution_id'): - raise Exception('Unable to cancel because mistral execution_id is missing.') - - # Cancels the main workflow execution. Any non-workflow tasks that are still - # running will be allowed to complete gracefully. - self._client.executions.update(mistral_ctx.get('execution_id'), 'CANCELLED') - - # If workflow is executed under another parent workflow, cancel the corresponding - # action execution for the task in the parent workflow. - if 'parent' in getattr(self, 'context', {}) and mistral_ctx.get('action_execution_id'): - mistral_action_ex_id = mistral_ctx.get('action_execution_id') - self._client.action_executions.update(mistral_action_ex_id, 'CANCELLED') - - # Identify the list of action executions that are workflows and still running. - for child_exec_id in self.execution.children: - child_exec = ActionExecution.get(id=child_exec_id) - if (child_exec.runner['name'] in action_constants.WORKFLOW_RUNNER_TYPES and - child_exec.status in action_constants.LIVEACTION_CANCELABLE_STATES): - action_service.request_cancellation( - LiveAction.get(id=child_exec.liveaction['id']), - self.context.get('user', None) - ) - - status = ( - action_constants.LIVEACTION_STATUS_CANCELING - if action_service.is_children_active(self.liveaction.id) - else action_constants.LIVEACTION_STATUS_CANCELED - ) - - return ( - status, - self.liveaction.result, - self.liveaction.context - ) - - @staticmethod - def _build_mistral_context(parent, current): - """ - Mistral workflow might be kicked off in st2 by a parent Mistral - workflow. In that case, we need to make sure that the existing - mistral 'context' is moved as 'parent' and the child workflow - 'context' is added. - """ - parent = copy.deepcopy(parent) - context = dict() - - if not parent: - context['mistral'] = current - else: - if 'mistral' in list(parent.keys()): - orig_parent_context = parent.get('mistral', dict()) - actual_parent = dict() - if 'workflow_name' in list(orig_parent_context.keys()): - actual_parent['workflow_name'] = orig_parent_context['workflow_name'] - del orig_parent_context['workflow_name'] - if 'workflow_execution_id' in list(orig_parent_context.keys()): - actual_parent['workflow_execution_id'] = \ - orig_parent_context['workflow_execution_id'] - del orig_parent_context['workflow_execution_id'] - context['mistral'] = orig_parent_context - context['mistral'].update(current) - context['mistral']['parent'] = actual_parent - else: - context['mistral'] = current - - return context - - -def get_runner(): - return MistralRunner(str(uuid.uuid4())) - - -def get_metadata(): - return get_runner_metadata('mistral_v2')[0] diff --git a/contrib/runners/mistral_v2/mistral_v2/query.py b/contrib/runners/mistral_v2/mistral_v2/query.py deleted file mode 100644 index 464d2704a6..0000000000 --- a/contrib/runners/mistral_v2/mistral_v2/query.py +++ /dev/null @@ -1,333 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import random -import uuid - -from mistralclient.api import base as mistralclient_base -from mistralclient.api import client as mistral -from oslo_config import cfg -import eventlet -import retrying - -from st2common.query.base import Querier -from st2common.constants import action as action_constants -from st2common.exceptions import resultstracker as exceptions -from st2common import log as logging -from st2common.persistence.execution import ActionExecution -from st2common.util import action_db as action_utils -from st2common.util import jsonify -from st2common.util.url import get_url_without_trailing_slash -from st2common.util.workflow import mistral as utils - - -LOG = logging.getLogger(__name__) - -DONE_STATES = { - 'ERROR': action_constants.LIVEACTION_STATUS_FAILED, - 'SUCCESS': action_constants.LIVEACTION_STATUS_SUCCEEDED, - 'CANCELLED': action_constants.LIVEACTION_STATUS_CANCELED, - 'PAUSED': action_constants.LIVEACTION_STATUS_PAUSED -} - -ACTIVE_STATES = { - 'RUNNING': action_constants.LIVEACTION_STATUS_RUNNING -} - -CANCELED_STATES = [ - action_constants.LIVEACTION_STATUS_CANCELED, - action_constants.LIVEACTION_STATUS_CANCELING -] - -PAUSED_STATES = [ - action_constants.LIVEACTION_STATUS_PAUSED, - action_constants.LIVEACTION_STATUS_PAUSING -] - -RESUMING_STATES = [ - action_constants.LIVEACTION_STATUS_RESUMING -] - - -def get_instance(): - return MistralResultsQuerier(str(uuid.uuid4())) - - -class MistralResultsQuerier(Querier): - delete_state_object_on_error = False - - def __init__(self, id, *args, **kwargs): - super(MistralResultsQuerier, self).__init__(*args, **kwargs) - self._base_url = get_url_without_trailing_slash(cfg.CONF.mistral.v2_base_url) - self._client = mistral.client( - mistral_url=self._base_url, - username=cfg.CONF.mistral.keystone_username, - api_key=cfg.CONF.mistral.keystone_password, - project_name=cfg.CONF.mistral.keystone_project_name, - auth_url=cfg.CONF.mistral.keystone_auth_url, - cacert=cfg.CONF.mistral.cacert, - insecure=cfg.CONF.mistral.insecure) - self._jitter = cfg.CONF.mistral.jitter_interval - - @retrying.retry( - retry_on_exception=utils.retry_on_exceptions, - wait_exponential_multiplier=cfg.CONF.mistral.retry_exp_msec, - wait_exponential_max=cfg.CONF.mistral.retry_exp_max_msec, - stop_max_delay=cfg.CONF.mistral.retry_stop_max_msec) - def query(self, execution_id, query_context, last_query_time=None): - """ - Queries mistral for workflow results using v2 APIs. - :param execution_id: st2 execution_id (context to be used for logging/audit) - :type execution_id: ``str`` - :param query_context: context for the query to be made to mistral. This contains mistral - execution id. - :type query_context: ``object`` - :param last_query_time: Timestamp of last query. - :type last_query_time: ``float`` - :rtype: (``str``, ``object``) - """ - # Retrieve liveaction_db to append new result to existing result. - liveaction_db = action_utils.get_liveaction_by_id(execution_id) - - mistral_exec_id = query_context.get('mistral', {}).get('execution_id', None) - if not mistral_exec_id: - raise Exception('[%s] Missing mistral workflow execution ID in query context. %s' - % (execution_id, query_context)) - - LOG.info('[%s] Querying mistral execution %s...', execution_id, mistral_exec_id) - - try: - wf_result = self._get_workflow_result(execution_id, mistral_exec_id) - - stream = getattr(liveaction_db, 'result', {}) - - wf_tasks_result = self._get_workflow_tasks( - execution_id, - mistral_exec_id, - recorded_tasks=stream.get('tasks', []) - ) - - result = self._format_query_result( - liveaction_db.result, - wf_result, - wf_tasks_result - ) - except exceptions.ReferenceNotFoundError as exc: - LOG.exception('[%s] Unable to find reference.', execution_id) - return (action_constants.LIVEACTION_STATUS_FAILED, str(exc)) - except Exception: - LOG.exception('[%s] Unable to fetch mistral workflow result and tasks. %s', - execution_id, query_context) - raise - - # Retrieve liveaction_db again in case state has changed - # while the querier get results from mistral API above. - liveaction_db = action_utils.get_liveaction_by_id(execution_id) - - status = self._determine_execution_status( - liveaction_db, - result['extra']['state'], - result['tasks'] - ) - - LOG.info('[%s] Determined execution status: %s', execution_id, status) - LOG.debug('[%s] Combined execution result: %s', execution_id, result) - - return (status, result) - - def _get_workflow_result(self, st2_exec_id, mistral_exec_id): - """ - Returns the workflow status and output. Mistral workflow status will be converted - to st2 action status. - :param st2_exec_id: st2 execution ID - :type st2_exec_id: ``str`` - :param mistral_exec_id: Mistral execution ID - :type mistral_exec_id: ``str`` - :rtype: (``str``, ``dict``) - """ - try: - jitter = random.uniform(0, self._jitter) - eventlet.sleep(jitter) - execution = self._client.executions.get(mistral_exec_id) - except mistralclient_base.APIException as mistral_exc: - if 'not found' in str(mistral_exc): - raise exceptions.ReferenceNotFoundError(str(mistral_exc)) - raise mistral_exc - - result = jsonify.try_loads(execution.output) if execution.state in DONE_STATES else {} - - result['extra'] = { - 'state': execution.state, - 'state_info': execution.state_info - } - - LOG.info( - '[%s] Query returned status "%s" for mistral execution %s.', - st2_exec_id, - execution.state, - mistral_exec_id - ) - - return result - - def _get_workflow_tasks(self, st2_exec_id, mistral_exec_id, recorded_tasks=None): - """ - Returns the list of tasks for a workflow execution. - :param st2_exec_id: st2 execution ID - :type st2_exec_id: ``str`` - :param mistral_exec_id: Mistral execution ID - :type mistral_exec_id: ``str`` - :param recorded_tasks: The list of tasks recorded in the liveaction result. - :rtype: ``list`` - """ - result = [] - queries = [] - - if recorded_tasks is None: - recorded_tasks = [] - - try: - wf_tasks = self._client.tasks.list(workflow_execution_id=mistral_exec_id) - - for wf_task in wf_tasks: - recorded = list([x for x in recorded_tasks if x['id'] == wf_task.id]) - - if (not recorded or - recorded[0].get('state') != wf_task.state or - str(recorded[0].get('created_at')) != wf_task.created_at or - str(recorded[0].get('updated_at')) != wf_task.updated_at): - queries.append(wf_task) - - target_task_names = [wf_task.name for wf_task in queries] - - LOG.info( - '[%s] Querying the following tasks for mistral execution %s: %s', - st2_exec_id, - mistral_exec_id, - ', '.join(target_task_names) if target_task_names else 'None' - ) - - for wf_task in queries: - result.append(self._client.tasks.get(wf_task.id)) - - # Lets not blast requests but just space it out for better CPU profile - jitter = random.uniform(0, self._jitter) - eventlet.sleep(jitter) - except mistralclient_base.APIException as mistral_exc: - if 'not found' in str(mistral_exc): - raise exceptions.ReferenceNotFoundError(str(mistral_exc)) - raise mistral_exc - - return [self._format_task_result(task=entry.to_dict()) for entry in result] - - def _format_task_result(self, task): - """ - Format task result to follow the unified workflow result format. - """ - result = { - 'id': task['id'], - 'name': task['name'], - 'workflow_execution_id': task.get('workflow_execution_id', None), - 'workflow_name': task['workflow_name'], - 'created_at': task.get('created_at', None), - 'updated_at': task.get('updated_at', None), - 'state': task.get('state', None), - 'state_info': task.get('state_info', None) - } - - for attr in ['result', 'input', 'published']: - result[attr] = jsonify.try_loads(task.get(attr, None)) - - return result - - def _format_query_result(self, current_result, new_wf_result, new_wf_tasks_result): - result = new_wf_result - - new_wf_task_ids = [entry['id'] for entry in new_wf_tasks_result] - - old_wf_tasks_result_to_keep = [ - entry for entry in current_result.get('tasks', []) - if entry['id'] not in new_wf_task_ids - ] - - result['tasks'] = old_wf_tasks_result_to_keep + new_wf_tasks_result - - return result - - def _has_active_tasks(self, liveaction_db, mistral_wf_state, mistral_tasks): - # Identify if there are any active tasks in Mistral. - active_mistral_tasks = len([t for t in mistral_tasks if t['state'] in ACTIVE_STATES]) > 0 - - active_st2_tasks = False - execution = ActionExecution.get(liveaction__id=str(liveaction_db.id)) - - for child_exec_id in execution.children: - child_exec = ActionExecution.get(id=child_exec_id) - - # Catch exception where a child is requested twice due to st2mistral retrying - # from a st2 API connection failure. The first child will be stuck in requested - # while the mistral workflow is already completed. - if (mistral_wf_state in DONE_STATES and - child_exec.status == action_constants.LIVEACTION_STATUS_REQUESTED): - continue - - if (child_exec.status not in action_constants.LIVEACTION_COMPLETED_STATES and - child_exec.status != action_constants.LIVEACTION_STATUS_PAUSED): - active_st2_tasks = True - break - - if active_mistral_tasks: - LOG.info('There are active mistral tasks for %s.', str(liveaction_db.id)) - - if active_st2_tasks: - LOG.info('There are active st2 tasks for %s.', str(liveaction_db.id)) - - return active_mistral_tasks or active_st2_tasks - - def _determine_execution_status(self, liveaction_db, wf_state, tasks): - # Determine if liveaction is being canceled, paused, or resumed. - is_action_canceled = liveaction_db.status in CANCELED_STATES - is_action_paused = liveaction_db.status in PAUSED_STATES - is_action_resuming = liveaction_db.status in RESUMING_STATES - - # Identify the list of tasks that are still running or pausing. - active_tasks = self._has_active_tasks(liveaction_db, wf_state, tasks) - - # Keep the execution in running state if there are active tasks. - # In certain use cases, Mistral sets the workflow state to - # completion prior to task completion. - if is_action_canceled and active_tasks: - status = action_constants.LIVEACTION_STATUS_CANCELING - elif is_action_canceled and not active_tasks and wf_state not in DONE_STATES: - status = action_constants.LIVEACTION_STATUS_CANCELING - elif not is_action_canceled and active_tasks and wf_state == 'CANCELLED': - status = action_constants.LIVEACTION_STATUS_CANCELING - elif is_action_paused and active_tasks: - status = action_constants.LIVEACTION_STATUS_PAUSING - elif is_action_paused and not active_tasks and wf_state not in DONE_STATES: - status = action_constants.LIVEACTION_STATUS_PAUSING - elif not is_action_paused and active_tasks and wf_state == 'PAUSED': - status = action_constants.LIVEACTION_STATUS_PAUSING - elif is_action_resuming and wf_state == 'PAUSED': - status = action_constants.LIVEACTION_STATUS_RESUMING - elif wf_state in DONE_STATES and active_tasks: - status = action_constants.LIVEACTION_STATUS_RUNNING - elif wf_state in DONE_STATES and not active_tasks: - status = DONE_STATES[wf_state] - else: - status = action_constants.LIVEACTION_STATUS_RUNNING - - return status diff --git a/contrib/runners/mistral_v2/mistral_v2/runner.yaml b/contrib/runners/mistral_v2/mistral_v2/runner.yaml deleted file mode 100644 index 6a23ce9a47..0000000000 --- a/contrib/runners/mistral_v2/mistral_v2/runner.yaml +++ /dev/null @@ -1,24 +0,0 @@ -- aliases: [] - description: A runner for executing mistral v2 workflow. - enabled: true - name: mistral-v2 - query_module: mistral_v2 - runner_module: mistral_v2 - runner_parameters: - context: - default: {} - description: Additional workflow inputs. - type: object - skip_notify: - default: [] - description: List of tasks to skip notifications for. - type: array - task_name: - description: The name of the task to run for reverse workflow. - type: string - workflow: - description: The name of the workflow to run if the entry_point is a workbook - of many workflows. The name should be in the format "..". - If entry point is a workflow or a workbook with a single workflow, the runner - will identify the workflow automatically. - type: string diff --git a/contrib/runners/mistral_v2/query/__init__.py b/contrib/runners/mistral_v2/query/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/contrib/runners/mistral_v2/requirements.txt b/contrib/runners/mistral_v2/requirements.txt deleted file mode 100644 index f4a1c5a5ee..0000000000 --- a/contrib/runners/mistral_v2/requirements.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Don't edit this file. It's generated automatically! -# If you want to update global dependencies, modify fixed-requirements.txt -# and then run 'make requirements' to update requirements.txt for all -# components. -# If you want to update depdencies for a single component, modify the -# in-requirements.txt for that component and then run 'make requirements' to -# update the component requirements.txt - diff --git a/contrib/runners/mistral_v2/runner.yaml b/contrib/runners/mistral_v2/runner.yaml deleted file mode 120000 index 9cde8260f5..0000000000 --- a/contrib/runners/mistral_v2/runner.yaml +++ /dev/null @@ -1 +0,0 @@ -./mistral_v2/runner.yaml \ No newline at end of file diff --git a/contrib/runners/mistral_v2/setup.py b/contrib/runners/mistral_v2/setup.py deleted file mode 100644 index 20475793e9..0000000000 --- a/contrib/runners/mistral_v2/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import os.path - -from setuptools import setup -from setuptools import find_packages - -from dist_utils import fetch_requirements -from dist_utils import apply_vagrant_workaround - -from mistral_v2 import __version__ - -BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -REQUIREMENTS_FILE = os.path.join(BASE_DIR, 'requirements.txt') - -install_reqs, dep_links = fetch_requirements(REQUIREMENTS_FILE) - -apply_vagrant_workaround() -setup( - name='stackstorm-runner-mistral-v2', - version=__version__, - description=('Mistral v2 workflow action runner for StackStorm event-driven ' - 'automation platform'), - author='StackStorm', - author_email='info@stackstorm.com', - license='Apache License (2.0)', - url='https://stackstorm.com/', - install_requires=install_reqs, - dependency_links=dep_links, - test_suite='tests', - zip_safe=False, - include_package_data=True, - packages=find_packages(exclude=['setuptools', 'tests']), - package_data={'mistral_v2': ['runner.yaml']}, - scripts=[], - entry_points={ - 'st2common.runners.runner': [ - 'mistral-v2 = mistral_v2.mistral_v2', - ], - 'st2common.runners.query': [ - 'mistral-v2 = mistral_v2.query', - ], - 'st2common.runners.callback': [ - 'mistral-v2 = mistral_v2.callback', - ], - } -) diff --git a/contrib/runners/mistral_v2/tests/integration/__init__.py b/contrib/runners/mistral_v2/tests/integration/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/contrib/runners/mistral_v2/tests/unit/__init__.py b/contrib/runners/mistral_v2/tests/unit/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_utils.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_utils.py deleted file mode 100644 index 96969bcaae..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_utils.py +++ /dev/null @@ -1,62 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import unittest2 - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -tests_config.parse_args() - -from st2common.runners.base import get_callback_module - - -MISTRAL_RUNNER_NAME = 'mistral_v2' - - -class MistralUtilityTest(unittest2.TestCase): - - def test_get_action_execution_id_from_url(self): - mistral_callback_module = get_callback_module(MISTRAL_RUNNER_NAME) - - self.assertEqual( - '12345', - mistral_callback_module.get_action_execution_id_from_url( - 'http://127.0.0.1:8989/v2/action_executions/12345' - ) - ) - - self.assertRaises( - ValueError, - mistral_callback_module.get_action_execution_id_from_url, - 'http://127.0.0.1:8989/v2/action_executions' - ) - - self.assertRaises( - ValueError, - mistral_callback_module.get_action_execution_id_from_url, - '/action_executions/12345' - ) - - self.assertRaises( - ValueError, - mistral_callback_module.get_action_execution_id_from_url, - '/action_executions' - ) - - self.assertRaises( - ValueError, - mistral_callback_module.get_action_execution_id_from_url, - 'http://127.0.0.1:8989/v2/workflows/abcde' - ) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2.py deleted file mode 100644 index 33b344dc7f..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2.py +++ /dev/null @@ -1,969 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -import requests -import yaml - -from mistralclient.api.base import APIException -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import workbooks -from mistralclient.api.v2 import workflows -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -tests_config.parse_args() - -# NOTE: This has to be done before importing MistralRunner -cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') -cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') -cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.api.notification import NotificationsHelper -from st2common.models.db.liveaction import LiveActionDB -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -TEST_FIXTURES = { - 'workflows': [ - 'workbook_v2.yaml', - 'workbook_v2_many_workflows.yaml', - 'workbook_v2_many_workflows_no_default.yaml', - 'workflow_v2.yaml', - 'workflow_v2_many_workflows.yaml', - 'workflow_v2_reverse.yaml', - ], - 'actions': [ - 'workbook_v2.yaml', - 'workbook_v2_many_workflows.yaml', - 'workbook_v2_many_workflows_no_default.yaml', - 'workflow_v2.yaml', - 'workflow_v2_many_workflows.yaml', - 'workbook_v2_name_mismatch.yaml', - 'workflow_v2_name_mismatch.yaml', - 'workflow_v2_reverse.yaml', - ] -} - -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Action executions requirements -MISTRAL_EXECUTION = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': None} -ACTION_PARAMS = {'friend': 'Rocky'} -NON_EMPTY_RESULT = 'non-empty' - -# Workbook with a single workflow (direct) -WB1_META_FILE_NAME = TEST_FIXTURES['workflows'][0] -WB1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WB1_META_FILE_NAME -WB1_META_CONTENT = loader.load_meta_file(WB1_META_FILE_PATH) -WB1_NAME = WB1_META_CONTENT['pack'] + '.' + WB1_META_CONTENT['name'] -WB1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WB1_META_CONTENT['entry_point'] -WB1_ENTRY_POINT_X = WB1_ENTRY_POINT.replace(WB1_META_FILE_NAME, 'xformed_' + WB1_META_FILE_NAME) -WB1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WB1_ENTRY_POINT_X)) -WB1_YAML = yaml.safe_dump(WB1_SPEC, default_flow_style=False) -WB1 = workbooks.Workbook(None, {'name': WB1_NAME, 'definition': WB1_YAML}) -WB1_OLD = workbooks.Workbook(None, {'name': WB1_NAME, 'definition': ''}) -WB1_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WB1_EXEC['workflow_name'] = WB1_NAME - -# Workbook with many workflows (direct) -WB2_META_FILE_NAME = TEST_FIXTURES['workflows'][1] -WB2_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WB2_META_FILE_NAME -WB2_META_CONTENT = loader.load_meta_file(WB2_META_FILE_PATH) -WB2_NAME = WB2_META_CONTENT['pack'] + '.' + WB2_META_CONTENT['name'] -WB2_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WB2_META_CONTENT['entry_point'] -WB2_ENTRY_POINT_X = WB2_ENTRY_POINT.replace(WB2_META_FILE_NAME, 'xformed_' + WB2_META_FILE_NAME) -WB2_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WB2_ENTRY_POINT_X)) -WB2_YAML = yaml.safe_dump(WB2_SPEC, default_flow_style=False) -WB2 = workbooks.Workbook(None, {'name': WB2_NAME, 'definition': WB2_YAML}) -WB2_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WB2_EXEC['workflow_name'] = WB2_NAME - -# Workbook with many workflows (direct) but no default workflow is defined -WB3_META_FILE_NAME = TEST_FIXTURES['workflows'][2] -WB3_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WB3_META_FILE_NAME -WB3_META_CONTENT = loader.load_meta_file(WB3_META_FILE_PATH) -WB3_NAME = WB3_META_CONTENT['pack'] + '.' + WB3_META_CONTENT['name'] -WB3_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WB3_META_CONTENT['entry_point'] -WB3_ENTRY_POINT_X = WB3_ENTRY_POINT.replace(WB3_META_FILE_NAME, 'xformed_' + WB3_META_FILE_NAME) -WB3_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WB3_ENTRY_POINT_X)) -WB3_YAML = yaml.safe_dump(WB3_SPEC, default_flow_style=False) -WB3 = workbooks.Workbook(None, {'name': WB3_NAME, 'definition': WB3_YAML}) -WB3_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WB3_EXEC['workflow_name'] = WB3_NAME - -# Non-workbook with a single workflow (direct) -WF1_META_FILE_NAME = TEST_FIXTURES['workflows'][3] -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -WF1_OLD = workflows.Workflow(None, {'name': WF1_NAME, 'definition': ''}) -WF1_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WF1_EXEC['workflow_name'] = WF1_NAME - -# Non-workbook with a many workflows (direct) -WF2_META_FILE_NAME = TEST_FIXTURES['workflows'][4] -WF2_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF2_META_FILE_NAME -WF2_META_CONTENT = loader.load_meta_file(WF2_META_FILE_PATH) -WF2_NAME = WF2_META_CONTENT['pack'] + '.' + WF2_META_CONTENT['name'] -WF2_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF2_META_CONTENT['entry_point'] -WF2_ENTRY_POINT_X = WF2_ENTRY_POINT.replace(WF2_META_FILE_NAME, 'xformed_' + WF2_META_FILE_NAME) -WF2_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF2_ENTRY_POINT_X)) -WF2_YAML = yaml.safe_dump(WF2_SPEC, default_flow_style=False) -WF2 = workflows.Workflow(None, {'name': WF2_NAME, 'definition': WF2_YAML}) -WF2_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WF2_EXEC['workflow_name'] = WF2_NAME - -# Non-workbook with a single workflow (reverse) -WF3_META_FILE_NAME = TEST_FIXTURES['workflows'][5] -WF3_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF3_META_FILE_NAME -WF3_META_CONTENT = loader.load_meta_file(WF3_META_FILE_PATH) -WF3_NAME = WF3_META_CONTENT['pack'] + '.' + WF3_META_CONTENT['name'] -WF3_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF3_META_CONTENT['entry_point'] -WF3_ENTRY_POINT_X = WF3_ENTRY_POINT.replace(WF3_META_FILE_NAME, 'xformed_' + WF3_META_FILE_NAME) -WF3_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF3_ENTRY_POINT_X)) -WF3_YAML = yaml.safe_dump(WF3_SPEC, default_flow_style=False) -WF3 = workflows.Workflow(None, {'name': WF3_NAME, 'definition': WF3_YAML}) -WF3_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WF3_EXEC['workflow_name'] = WF3_NAME -WF3_REVERSE_TARGET_TASK_NAME = WF3_META_CONTENT['parameters']['task_name']['default'] - -# Data for the notify param -NOTIFY = [{'type': 'st2'}] - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralRunnerTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerTest, cls).setUpClass() - - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - @classmethod - def get_runner_class(cls, runner_name): - return runners.get_runner(runner_name, runner_name).__class__ - - def test_build_context(self): - parent = { - 'mistral': { - 'workflow_name': 'foo', - 'workflow_execution_id': 'b222b934-7473-4cd4-a2ec-e204a8c93848', - 'task_tags': None, - 'task_name': 'some_fancy_wf_task', - 'task_id': '6c7d4334-3e7d-49c6-918d-698e846affaf', - 'action_execution_id': '24da5c88-834c-4a65-8b56-4ddbd654eb68' - } - } - - current = { - 'workflow_name': 'foo.subwf', - 'workflow_execution_id': '135e3446-4c89-4afe-821f-6ec6a0849b27' - } - - context = MistralRunner._build_mistral_context(parent, current) - self.assertIsNotNone(context) - self.assertIn('parent', list(context['mistral'].keys())) - - parent_dict = { - 'workflow_name': parent['mistral']['workflow_name'], - 'workflow_execution_id': parent['mistral']['workflow_execution_id'] - } - - self.assertDictEqual(context['mistral']['parent'], parent_dict) - self.assertEqual(context['mistral']['workflow_execution_id'], - current['workflow_execution_id']) - - parent = None - context = MistralRunner._build_mistral_context(parent, current) - self.assertDictEqual(context['mistral'], current) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id) - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_under_parent_chain_with_jinja_params(self): - ac_ctx = { - 'chain': { - 'params': { - 'var1': 'foobar', - 'var2': '{{foobar}}', - 'var3': ['{{foo}}', '{{bar}}'], - 'var4': { - 'foobar': '{{foobar}}' - }, - 'var5': { - 'foobar': '{% for item in items %}foobar{% end for %}' - } - } - } - } - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ac_ctx) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id), - 'chain': { - 'params': { - 'var1': 'foobar', - 'var2': '{% raw %}{{foobar}}{% endraw %}', - 'var3': [ - '{% raw %}{{foo}}{% endraw %}', - '{% raw %}{{bar}}{% endraw %}' - ], - 'var4': { - 'foobar': '{% raw %}{{foobar}}{% endraw %}' - }, - 'var5': { - 'foobar': ( - '{% raw %}{% for item in items %}' - 'foobar{% end for %}{% endraw %}' - ) - } - } - } - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_under_parent_chain_with_jinja_parameters(self): - ac_ctx = { - 'chain': { - 'parameters': { - 'var1': 'foobar', - 'var2': '{{foobar}}', - 'var3': ['{{foo}}', '{{bar}}'], - 'var4': { - 'foobar': '{{foobar}}' - }, - } - } - } - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ac_ctx) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id), - 'chain': { - 'parameters': { - 'var1': 'foobar', - 'var2': '{% raw %}{{foobar}}{% endraw %}', - 'var3': [ - '{% raw %}{{foo}}{% endraw %}', - '{% raw %}{{bar}}{% endraw %}' - ], - 'var4': { - 'foobar': '{% raw %}{{foobar}}{% endraw %}' - } - } - } - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_under_parent_chain_with_nonetype_in_chain_context(self): - ac_ctx = {'chain': None} - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ac_ctx) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id), - 'chain': None - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_under_parent_chain_with_nonetype_in_params_context(self): - ac_ctx = {'chain': {'params': None}} - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ac_ctx) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id), - 'chain': { - 'params': None - } - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_with_st2_https(self): - cfg.CONF.set_override('api_url', 'https://0.0.0.0:9101', group='auth') - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'https://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'https://0.0.0.0:9101/v1', - 'endpoint': 'https://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id) - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_with_notifications(self): - notify_data = {'on_complete': {'routes': ['slack'], - 'message': '"@channel: Action succeeded."', 'data': {}}} - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, notify=notify_data) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id) - }, - 'notify': NotificationsHelper.from_model(liveaction.notify), - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(side_effect=requests.exceptions.ConnectionError('Connection refused'))) - def test_launch_workflow_mistral_offline(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Connection refused', liveaction.result['error']) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(side_effect=[requests.exceptions.ConnectionError(), []])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_mistral_retry(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(side_effect=[APIException(error_message='Duplicate entry.'), WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_duplicate_error(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1_OLD)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - workflows.WorkflowManager, 'update', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_when_workflow_definition_changed(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=Exception())) - @mock.patch.object( - workbooks.WorkbookManager, 'delete', - mock.MagicMock(side_effect=Exception())) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_when_workflow_not_exists(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF2)) - def test_launch_workflow_with_many_workflows(self): - liveaction = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Multiple workflows is not supported.', liveaction.result['error']) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=Exception())) - def test_launch_workflow_name_mistmatch(self): - action_ref = TEST_PACK + '.workflow_v2_name_mismatch' - liveaction = LiveActionDB(action=action_ref, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Name of the workflow must be the same', liveaction.result['error']) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF3)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF3])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF3_EXEC))) - def test_launch_workflow_reverse(self): - # no differences for liveaction (direct == reverse) - liveaction = LiveActionDB(action=WF3_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - # no differences for mistral_context (direct == reverse) - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF3_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF3_EXEC.get('workflow_name')) - - # no differences for workflow_input (direct == reverse) - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id) - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - # task_name must be passed to mistral.executions.create for reverse workflows - task_name = WF3_REVERSE_TARGET_TASK_NAME - - executions.ExecutionManager.create.assert_called_with( - WF3_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY, - task_name=task_name) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - workbooks.WorkbookManager, 'update', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_EXEC))) - def test_launch_workbook(self): - liveaction = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WB1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WB1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(return_value=WB2)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB2)) - @mock.patch.object( - workbooks.WorkbookManager, 'update', - mock.MagicMock(return_value=WB2)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB2_EXEC))) - def test_launch_workbook_with_many_workflows(self): - liveaction = LiveActionDB(action=WB2_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WB2_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WB2_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(return_value=WB3)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB3)) - @mock.patch.object( - workbooks.WorkbookManager, 'update', - mock.MagicMock(return_value=WB3)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB3_EXEC))) - def test_launch_workbook_with_many_workflows_no_default(self): - liveaction = LiveActionDB(action=WB3_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Default workflow cannot be determined.', liveaction.result['error']) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(return_value=WB1_OLD)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - workbooks.WorkbookManager, 'update', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_EXEC))) - def test_launch_when_workbook_definition_changed(self): - liveaction = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WB1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WB1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(side_effect=Exception())) - @mock.patch.object( - workflows.WorkflowManager, 'delete', - mock.MagicMock(side_effect=Exception())) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_EXEC))) - def test_launch_when_workbook_not_exists(self): - liveaction = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WB1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WB1_EXEC.get('workflow_name')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workbooks.WorkbookManager, 'get', - mock.MagicMock(side_effect=Exception())) - def test_launch_workbook_name_mismatch(self): - action_ref = TEST_PACK + '.workbook_v2_name_mismatch' - liveaction = LiveActionDB(action=action_ref, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Name of the workbook must be the same', liveaction.result['error']) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_auth.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_auth.py deleted file mode 100644 index 9e3d64d2b2..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_auth.py +++ /dev/null @@ -1,269 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -import yaml - -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import workflows -from mistralclient.auth import keystone -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -tests_config.parse_args() - -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.api.auth import TokenAPI -from st2common.models.db.liveaction import LiveActionDB -from st2common.runners import base as runners -from st2common.services import access as access_service -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import isotime -from st2common.util import date as date_utils -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -TEST_FIXTURES = { - 'workflows': [ - 'workflow_v2.yaml' - ], - 'actions': [ - 'workflow_v2.yaml' - ] -} - -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Action executions requirements -MISTRAL_EXECUTION = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': None} -ACTION_CONTEXT = {'user': 'stanley'} -ACTION_PARAMS = {'friend': 'Rocky'} -NON_EMPTY_RESULT = 'non-empty' - -# Non-workbook with a single workflow -WF1_META_FILE_NAME = TEST_FIXTURES['workflows'][0] -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -WF1_OLD = workflows.Workflow(None, {'name': WF1_NAME, 'definition': ''}) -WF1_EXEC = copy.deepcopy(MISTRAL_EXECUTION) -WF1_EXEC['workflow_name'] = WF1_NAME - -# Data for the notify param -NOTIFY = [{'type': 'st2'}] - -# Token for auth test cases -TOKEN_API = TokenAPI( - user=ACTION_CONTEXT['user'], token=uuid.uuid4().hex, - expiry=isotime.format(date_utils.get_datetime_utc_now(), offset=False)) -TOKEN_DB = TokenAPI.to_model(TOKEN_API) - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralAuthTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralAuthTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCase.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - def setUp(self): - super(MistralAuthTest, self).setUp() - - # Mock the local runner run method. - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - - def tearDown(self): - super(MistralAuthTest, self).tearDown() - cfg.CONF.set_default('keystone_username', None, group='mistral') - cfg.CONF.set_default('keystone_password', None, group='mistral') - cfg.CONF.set_default('keystone_project_name', None, group='mistral') - cfg.CONF.set_default('keystone_auth_url', None, group='mistral') - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - access_service, 'create_token', - mock.MagicMock(return_value=TOKEN_DB)) - def test_launch_workflow_with_st2_auth(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=ACTION_CONTEXT) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'auth_token': TOKEN_DB.token, - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'user': liveaction.context['user'], - 'execution_id': str(execution.id) - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) - - @mock.patch.object( - keystone.KeystoneAuthHandler, 'authenticate', - mock.MagicMock(return_value={})) - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_launch_workflow_with_mistral_auth(self): - cfg.CONF.set_default('keystone_username', 'foo', group='mistral') - cfg.CONF.set_default('keystone_password', 'bar', group='mistral') - cfg.CONF.set_default('keystone_project_name', 'admin', group='mistral') - cfg.CONF.set_default('keystone_auth_url', 'http://127.0.0.1:5000/v3', group='mistral') - - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - workflow_input = copy.deepcopy(ACTION_PARAMS) - workflow_input.update({'count': '3'}) - - env = { - 'st2_execution_id': str(execution.id), - 'st2_liveaction_id': str(liveaction.id), - 'st2_action_api_url': 'http://0.0.0.0:9101/v1', - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'parent': { - 'pack': 'mistral_tests', - 'execution_id': str(execution.id) - }, - 'notify': {}, - 'skip_notify_tasks': [] - } - } - } - } - - auth_req = { - 'auth_url': cfg.CONF.mistral.keystone_auth_url, - 'mistral_url': cfg.CONF.mistral.v2_base_url, - 'project_name': cfg.CONF.mistral.keystone_project_name, - 'username': cfg.CONF.mistral.keystone_username, - 'api_key': cfg.CONF.mistral.keystone_password, - 'insecure': False, - 'cacert': None - } - - keystone.KeystoneAuthHandler.authenticate.assert_called_with(auth_req, session=None) - - executions.ExecutionManager.create.assert_called_with( - WF1_NAME, workflow_input=workflow_input, env=env, notify=NOTIFY) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_callback.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_callback.py deleted file mode 100644 index 847dde75c2..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_callback.py +++ /dev/null @@ -1,539 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import six -import mock -import requests -from mock import call - -from mistralclient.api.v2 import action_executions -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -from six.moves import range -tests_config.parse_args() - -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.db.liveaction import LiveActionDB -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.runners import base as runner_base -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -MISTRAL_RUNNER_NAME = 'mistral_v2' -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -if six.PY2: - NON_EMPTY_RESULT = '{"stdout": "non-empty"}' -else: - NON_EMPTY_RESULT = u'{"stdout": "non-empty"}' - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralRunnerCallbackTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerCallbackTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCase.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - # Get an instance of the callback module and reference to mistral status map - cls.callback_module = runner_base.get_callback_module(MISTRAL_RUNNER_NAME) - cls.callback_class = cls.callback_module.get_instance() - cls.status_map = cls.callback_module.STATUS_MAP - - @classmethod - def get_runner_class(cls, package_name, module_name): - return runners.get_runner(package_name, module_name).__class__ - - def get_liveaction_instance(self, status=None, result=None): - callback = { - 'source': MISTRAL_RUNNER_NAME, - 'url': 'http://127.0.0.1:8989/v2/action_executions/12345' - } - - liveaction = LiveActionDB( - action='core.local', - parameters={'cmd': 'uname -a'}, - callback=callback, - context=dict() - ) - - if status: - liveaction.status = status - - if result: - liveaction.result = result - - return liveaction - - def test_callback_handler_status_map(self): - # Ensure all StackStorm status are mapped otherwise leads to zombie workflow. - self.assertListEqual(sorted(self.status_map.keys()), - sorted(action_constants.LIVEACTION_STATUSES)) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_text(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='' - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_dict(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = {'a': 1} - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='{"a": 1}' - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_json_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '{"a": 1}' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='{"a": 1}' - ) - - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = "{'a': 1}" - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='{"a": 1}' - ) - - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = u"{'a': 1}" - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='{"a": 1}' - ) - - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = "{u'a': u'xyz'}" - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='{"a": "xyz"}' - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_list(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = ["a", "b", "c"] - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='["a", "b", "c"]' - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_list_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '["a", "b", "c"]' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='["a", "b", "c"]' - ) - - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = u'["a", "b", "c"]' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='["a", "b", "c"]' - ) - - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '[u"a", "b", "c"]' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output='["a", "b", "c"]' - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_unicode_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '什麼' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '\\u4ec0\\u9ebc' - else: - expected_output = '什麼' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_unicode_encoded_as_ascii_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = '\u4ec0\u9ebc' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '\\\\u4ec0\\\\u9ebc' - else: - expected_output = '什麼' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_unicode_encoded_as_type(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = u'\u4ec0\u9ebc' - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '\\u4ec0\\u9ebc' - else: - expected_output = '什麼' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_list_with_unicode_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = ['\u4ec0\u9ebc'] - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '["\\\\u4ec0\\\\u9ebc"]' - else: - expected_output = '["\\u4ec0\\u9ebc"]' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_list_with_unicode_type(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = [u'\u4ec0\u9ebc'] - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '["\\\\u4ec0\\\\u9ebc"]' - else: - expected_output = '["\\u4ec0\\u9ebc"]' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_dict_with_unicode_str(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = {'a': '\u4ec0\u9ebc'} - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '{"a": "\\\\u4ec0\\\\u9ebc"}' - else: - expected_output = '{"a": "\\u4ec0\\u9ebc"}' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_handler_with_result_as_dict_with_unicode_type(self): - status = action_constants.LIVEACTION_STATUS_SUCCEEDED - result = {'a': u'\u4ec0\u9ebc'} - liveaction = self.get_liveaction_instance(status, result) - self.callback_class.callback(liveaction) - - if six.PY2: - expected_output = '{"a": "\\\\u4ec0\\\\u9ebc"}' - else: - expected_output = '{"a": "\\u4ec0\\u9ebc"}' - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', - state='SUCCESS', - output=expected_output - ) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_success_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - expected_mistral_status = self.status_map[local_run_result[0]] - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', state=expected_mistral_status, output=NON_EMPTY_RESULT) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_incomplete_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_RUNNING, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_run_result[0]) - self.assertFalse(action_executions.ActionExecutionManager.update.called) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_canceling_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_CANCELING, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - local_cancel_result = (action_constants.LIVEACTION_STATUS_CANCELING, NON_EMPTY_RESULT, None) - local_runner_cls.cancel = mock.Mock(return_value=local_cancel_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_cancel_result[0]) - - action_executions.ActionExecutionManager.update.assert_not_called() - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_canceled_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_CANCELED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - expected_mistral_status = self.status_map[local_run_result[0]] - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_run_result[0]) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', state=expected_mistral_status, output=NON_EMPTY_RESULT) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_pausing_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_PAUSING, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - local_pause_result = (action_constants.LIVEACTION_STATUS_PAUSING, NON_EMPTY_RESULT, None) - local_runner_cls.pause = mock.Mock(return_value=local_pause_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_pause_result[0]) - - action_executions.ActionExecutionManager.update.assert_not_called() - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_paused_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_PAUSED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - expected_mistral_status = self.status_map[local_run_result[0]] - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_run_result[0]) - - action_executions.ActionExecutionManager.update.assert_called_with( - '12345', state=expected_mistral_status, output=NON_EMPTY_RESULT) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_callback_resuming_state(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_RESUMING, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - local_resume_result = (action_constants.LIVEACTION_STATUS_RUNNING, NON_EMPTY_RESULT, None) - local_runner_cls.resume = mock.Mock(return_value=local_resume_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, local_resume_result[0]) - self.assertFalse(action_executions.ActionExecutionManager.update.called) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(side_effect=[ - requests.exceptions.ConnectionError(), - None])) - def test_callback_retry(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - calls = [call('12345', state='SUCCESS', output=NON_EMPTY_RESULT) for i in range(0, 2)] - action_executions.ActionExecutionManager.update.assert_has_calls(calls) - - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(side_effect=[ - requests.exceptions.ConnectionError(), - requests.exceptions.ConnectionError(), - requests.exceptions.ConnectionError(), - requests.exceptions.ConnectionError(), - None])) - def test_callback_retry_exhausted(self): - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - liveaction = self.get_liveaction_instance() - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - # This test initially setup mock for action_executions.ActionExecutionManager.update - # to fail the first 4 times and return success on the 5th times. The max attempts - # is set to 3. We expect only 3 calls to pass thru the update method. - calls = [call('12345', state='SUCCESS', output=NON_EMPTY_RESULT) for i in range(0, 2)] - action_executions.ActionExecutionManager.update.assert_has_calls(calls) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_cancel.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_cancel.py deleted file mode 100644 index bf1629a9b7..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_cancel.py +++ /dev/null @@ -1,306 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -from mock import call -import requests -import yaml -import eventlet - -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import workflows -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -from six.moves import range -tests_config.parse_args() - -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.db.execution import ActionExecutionDB -from st2common.models.db.liveaction import LiveActionDB -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher -from st2tests.mocks.liveaction import MockLiveActionPublisherNonBlocking - - -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Action executions requirements -ACTION_PARAMS = {'friend': 'Rocky'} -NON_EMPTY_RESULT = 'non-empty' - -# Non-workbook with a single workflow -WF1_META_FILE_NAME = 'workflow_v2.yaml' -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -WF1_OLD = workflows.Workflow(None, {'name': WF1_NAME, 'definition': ''}) -WF1_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': WF1_NAME} -WF1_EXEC_CANCELLED = copy.deepcopy(WF1_EXEC) -WF1_EXEC_CANCELLED['state'] = 'CANCELLED' - -# Workflow with a subworkflow action -WF2_META_FILE_NAME = 'workflow_v2_call_workflow_action.yaml' -WF2_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF2_META_FILE_NAME -WF2_META_CONTENT = loader.load_meta_file(WF2_META_FILE_PATH) -WF2_NAME = WF2_META_CONTENT['pack'] + '.' + WF2_META_CONTENT['name'] -WF2_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF2_META_CONTENT['entry_point'] -WF2_ENTRY_POINT_X = WF2_ENTRY_POINT.replace(WF2_META_FILE_NAME, 'xformed_' + WF2_META_FILE_NAME) -WF2_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF2_ENTRY_POINT_X)) -WF2_YAML = yaml.safe_dump(WF2_SPEC, default_flow_style=False) -WF2 = workflows.Workflow(None, {'name': WF2_NAME, 'definition': WF2_YAML}) -WF2_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': WF2_NAME} -WF2_EXEC_CANCELLED = copy.deepcopy(WF2_EXEC) -WF2_EXEC_CANCELLED['state'] = 'CANCELLED' - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -class MistralRunnerCancelTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerCancelTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCas.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - @classmethod - def get_runner_class(cls, runner_name): - return runners.get_runner(runner_name, runner_name).__class__ - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC_CANCELLED))) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - @mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) - def test_cancel(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - requester = cfg.CONF.system_user.user - liveaction, execution = action_service.request_cancellation(liveaction, requester) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_CANCELING) - executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'CANCELLED') - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=[WF2, WF1])) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(side_effect=[[WF2], [WF1]])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC_CANCELLED), - executions.Execution(None, WF1_EXEC_CANCELLED)])) - @mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) - def test_cancel_subworkflow_action(self): - liveaction1 = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - liveaction1 = self._wait_on_status(liveaction1, action_constants.LIVEACTION_STATUS_RUNNING) - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_RUNNING) - - # Mock the children of the parent execution to make this - # test case has subworkflow execution. - with mock.patch.object( - ActionExecutionDB, 'children', - new_callable=mock.PropertyMock) as action_ex_children_mock: - action_ex_children_mock.return_value = [execution2.id] - - mistral_context = liveaction1.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF2_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF2_EXEC.get('workflow_name')) - - requester = cfg.CONF.system_user.user - liveaction1, execution1 = action_service.request_cancellation(liveaction1, requester) - - liveaction1 = self._wait_on_status( - liveaction1, - action_constants.LIVEACTION_STATUS_CANCELED - ) - - self.assertTrue(executions.ExecutionManager.update.called) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'CANCELLED'), - mock.call(WF1_EXEC.get('id'), 'CANCELLED') - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[requests.exceptions.ConnectionError(), - executions.Execution(None, WF1_EXEC_CANCELLED)])) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - @mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) - def test_cancel_retry(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - requester = cfg.CONF.system_user.user - liveaction, execution = action_service.request_cancellation(liveaction, requester) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_CANCELING) - executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'CANCELLED') - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=requests.exceptions.ConnectionError('Connection refused'))) - @mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisherNonBlocking.publish_state)) - def test_cancel_retry_exhausted(self): - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - - MockLiveActionPublisherNonBlocking.wait_all() - eventlet.sleep(4) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - requester = cfg.CONF.system_user.user - liveaction, execution = action_service.request_cancellation(liveaction, requester) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_CANCELING) - - expected_call_count = 2 - self._wait_on_call_count(executions.ExecutionManager.update, expected_call_count) - calls = [call(WF1_EXEC.get('id'), 'CANCELLED') for i in range(0, expected_call_count)] - executions.ExecutionManager.update.assert_has_calls(calls) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_pause_and_resume.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_pause_and_resume.py deleted file mode 100644 index 2dc1224c80..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_pause_and_resume.py +++ /dev/null @@ -1,473 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -import yaml - -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import workflows -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -tests_config.parse_args() - -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.db.execution import ActionExecutionDB -from st2common.models.db.liveaction import LiveActionDB -from st2common.persistence.liveaction import LiveAction -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Action executions requirements -ACTION_PARAMS = {'friend': 'Rocky'} -NON_EMPTY_RESULT = 'non-empty' - -# Non-workbook with a single workflow -WF1_META_FILE_NAME = 'workflow_v2.yaml' -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -WF1_OLD = workflows.Workflow(None, {'name': WF1_NAME, 'definition': ''}) -WF1_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': WF1_NAME} -WF1_EXEC_PAUSED = copy.deepcopy(WF1_EXEC) -WF1_EXEC_PAUSED['state'] = 'PAUSED' - -# Workflow with a subworkflow action -WF2_META_FILE_NAME = 'workflow_v2_call_workflow_action.yaml' -WF2_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF2_META_FILE_NAME -WF2_META_CONTENT = loader.load_meta_file(WF2_META_FILE_PATH) -WF2_NAME = WF2_META_CONTENT['pack'] + '.' + WF2_META_CONTENT['name'] -WF2_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF2_META_CONTENT['entry_point'] -WF2_ENTRY_POINT_X = WF2_ENTRY_POINT.replace(WF2_META_FILE_NAME, 'xformed_' + WF2_META_FILE_NAME) -WF2_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF2_ENTRY_POINT_X)) -WF2_YAML = yaml.safe_dump(WF2_SPEC, default_flow_style=False) -WF2 = workflows.Workflow(None, {'name': WF2_NAME, 'definition': WF2_YAML}) -WF2_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': WF2_NAME} -WF2_EXEC_PAUSED = copy.deepcopy(WF2_EXEC) -WF2_EXEC_PAUSED['state'] = 'PAUSED' - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralRunnerPauseResumeTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerPauseResumeTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCas.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - @classmethod - def get_runner_class(cls, runner_name): - return runners.get_runner(runner_name, runner_name).__class__ - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC_PAUSED))) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - def test_pause(self): - # Launch the workflow execution. - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - # Pause the workflow execution. - requester = cfg.CONF.system_user.user - liveaction, execution = action_service.request_pause(liveaction, requester) - executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'PAUSED') - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_PAUSING) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF1_EXEC_PAUSED), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - def test_resume(self): - # Launch the workflow execution. - liveaction = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction, execution = action_service.request(liveaction) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - mistral_context = liveaction.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF1_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF1_EXEC.get('workflow_name')) - - # Pause the workflow execution. - requester = cfg.CONF.system_user.user - liveaction, execution = action_service.request_pause(liveaction, requester) - executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'PAUSED') - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_PAUSING) - - # Manually update the liveaction from pausing to paused. The paused state - # is usually updated by the mistral querier. - action_service.update_status(liveaction, action_constants.LIVEACTION_STATUS_PAUSED) - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the workflow execution. - liveaction, execution = action_service.request_resume(liveaction, requester) - executions.ExecutionManager.update.assert_called_with(WF1_EXEC.get('id'), 'RUNNING') - liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_RUNNING) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=[WF2, WF1])) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(side_effect=[[WF2], [WF1]])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC_PAUSED), - executions.Execution(None, WF1_EXEC_PAUSED), - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - def test_resume_subworkflow_action(self): - requester = cfg.CONF.system_user.user - - liveaction1 = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - liveaction1 = self._wait_on_status(liveaction1, action_constants.LIVEACTION_STATUS_RUNNING) - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_RUNNING) - - # Mock the children of the parent execution to make this - # test case has subworkflow execution. - with mock.patch.object( - ActionExecutionDB, 'children', - new_callable=mock.PropertyMock) as action_ex_children_mock: - action_ex_children_mock.return_value = [execution2.id] - - mistral_context = liveaction1.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF2_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF2_EXEC.get('workflow_name')) - - # Pause the parent liveaction and check that the request is cascaded down. - liveaction1, execution1 = action_service.request_pause(liveaction1, requester) - - self.assertTrue(executions.ExecutionManager.update.called) - self.assertEqual(executions.ExecutionManager.update.call_count, 2) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'PAUSED'), - mock.call(WF1_EXEC.get('id'), 'PAUSED') - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_PAUSING) - - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - self.assertEqual(liveaction2.status, action_constants.LIVEACTION_STATUS_PAUSING) - - # Manually set the liveaction status to PAUSED. - action_service.update_status(liveaction2, action_constants.LIVEACTION_STATUS_PAUSED) - action_service.update_status(liveaction1, action_constants.LIVEACTION_STATUS_PAUSED) - - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_PAUSED) - - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - self.assertEqual(liveaction2.status, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the parent liveaction and check that the request is cascaded down. - liveaction1, execution1 = action_service.request_resume(liveaction1, requester) - - # Includes the previous calls. - self.assertTrue(executions.ExecutionManager.update.called) - self.assertEqual(executions.ExecutionManager.update.call_count, 4) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'PAUSED'), - mock.call(WF1_EXEC.get('id'), 'PAUSED'), - mock.call(WF2_EXEC.get('id'), 'RUNNING'), - mock.call(WF1_EXEC.get('id'), 'RUNNING') - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_RUNNING) - - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - self.assertEqual(liveaction2.status, action_constants.LIVEACTION_STATUS_RUNNING) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=[WF2, WF1])) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(side_effect=[[WF2], [WF1]])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC_PAUSED), - executions.Execution(None, WF1_EXEC_PAUSED), - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - def test_pause_missing_subworkflow_action(self): - requester = cfg.CONF.system_user.user - - liveaction1 = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - liveaction1 = self._wait_on_status(liveaction1, action_constants.LIVEACTION_STATUS_RUNNING) - - # Mock the children of the parent execution to make this - # test case has subworkflow execution. - with mock.patch.object( - ActionExecutionDB, 'children', - new_callable=mock.PropertyMock) as action_ex_children_mock: - action_ex_children_mock.return_value = [uuid.uuid4().hex] - - mistral_context = liveaction1.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF2_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF2_EXEC.get('workflow_name')) - - # Pause the parent liveaction and check that the request is cascaded down. - liveaction1, execution1 = action_service.request_pause(liveaction1, requester) - - self.assertTrue(executions.ExecutionManager.update.called) - self.assertEqual(executions.ExecutionManager.update.call_count, 1) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'PAUSED'), - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - # The workflow execution will fail because the liveaction for the subworkflow - # should not be missing and we do not know what state it is in. - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('not a valid ObjectId', liveaction1.result.get('error', '')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(side_effect=[WF2, WF1])) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(side_effect=[[WF2], [WF1]])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WF2_EXEC_PAUSED), - executions.Execution(None, WF1_EXEC_PAUSED), - executions.Execution(None, WF2_EXEC), - executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - action_service, 'is_children_active', - mock.MagicMock(return_value=True)) - def test_resume_missing_subworkflow_action(self): - requester = cfg.CONF.system_user.user - - liveaction1 = LiveActionDB(action=WF2_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - liveaction1 = self._wait_on_status(liveaction1, action_constants.LIVEACTION_STATUS_RUNNING) - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_RUNNING) - - # Mock the children of the parent execution to make this - # test case has subworkflow execution. - with mock.patch.object( - ActionExecutionDB, 'children', - new_callable=mock.PropertyMock) as action_ex_children_mock: - action_ex_children_mock.return_value = [execution2.id] - - mistral_context = liveaction1.context.get('mistral', None) - self.assertIsNotNone(mistral_context) - self.assertEqual(mistral_context['execution_id'], WF2_EXEC.get('id')) - self.assertEqual(mistral_context['workflow_name'], WF2_EXEC.get('workflow_name')) - - # Pause the parent liveaction and check that the request is cascaded down. - liveaction1, execution1 = action_service.request_pause(liveaction1, requester) - - self.assertTrue(executions.ExecutionManager.update.called) - self.assertEqual(executions.ExecutionManager.update.call_count, 2) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'PAUSED'), - mock.call(WF1_EXEC.get('id'), 'PAUSED') - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_PAUSING) - - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - self.assertEqual(liveaction2.status, action_constants.LIVEACTION_STATUS_PAUSING) - - # Manually set the liveaction status to PAUSED. - action_service.update_status(liveaction2, action_constants.LIVEACTION_STATUS_PAUSED) - action_service.update_status(liveaction1, action_constants.LIVEACTION_STATUS_PAUSED) - - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_PAUSED) - - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - self.assertEqual(liveaction2.status, action_constants.LIVEACTION_STATUS_PAUSED) - - # Mock the children of the parent execution to make this - # test case has subworkflow execution. - with mock.patch.object( - ActionExecutionDB, 'children', - new_callable=mock.PropertyMock) as action_ex_children_mock: - action_ex_children_mock.return_value = [uuid.uuid4().hex] - - # Resume the parent liveaction and check that the request is cascaded down. - liveaction1, execution1 = action_service.request_resume(liveaction1, requester) - - # Includes the previous calls. - self.assertTrue(executions.ExecutionManager.update.called) - self.assertEqual(executions.ExecutionManager.update.call_count, 3) - - calls = [ - mock.call(WF2_EXEC.get('id'), 'PAUSED'), - mock.call(WF1_EXEC.get('id'), 'PAUSED'), - mock.call(WF2_EXEC.get('id'), 'RUNNING'), - ] - - executions.ExecutionManager.update.assert_has_calls(calls, any_order=False) - - # The workflow execution will fail because the liveaction for the subworkflow - # should not be missing and we do not know what state it is in. - liveaction1 = LiveAction.get_by_id(str(liveaction1.id)) - self.assertEqual(liveaction1.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('not a valid ObjectId', liveaction1.result.get('error', '')) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_policy.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_policy.py deleted file mode 100644 index facab889a2..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_policy.py +++ /dev/null @@ -1,274 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -import yaml - -from mistralclient.api.v2 import action_executions -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import workflows -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -from six.moves import range -tests_config.parse_args() - -import st2common -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import policiesregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.db.liveaction import LiveActionDB -from st2common.persistence.liveaction import LiveAction -from st2common.persistence.policy import Policy -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -MISTRAL_RUNNER_NAME = 'mistral_v2' -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Non-workbook with a single workflow -WF1_META_FILE_NAME = 'workflow_v2.yaml' -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -MISTRAL_EXECUTION = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'workflow_name': WF1_NAME} -WF1_EXEC = copy.deepcopy(MISTRAL_EXECUTION) - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralRunnerPolicyTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerPolicyTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCas.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - def setUp(self): - super(MistralRunnerPolicyTest, self).setUp() - - # Start with a clean database for each test. - self._establish_connection_and_re_create_db() - - # Register runners. - runnersregistrar.register_runners() - - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - # Register policies required for the tests. - policiesregistrar.register_policy_types(st2common) - - policies_registrar = policiesregistrar.PolicyRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - policies_registrar.register_from_pack(pack) - - @classmethod - def get_runner_class(cls, runner_name): - return runners.get_runner(runner_name, runner_name).__class__ - - def _drop_all_other_policies(self, test_policy): - policy_dbs = [policy_db for policy_db in Policy.get_all() if policy_db.ref != test_policy] - - for policy_db in policy_dbs: - Policy.delete(policy_db, publish=False) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_cancel_on_task_action_concurrency(self): - # Delete other policies in the test pack to avoid conflicts. - required_policy = 'mistral_tests.cancel_on_concurrency' - self._drop_all_other_policies(required_policy) - - # Get threshold from the policy. - policy = Policy.get_by_ref(required_policy) - threshold = policy.parameters.get('threshold', 0) - self.assertGreater(threshold, 0) - - # Launch instances of the workflow up to threshold. - for i in range(0, threshold): - liveaction = LiveActionDB(action=WF1_NAME, parameters={'friend': 'friend' + str(i)}) - liveaction, execution1 = action_service.request(liveaction) - - liveaction = self._wait_on_status( - liveaction, - action_constants.LIVEACTION_STATUS_RUNNING - ) - - # Check number of running instances - running = LiveAction.count( - action=WF1_NAME, status=action_constants.LIVEACTION_STATUS_RUNNING) - - self.assertEqual(running, threshold) - - # Mock the mistral runner cancel method to assert cancel is called. - mistral_runner_cls = runners.get_runner('mistral-v2').__class__ - mock_cancel_return_value = (action_constants.LIVEACTION_STATUS_CANCELING, None, None) - mock_cancel = mock.MagicMock(return_value=mock_cancel_return_value) - - with mock.patch.object(mistral_runner_cls, 'cancel', mock_cancel): - # Launch another instance of the workflow with mistral callback defined - # to indicate that this is executed under a workflow. - callback = { - 'source': MISTRAL_RUNNER_NAME, - 'url': 'http://127.0.0.1:8989/v2/action_executions/12345' - } - - params = {'friend': 'grande animalerie'} - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=params, callback=callback) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - - # Assert cancel has been called. - liveaction2 = self._wait_on_status( - liveaction2, - action_constants.LIVEACTION_STATUS_CANCELING - ) - - mistral_runner_cls.cancel.assert_called_once_with() - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - action_executions.ActionExecutionManager, 'update', - mock.MagicMock(return_value=None)) - def test_cancel_on_task_action_concurrency_by_attr(self): - # Delete other policies in the test pack to avoid conflicts. - required_policy = 'mistral_tests.cancel_on_concurrency_by_attr' - self._drop_all_other_policies(required_policy) - - # Get threshold from the policy. - policy = Policy.get_by_ref(required_policy) - threshold = policy.parameters.get('threshold', 0) - self.assertGreater(threshold, 0) - - params = {'friend': 'grande animalerie'} - - # Launch instances of the workflow up to threshold. - for i in range(0, threshold): - liveaction = LiveActionDB(action=WF1_NAME, parameters=params) - liveaction, execution1 = action_service.request(liveaction) - liveaction = LiveAction.get_by_id(str(liveaction.id)) - - liveaction = self._wait_on_status( - liveaction, - action_constants.LIVEACTION_STATUS_RUNNING - ) - - # Check number of running instances - running = LiveAction.count( - action=WF1_NAME, status=action_constants.LIVEACTION_STATUS_RUNNING, - parameters__friend=params['friend']) - - self.assertEqual(running, threshold) - - # Mock the mistral runner cancel method to assert cancel is called. - mistral_runner_cls = runners.get_runner('mistral-v2').__class__ - mock_cancel_return_value = (action_constants.LIVEACTION_STATUS_CANCELING, None, None) - mock_cancel = mock.MagicMock(return_value=mock_cancel_return_value) - - with mock.patch.object(mistral_runner_cls, 'cancel', mock_cancel): - # Launch another instance of the workflow with mistral callback defined - # to indicate that this is executed under a workflow. - callback = { - 'source': MISTRAL_RUNNER_NAME, - 'url': 'http://127.0.0.1:8989/v2/action_executions/12345' - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=params, callback=callback) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = LiveAction.get_by_id(str(liveaction2.id)) - - # Assert cancel has been called. - liveaction2 = self._wait_on_status( - liveaction2, - action_constants.LIVEACTION_STATUS_CANCELING - ) - - mistral_runner_cls.cancel.assert_called_once_with() diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_querier.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_querier.py deleted file mode 100644 index ba96cb45f9..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_querier.py +++ /dev/null @@ -1,1261 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import datetime -import json -import requests -import time -import uuid - -import mock -from mock import call - -from mistralclient.api import base as mistralclient_base -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import tasks -from oslo_config import cfg - -import st2tests.config as tests_config -from six.moves import range -tests_config.parse_args() - -from st2common.constants import action as action_constants -from st2common.exceptions import db as db_exc -from st2common.models.db.execution import ActionExecutionDB -from st2common.models.db.liveaction import LiveActionDB -from st2common.persistence.execution import ActionExecution -from st2common.util import action_db as action_utils -from st2common.runners.base import get_query_module -from st2tests import DbTestCase - - -MOCK_WF_TASKS_SUCCEEDED = [ - {'name': 'task1', 'state': 'SUCCESS'}, - {'name': 'task2', 'state': 'SUCCESS'} -] - -MOCK_WF_TASKS_ERRORED = [ - {'name': 'task1', 'state': 'SUCCESS'}, - {'name': 'task2', 'state': 'ERROR'} -] - -MOCK_WF_TASKS_RUNNING = [ - {'name': 'task1', 'state': 'SUCCESS'}, - {'name': 'task2', 'state': 'RUNNING'} -] - -MOCK_WF_TASKS_WAITING = [ - {'name': 'task1', 'state': 'SUCCESS'}, - {'name': 'task2', 'state': 'WAITING'} -] - -MOCK_WF_TASKS_PAUSED = [ - {'name': 'task1', 'state': 'SUCCESS'}, - {'name': 'task2', 'state': 'PAUSED'} -] - -MOCK_WF_EX_DATA = { - 'id': uuid.uuid4().hex, - 'name': 'main', - 'output': '{"k1": "v1"}', - 'state': 'SUCCESS', - 'state_info': None -} - -MOCK_WF_EX = executions.Execution(None, MOCK_WF_EX_DATA) - -MOCK_WF_EX_TASKS_DATA = [ - { - 'id': uuid.uuid4().hex, - 'name': 'task1', - 'workflow_execution_id': MOCK_WF_EX_DATA['id'], - 'workflow_name': MOCK_WF_EX_DATA['name'], - 'created_at': str(datetime.datetime.utcnow()), - 'updated_at': str(datetime.datetime.utcnow()), - 'state': 'SUCCESS', - 'state_info': None, - 'input': '{"a": "b"}', - 'result': '{"c": "d"}', - 'published': '{"c": "d"}' - }, - { - 'id': uuid.uuid4().hex, - 'name': 'task2', - 'workflow_execution_id': MOCK_WF_EX_DATA['id'], - 'workflow_name': MOCK_WF_EX_DATA['name'], - 'created_at': str(datetime.datetime.utcnow()), - 'updated_at': str(datetime.datetime.utcnow()), - 'state': 'SUCCESS', - 'state_info': None, - 'input': '{"e": "f", "g": "h"}', - 'result': '{"i": "j", "k": "l"}', - 'published': '{"k": "l"}' - } -] - -MOCK_WF_EX_TASKS = [ - tasks.Task(None, MOCK_WF_EX_TASKS_DATA[0]), - tasks.Task(None, MOCK_WF_EX_TASKS_DATA[1]) -] - -MOCK_QRY_CONTEXT = { - 'mistral': { - 'execution_id': uuid.uuid4().hex - } -} - -MOCK_LIVEACTION_RESULT = { - 'tasks': [ - { - 'id': MOCK_WF_EX_TASKS_DATA[0]['id'], - 'name': MOCK_WF_EX_TASKS_DATA[0]['name'], - 'workflow_execution_id': MOCK_WF_EX_TASKS_DATA[0]['workflow_execution_id'], - 'workflow_name': MOCK_WF_EX_TASKS_DATA[0]['workflow_name'], - 'created_at': MOCK_WF_EX_TASKS_DATA[0]['created_at'], - 'updated_at': MOCK_WF_EX_TASKS_DATA[0]['updated_at'], - 'state': MOCK_WF_EX_TASKS_DATA[0]['state'], - 'state_info': MOCK_WF_EX_TASKS_DATA[0]['state_info'], - 'input': json.loads(MOCK_WF_EX_TASKS_DATA[0]['input']), - 'result': json.loads(MOCK_WF_EX_TASKS_DATA[0]['result']), - 'published': json.loads(MOCK_WF_EX_TASKS_DATA[0]['published']) - } - ] -} - -MOCK_WF_EX_INCOMPLETE_TASKS_DATA = [ - { - 'id': uuid.uuid4().hex, - 'name': 'task1', - 'workflow_execution_id': MOCK_WF_EX_DATA['id'], - 'workflow_name': MOCK_WF_EX_DATA['name'], - 'created_at': str(datetime.datetime.utcnow() - datetime.timedelta(seconds=180)), - 'updated_at': str(datetime.datetime.utcnow()), - 'state': 'RUNNING', - 'state_info': None, - 'input': '{"a": "b"}', - 'result': '{"c": "d"}', - 'published': '{"c": "d"}' - }, - { - 'id': uuid.uuid4().hex, - 'name': 'task2', - 'workflow_execution_id': MOCK_WF_EX_DATA['id'], - 'workflow_name': MOCK_WF_EX_DATA['name'], - 'created_at': str(datetime.datetime.utcnow() - datetime.timedelta(seconds=180)), - 'updated_at': str(datetime.datetime.utcnow()), - 'state': 'RUNNING', - 'state_info': None, - 'input': '{"e": "f", "g": "h"}', - 'result': '{"i": "j", "k": "l"}', - 'published': '{"k": "l"}' - } -] - -MOCK_WF_EX_INCOMPLETE_TASKS = [ - tasks.Task(None, MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]), - tasks.Task(None, MOCK_WF_EX_INCOMPLETE_TASKS_DATA[1]) -] - -MOCK_LIVEACTION_OUTDATED_INCOMPLETE_TASKS_RESULT = { - 'tasks': [ - { - 'id': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['id'], - 'name': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['name'], - 'workflow_execution_id': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['workflow_execution_id'], - 'workflow_name': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['workflow_name'], - 'created_at': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['created_at'], - 'updated_at': str(datetime.datetime.utcnow() - datetime.timedelta(seconds=120)), - 'state': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['state'], - 'state_info': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['state_info'], - 'input': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['input']), - 'result': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['result']), - 'published': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['published']) - } - ] -} - -MOCK_LIVEACTION_UP_TO_DATE_INCOMPLETE_TASKS_RESULT = { - 'tasks': [ - { - 'id': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['id'], - 'name': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['name'], - 'workflow_execution_id': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['workflow_execution_id'], - 'workflow_name': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['workflow_name'], - 'created_at': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['created_at'], - 'updated_at': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['updated_at'], - 'state': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['state'], - 'state_info': MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['state_info'], - 'input': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['input']), - 'result': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['result']), - 'published': json.loads(MOCK_WF_EX_INCOMPLETE_TASKS_DATA[0]['published']) - } - ] -} - -MOCK_CHILD_ACTIONEXECUTION_REQUESTED = ActionExecutionDB( - action={'ref': 'mock.task'}, - runner={'name': 'local-shell-cmd'}, - liveaction={'id': uuid.uuid4().hex}, - status=action_constants.LIVEACTION_STATUS_REQUESTED, - children=[] -) - -MOCK_CHILD_ACTIONEXECUTION_RUNNING = ActionExecutionDB( - action={'ref': 'mock.task'}, - runner={'name': 'local-shell-cmd'}, - liveaction={'id': uuid.uuid4().hex}, - status=action_constants.LIVEACTION_STATUS_RUNNING, - children=[] -) - -MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED = ActionExecutionDB( - action={'ref': 'mock.task'}, - runner={'name': 'local-shell-cmd'}, - liveaction={'id': uuid.uuid4().hex}, - status=action_constants.LIVEACTION_STATUS_SUCCEEDED, - children=[] -) - -MOCK_CHILD_ACTIONEXECUTION_PAUSED = ActionExecutionDB( - action={'ref': 'mock.task'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': uuid.uuid4().hex}, - status=action_constants.LIVEACTION_STATUS_PAUSED, - children=[] -) - -MOCK_LIVEACTION_RUNNING = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_RUNNING -) - -MOCK_ACTIONEXECUTION_RUNNING_CHILD_REQUESTED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_RUNNING.id}, - status=action_constants.LIVEACTION_STATUS_RUNNING, - children=[MOCK_CHILD_ACTIONEXECUTION_REQUESTED.id] -) - -MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_RUNNING.id}, - status=action_constants.LIVEACTION_STATUS_RUNNING, - children=[MOCK_CHILD_ACTIONEXECUTION_RUNNING.id] -) - -MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_RUNNING.id}, - status=action_constants.LIVEACTION_STATUS_RUNNING, - children=[MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED.id] -) - -MOCK_LIVEACTION_RUNNING_WITH_STREAMING_RESULT = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_RUNNING, - result=MOCK_LIVEACTION_RESULT -) - -MOCK_LIVEACTION_RUNNING_WITH_OUTDATED_INCOMPLETE_TASKS_STREAMING_RESULT = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_RUNNING, - result=MOCK_LIVEACTION_OUTDATED_INCOMPLETE_TASKS_RESULT -) - -MOCK_LIVEACTION_RUNNING_WITH_UP_TO_DATE_INCOMPLETE_TASKS_STREAMING_RESULT = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_RUNNING, - result=MOCK_LIVEACTION_UP_TO_DATE_INCOMPLETE_TASKS_RESULT -) - -MOCK_LIVEACTION_CANCELING = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_CANCELING -) - -MOCK_ACTIONEXECUTION_CANCELING_CHILD_RUNNING = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_CANCELING.id}, - status=action_constants.LIVEACTION_STATUS_CANCELING, - children=[MOCK_CHILD_ACTIONEXECUTION_RUNNING.id] -) - -MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_CANCELING.id}, - status=action_constants.LIVEACTION_STATUS_CANCELING, - children=[MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED.id] -) - -MOCK_ACTIONEXECUTION_CANCELING_CHILD_PAUSED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_CANCELING.id}, - status=action_constants.LIVEACTION_STATUS_CANCELING, - children=[MOCK_CHILD_ACTIONEXECUTION_PAUSED.id] -) - -MOCK_LIVEACTION_PAUSING = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_PAUSING -) - -MOCK_ACTIONEXECUTION_PAUSING = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_PAUSING.id}, - status=action_constants.LIVEACTION_STATUS_PAUSING, - children=[] -) - -MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_PAUSING.id}, - status=action_constants.LIVEACTION_STATUS_PAUSING, - children=[MOCK_CHILD_ACTIONEXECUTION_RUNNING.id] -) - -MOCK_ACTIONEXECUTION_PAUSING_CHILD_PAUSED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_PAUSING.id}, - status=action_constants.LIVEACTION_STATUS_PAUSING, - children=[MOCK_CHILD_ACTIONEXECUTION_PAUSED.id] -) - -MOCK_LIVEACTION_RESUMING = LiveActionDB( - action='mock.workflow', - status=action_constants.LIVEACTION_STATUS_RESUMING -) - -MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_RESUMING.id}, - status=action_constants.LIVEACTION_STATUS_RESUMING, - children=[MOCK_CHILD_ACTIONEXECUTION_RUNNING.id] -) - -MOCK_ACTIONEXECUTION_RESUMING_CHILD_SUCCEEDED = ActionExecutionDB( - action={'ref': 'mock.workflow'}, - runner={'name': 'mistral_v2'}, - liveaction={'id': MOCK_LIVEACTION_RESUMING.id}, - status=action_constants.LIVEACTION_STATUS_RESUMING, - children=[MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED.id] -) - - -class MistralQuerierTest(DbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralQuerierTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in DbTestCase.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - - # Register query module. - cls.query_module = get_query_module('mistral-v2') - - def setUp(self): - super(MistralQuerierTest, self).setUp() - self.querier = self.query_module.get_instance() - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_running_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'RUNNING', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_running_exec_running_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'RUNNING', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_running_exec_succeeded_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'SUCCESS', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_succeeded_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'SUCCESS', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_succeeded_tasks_completed_child_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'SUCCESS', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_running_exec_failed_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'ERROR', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_failed_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'ERROR', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_canceling_exec_canceled_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'CANCELLED', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_canceling_exec_canceled_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'CANCELLED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_canceling_exec_canceled_tasks_waiting(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'CANCELLED', - MOCK_WF_TASKS_WAITING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_PAUSED, - MOCK_CHILD_ACTIONEXECUTION_PAUSED])) - def test_determine_status_wf_canceling_exec_canceled_tasks_paused(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'CANCELLED', - MOCK_WF_TASKS_PAUSED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_canceling_exec_running_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'RUNNING', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_canceling_exec_running_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'RUNNING', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_CANCELING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_canceling_exec_running_tasks_waiting(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_CANCELING, - 'RUNNING', - MOCK_WF_TASKS_WAITING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_cancelled_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'CANCELLED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_PAUSING_CHILD_PAUSED, - MOCK_CHILD_ACTIONEXECUTION_PAUSED])) - def test_determine_status_wf_pausing_exec_paused_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_PAUSING, - 'PAUSED', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_pausing_exec_paused_tasks_completed_child_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_PAUSING, - 'PAUSED', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_pausing_exec_paused_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_PAUSING, - 'PAUSED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_PAUSING_CHILD_PAUSED, - MOCK_CHILD_ACTIONEXECUTION_PAUSED])) - def test_determine_status_wf_pausing_exec_paused_tasks_paused(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_PAUSING, - 'PAUSED', - MOCK_WF_TASKS_PAUSED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_PAUSING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_pausing_exec_running_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_PAUSING, - 'RUNNING', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_running_exec_paused_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'PAUSED', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSED, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_running_exec_paused_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RUNNING, - 'PAUSED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RESUMING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_resuming_exec_paused_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RESUMING, - 'PAUSED', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RESUMING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RESUMING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_determine_status_wf_resuming_exec_running_tasks_completed(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RESUMING, - 'RUNNING', - MOCK_WF_TASKS_SUCCEEDED - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_resuming_exec_running_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RESUMING, - 'RUNNING', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_resuming_exec_paused_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RESUMING, - 'PAUSED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_PAUSING, status) - - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RESUMING_CHILD_RUNNING, - MOCK_CHILD_ACTIONEXECUTION_RUNNING])) - def test_determine_status_wf_resuming_exec_canceled_tasks_running(self): - status = self.querier._determine_execution_status( - MOCK_LIVEACTION_RESUMING, - 'CANCELLED', - MOCK_WF_TASKS_RUNNING - ) - - self.assertEqual(action_constants.LIVEACTION_STATUS_CANCELING, status) - - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - def test_get_workflow_result(self): - result = self.querier._get_workflow_result(uuid.uuid4().hex, uuid.uuid4().hex) - - expected = { - 'k1': 'v1', - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - self.assertDictEqual(expected, result) - - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - def test_get_workflow_tasks(self): - tasks = self.querier._get_workflow_tasks(uuid.uuid4().hex, uuid.uuid4().hex) - - expected = copy.deepcopy(MOCK_WF_EX_TASKS_DATA) - for task in expected: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - for i in range(0, len(tasks)): - self.assertDictEqual(expected[i], tasks[i]) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING_WITH_STREAMING_RESULT)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=[MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS[1])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_with_last_query_time(self): - last_query_time = time.time() - 3 - - (status, result) = self.querier.query( - uuid.uuid4().hex, - MOCK_QRY_CONTEXT, - last_query_time=last_query_time - ) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(side_effect=db_exc.StackStormDBObjectNotFoundError())) - def test_query_liveaction_not_found(self): - self.assertRaises( - db_exc.StackStormDBObjectNotFoundError, - self.querier.query, - uuid.uuid4().hex, - MOCK_QRY_CONTEXT - ) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(side_effect=[ - requests.exceptions.ConnectionError(), - MOCK_WF_EX])) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_get_workflow_retry(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) - - calls = [call(MOCK_QRY_CONTEXT['mistral']['execution_id']) for i in range(0, 2)] - executions.ExecutionManager.get.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4)) - def test_query_get_workflow_retry_exhausted(self): - self.assertRaises( - requests.exceptions.ConnectionError, - self.querier.query, - uuid.uuid4().hex, - MOCK_QRY_CONTEXT) - - calls = [call(MOCK_QRY_CONTEXT['mistral']['execution_id']) for i in range(0, 2)] - executions.ExecutionManager.get.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock( - side_effect=mistralclient_base.APIException( - error_code=404, error_message='Workflow not found.'))) - def test_query_get_workflow_not_found(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) - self.assertEqual('Workflow not found.', result) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(side_effect=[ - requests.exceptions.ConnectionError(), - MOCK_WF_EX_TASKS])) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_list_workflow_tasks_retry(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) - - mock_call = call(workflow_execution_id=MOCK_QRY_CONTEXT['mistral']['execution_id']) - calls = [mock_call for i in range(0, 2)] - tasks.TaskManager.list.assert_has_calls(calls) - - calls = [call(MOCK_WF_EX_TASKS[0].id), call(MOCK_WF_EX_TASKS[1].id)] - tasks.TaskManager.get.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - requests.exceptions.ConnectionError(), - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_get_workflow_tasks_retry(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) - - calls = [ - call(MOCK_WF_EX_TASKS[0].id), - call(MOCK_WF_EX_TASKS[0].id), - call(MOCK_WF_EX_TASKS[1].id) - ] - - tasks.TaskManager.get.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4)) - def test_query_list_workflow_tasks_retry_exhausted(self): - self.assertRaises( - requests.exceptions.ConnectionError, - self.querier.query, - uuid.uuid4().hex, - MOCK_QRY_CONTEXT) - - mock_call = call(workflow_execution_id=MOCK_QRY_CONTEXT['mistral']['execution_id']) - calls = [mock_call for i in range(0, 2)] - tasks.TaskManager.list.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[requests.exceptions.ConnectionError()] * 4)) - def test_query_get_workflow_tasks_retry_exhausted(self): - self.assertRaises( - requests.exceptions.ConnectionError, - self.querier.query, - uuid.uuid4().hex, - MOCK_QRY_CONTEXT) - - calls = [ - call(MOCK_WF_EX_TASKS[0].id), - call(MOCK_WF_EX_TASKS[0].id) - ] - - tasks.TaskManager.get.assert_has_calls(calls) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock( - side_effect=mistralclient_base.APIException( - error_code=404, error_message='Task not found.'))) - def test_query_get_workflow_tasks_not_found(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - self.assertEqual(action_constants.LIVEACTION_STATUS_FAILED, status) - self.assertEqual('Task not found.', result) - - def test_query_missing_context(self): - self.assertRaises(Exception, self.querier.query, uuid.uuid4().hex, {}) - - def test_query_missing_mistral_execution_id(self): - self.assertRaises(Exception, self.querier.query, uuid.uuid4().hex, {'mistral': {}}) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock( - return_value=MOCK_LIVEACTION_RUNNING_WITH_OUTDATED_INCOMPLETE_TASKS_STREAMING_RESULT)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=MOCK_WF_EX_INCOMPLETE_TASKS)) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_with_outdated_tasks_in_liveaction_result(self): - last_query_time = time.time() + 3 - - (status, result) = self.querier.query( - uuid.uuid4().hex, - MOCK_QRY_CONTEXT, - last_query_time=last_query_time - ) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_INCOMPLETE_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - self.assertDictEqual(expected, result) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock( - return_value=MOCK_LIVEACTION_RUNNING_WITH_UP_TO_DATE_INCOMPLETE_TASKS_STREAMING_RESULT)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX_INCOMPLETE_TASKS[1])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_SUCCEEDED, - MOCK_CHILD_ACTIONEXECUTION_SUCCEEDED])) - def test_query_with_up_to_date_tasks_in_liveaction_result(self): - last_query_time = time.time() + 3 - - (status, result) = self.querier.query( - uuid.uuid4().hex, - MOCK_QRY_CONTEXT, - last_query_time=last_query_time - ) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_INCOMPLETE_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_RUNNING, status) - self.assertDictEqual(expected, result) - - @mock.patch.object( - action_utils, 'get_liveaction_by_id', - mock.MagicMock(return_value=MOCK_LIVEACTION_RUNNING)) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=MOCK_WF_EX)) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=MOCK_WF_EX_TASKS)) - @mock.patch.object( - tasks.TaskManager, 'get', - mock.MagicMock(side_effect=[ - MOCK_WF_EX_TASKS[0], - MOCK_WF_EX_TASKS[1]])) - @mock.patch.object( - ActionExecution, 'get', - mock.MagicMock(side_effect=[ - MOCK_ACTIONEXECUTION_RUNNING_CHILD_REQUESTED, - MOCK_CHILD_ACTIONEXECUTION_REQUESTED])) - def test_orphaned_execution_child_in_requested_state(self): - (status, result) = self.querier.query(uuid.uuid4().hex, MOCK_QRY_CONTEXT) - - expected = { - 'k1': 'v1', - 'tasks': copy.deepcopy(MOCK_WF_EX_TASKS_DATA), - 'extra': { - 'state': MOCK_WF_EX.state, - 'state_info': MOCK_WF_EX.state_info - } - } - - for task in expected['tasks']: - task['input'] = json.loads(task['input']) - task['result'] = json.loads(task['result']) - task['published'] = json.loads(task['published']) - - self.assertEqual(action_constants.LIVEACTION_STATUS_SUCCEEDED, status) - self.assertDictEqual(expected, result) diff --git a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_rerun.py b/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_rerun.py deleted file mode 100644 index 128eff08de..0000000000 --- a/contrib/runners/mistral_v2/tests/unit/test_mistral_v2_rerun.py +++ /dev/null @@ -1,596 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -import copy -import uuid - -import mock -import yaml - -from mistralclient.api.v2 import executions -from mistralclient.api.v2 import tasks -from mistralclient.api.v2 import workbooks -from mistralclient.api.v2 import workflows -from oslo_config import cfg - -# XXX: actionsensor import depends on config being setup. -import st2tests.config as tests_config -tests_config.parse_args() - -from mistral_v2.mistral_v2 import MistralRunner -from st2common.bootstrap import actionsregistrar -from st2common.bootstrap import runnersregistrar -from st2common.constants import action as action_constants -from st2common.models.db.liveaction import LiveActionDB -from st2common.runners import base as runners -from st2common.services import action as action_service -from st2common.transport.liveaction import LiveActionPublisher -from st2common.transport.publishers import CUDPublisher -from st2common.util import loader -from st2tests import ExecutionDbTestCase -from st2tests import fixturesloader -from st2tests.mocks.liveaction import MockLiveActionPublisher - - -TEST_FIXTURES = { - 'workflows': [ - 'workflow_v2.yaml', - 'workbook_v2_many_workflows.yaml' - ], - 'actions': [ - 'workflow_v2.yaml', - 'workbook_v2_many_workflows.yaml' - ] -} - -TEST_PACK = 'mistral_tests' -TEST_PACK_PATH = fixturesloader.get_fixtures_packs_base_path() + '/' + TEST_PACK - -PACKS = [ - TEST_PACK_PATH, - fixturesloader.get_fixtures_packs_base_path() + '/core' -] - -# Action executions requirements -ACTION_PARAMS = {'friend': 'Rocky'} -NON_EMPTY_RESULT = 'non-empty' - -# Workbook with multiple workflows -WB1_META_FILE_NAME = TEST_FIXTURES['workflows'][1] -WB1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WB1_META_FILE_NAME -WB1_META_CONTENT = loader.load_meta_file(WB1_META_FILE_PATH) -WB1_NAME = WB1_META_CONTENT['pack'] + '.' + WB1_META_CONTENT['name'] -WB1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WB1_META_CONTENT['entry_point'] -WB1_ENTRY_POINT_X = WB1_ENTRY_POINT.replace(WB1_META_FILE_NAME, 'xformed_' + WB1_META_FILE_NAME) -WB1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WB1_ENTRY_POINT_X)) -WB1_YAML = yaml.safe_dump(WB1_SPEC, default_flow_style=False) -WB1 = workbooks.Workbook(None, {'name': WB1_NAME, 'definition': WB1_YAML}) -WB1_MAIN_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING'} -WB1_MAIN_EXEC['workflow_name'] = WB1_NAME + '.main' -WB1_MAIN_EXEC_ERRORED = copy.deepcopy(WB1_MAIN_EXEC) -WB1_MAIN_EXEC_ERRORED['state'] = 'ERROR' -WB1_MAIN_TASK1 = {'id': str(uuid.uuid4()), 'name': 'greet', 'state': 'ERROR'} -WB1_MAIN_TASKS = [tasks.Task(None, WB1_MAIN_TASK1)] -WB1_MAIN_TASK_ID = WB1_MAIN_TASK1['id'] -WB1_SUB1_EXEC = {'id': str(uuid.uuid4()), 'state': 'RUNNING', 'task_execution_id': WB1_MAIN_TASK_ID} -WB1_SUB1_EXEC['workflow_name'] = WB1_NAME + '.subflow1' -WB1_SUB1_EXEC_ERRORED = copy.deepcopy(WB1_SUB1_EXEC) -WB1_SUB1_EXEC_ERRORED['state'] = 'ERROR' -WB1_SUB1_TASK1 = {'id': str(uuid.uuid4()), 'name': 'say-greeting', 'state': 'SUCCESS'} -WB1_SUB1_TASK2 = {'id': str(uuid.uuid4()), 'name': 'say-friend', 'state': 'ERROR'} -WB1_SUB1_TASKS = [tasks.Task(None, WB1_SUB1_TASK1), tasks.Task(None, WB1_SUB1_TASK2)] - -# Non-workbook with a single workflow -WF1_META_FILE_NAME = TEST_FIXTURES['workflows'][0] -WF1_META_FILE_PATH = TEST_PACK_PATH + '/actions/' + WF1_META_FILE_NAME -WF1_META_CONTENT = loader.load_meta_file(WF1_META_FILE_PATH) -WF1_NAME = WF1_META_CONTENT['pack'] + '.' + WF1_META_CONTENT['name'] -WF1_ENTRY_POINT = TEST_PACK_PATH + '/actions/' + WF1_META_CONTENT['entry_point'] -WF1_ENTRY_POINT_X = WF1_ENTRY_POINT.replace(WF1_META_FILE_NAME, 'xformed_' + WF1_META_FILE_NAME) -WF1_SPEC = yaml.safe_load(MistralRunner.get_workflow_definition(WF1_ENTRY_POINT_X)) -WF1_YAML = yaml.safe_dump(WF1_SPEC, default_flow_style=False) -WF1 = workflows.Workflow(None, {'name': WF1_NAME, 'definition': WF1_YAML}) -WF1_EXEC = {'id': str(uuid.uuid4()), 'state': 'ERROR', 'workflow_name': WF1_NAME} -WF1_EXEC_NOT_RERUNABLE = copy.deepcopy(WF1_EXEC) -WF1_EXEC_NOT_RERUNABLE['state'] = 'PAUSED' -WF1_TASK1 = {'id': str(uuid.uuid4()), 'name': 'say-greeting', 'state': 'SUCCESS'} -WF1_TASK2 = {'id': str(uuid.uuid4()), 'name': 'say-friend', 'state': 'SUCCESS'} -WF1_TASKS = [tasks.Task(None, WF1_TASK1), tasks.Task(None, WF1_TASK2)] - - -@mock.patch.object( - CUDPublisher, - 'publish_update', - mock.MagicMock(return_value=None)) -@mock.patch.object( - CUDPublisher, - 'publish_create', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_create)) -@mock.patch.object( - LiveActionPublisher, - 'publish_state', - mock.MagicMock(side_effect=MockLiveActionPublisher.publish_state)) -class MistralRunnerTest(ExecutionDbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralRunnerTest, cls).setUpClass() - - # Override the retry configuration here otherwise st2tests.config.parse_args - # in ExecutionDbTestCase.setUpClass will reset these overrides. - cfg.CONF.set_override('retry_exp_msec', 100, group='mistral') - cfg.CONF.set_override('retry_exp_max_msec', 200, group='mistral') - cfg.CONF.set_override('retry_stop_max_msec', 200, group='mistral') - cfg.CONF.set_override('api_url', 'http://0.0.0.0:9101', group='auth') - - # Register runners. - runnersregistrar.register_runners() - - # Register test pack(s). - actions_registrar = actionsregistrar.ActionsRegistrar( - use_pack_cache=False, - fail_on_failure=True - ) - - for pack in PACKS: - actions_registrar.register_from_pack(pack) - - def setUp(self): - super(MistralRunnerTest, self).setUp() - - # Mock the local runner run method. - local_runner_cls = runners.get_runner('local-shell-cmd').__class__ - local_run_result = (action_constants.LIVEACTION_STATUS_SUCCEEDED, NON_EMPTY_RESULT, None) - local_runner_cls.run = mock.Mock(return_value=local_run_result) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_resume_option(self): - patched_mistral_runner = runners.get_runner('mistral-v2').__class__ - - mock_resume_result = ( - action_constants.LIVEACTION_STATUS_RUNNING, - {'tasks': []}, - {'execution_id': str(uuid.uuid4())} - ) - - with mock.patch.object(patched_mistral_runner, 'resume_workflow', - mock.MagicMock(return_value=mock_resume_result)): - - liveaction1 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - self.assertFalse(patched_mistral_runner.resume_workflow.called) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['x'] - } - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - - liveaction2 = self._wait_on_status( - liveaction2, - action_constants.LIVEACTION_STATUS_RUNNING - ) - - task_specs = { - 'x': { - 'reset': False - } - } - - patched_mistral_runner.resume_workflow.assert_called_with( - ex_ref=execution1, - task_specs=task_specs - ) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - def test_resume_option_reset_tasks(self): - patched_mistral_runner = runners.get_runner('mistral-v2').__class__ - - mock_resume_result = ( - action_constants.LIVEACTION_STATUS_RUNNING, - {'tasks': []}, - {'execution_id': str(uuid.uuid4())} - ) - - with mock.patch.object(patched_mistral_runner, 'resume_workflow', - mock.MagicMock(return_value=mock_resume_result)): - - liveaction1 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - self.assertFalse(patched_mistral_runner.resume_workflow.called) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['x', 'y'], - 'reset': ['y'] - } - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - - liveaction2 = self._wait_on_status( - liveaction2, - action_constants.LIVEACTION_STATUS_RUNNING - ) - - task_specs = { - 'x': { - 'reset': False - }, - 'y': { - 'reset': True - } - } - - patched_mistral_runner.resume_workflow.assert_called_with( - ex_ref=execution1, - task_specs=task_specs - ) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC_NOT_RERUNABLE))) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC_NOT_RERUNABLE))) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=WF1_TASKS)) - def test_resume_workflow_not_in_rerunable_state(self): - liveaction1 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['say-friend'] - } - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('not in a rerunable state', liveaction2.result.get('error')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'list', - mock.MagicMock(return_value=[executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=WF1_TASKS)) - def test_resume_tasks_not_in_rerunable_state(self): - liveaction1 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['say-friend'] - } - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Unable to identify rerunable', liveaction2.result.get('error')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workflows.WorkflowManager, 'create', - mock.MagicMock(return_value=[WF1])) - @mock.patch.object( - executions.ExecutionManager, 'list', - mock.MagicMock(return_value=[executions.Execution(None, WF1_EXEC)])) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WF1_EXEC))) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(return_value=WF1_TASKS)) - def test_resume_unidentified_tasks(self): - liveaction1 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['x'] - } - } - - liveaction2 = LiveActionDB(action=WF1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Unable to identify', liveaction2.result.get('error')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WB1_MAIN_EXEC), - executions.Execution(None, WB1_SUB1_EXEC) - ])) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC_ERRORED))) - @mock.patch.object( - executions.ExecutionManager, 'list', - mock.MagicMock(side_effect=[ - [ - executions.Execution(None, WB1_MAIN_EXEC_ERRORED), - executions.Execution(None, WB1_SUB1_EXEC_ERRORED) - ], - [ - executions.Execution(None, WB1_SUB1_EXEC_ERRORED) - ] - ])) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(side_effect=[ - WB1_MAIN_TASKS, # First call of _get_tasks at mistral_v2 runner - WB1_SUB1_TASKS, # Recursive call of the first _get_tasks - WB1_MAIN_TASKS, # tasks.list in _update_workflow_env at mistral_v2 runner - [] # Resursive call of _update_workflow_env - ])) - @mock.patch.object( - tasks.TaskManager, 'rerun', - mock.MagicMock(return_value=None)) - def test_resume_subworkflow_task(self): - liveaction1 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['greet.say-friend'] - } - } - - liveaction2 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_RUNNING) - - expected_env = { - 'st2_liveaction_id': str(liveaction2.id), - 'st2_execution_id': str(execution2.id), - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'notify': {}, - 'parent': { - 'pack': 'mistral_tests', - 're-run': context['re-run'], - 'execution_id': str(execution2.id) - }, - 'skip_notify_tasks': [] - } - } - }, - 'st2_action_api_url': 'http://0.0.0.0:9101/v1' - } - - tasks.TaskManager.rerun.assert_called_with( - WB1_SUB1_TASK2['id'], - reset=False, - env=expected_env - ) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC_ERRORED))) - @mock.patch.object( - executions.ExecutionManager, 'list', - mock.MagicMock( - return_value=[ - executions.Execution(None, WB1_MAIN_EXEC_ERRORED), - executions.Execution(None, WB1_SUB1_EXEC_ERRORED)])) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(side_effect=[WB1_MAIN_TASKS, WB1_SUB1_TASKS])) - def test_resume_unidentified_subworkflow_task(self): - liveaction1 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['greet.x'] - } - } - - liveaction2 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Unable to identify', liveaction2.result.get('error')) - - @mock.patch.object( - workflows.WorkflowManager, 'list', - mock.MagicMock(return_value=[])) - @mock.patch.object( - workflows.WorkflowManager, 'get', - mock.MagicMock(return_value=WF1)) - @mock.patch.object( - workbooks.WorkbookManager, 'create', - mock.MagicMock(return_value=WB1)) - @mock.patch.object( - executions.ExecutionManager, 'create', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC))) - @mock.patch.object( - executions.ExecutionManager, 'update', - mock.MagicMock(side_effect=[ - executions.Execution(None, WB1_MAIN_EXEC), - executions.Execution(None, WB1_SUB1_EXEC) - ])) - @mock.patch.object( - executions.ExecutionManager, 'get', - mock.MagicMock(return_value=executions.Execution(None, WB1_MAIN_EXEC_ERRORED))) - @mock.patch.object( - executions.ExecutionManager, 'list', - mock.MagicMock(side_effect=[ - [ - executions.Execution(None, WB1_MAIN_EXEC_ERRORED), - executions.Execution(None, WB1_SUB1_EXEC_ERRORED) - ], - [ - executions.Execution(None, WB1_SUB1_EXEC_ERRORED) - ] - ])) - @mock.patch.object( - tasks.TaskManager, 'list', - mock.MagicMock(side_effect=[ - WB1_MAIN_TASKS, # First call of _get_tasks at mistral_v2 runner - WB1_SUB1_TASKS, # Recursive call of the first _get_tasks - WB1_MAIN_TASKS, # tasks.list in _update_workflow_env at mistral_v2 runner - [] # Resursive call of _update_workflow_env - ])) - @mock.patch.object( - tasks.TaskManager, 'rerun', - mock.MagicMock(return_value=None)) - def test_resume_and_reset_subworkflow_task(self): - liveaction1 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS) - liveaction1, execution1 = action_service.request(liveaction1) - - # Rerun the execution. - context = { - 're-run': { - 'ref': execution1.id, - 'tasks': ['greet.say-friend'], - 'reset': ['greet.say-friend'] - } - } - - liveaction2 = LiveActionDB(action=WB1_NAME, parameters=ACTION_PARAMS, context=context) - liveaction2, execution2 = action_service.request(liveaction2) - liveaction2 = self._wait_on_status(liveaction2, action_constants.LIVEACTION_STATUS_RUNNING) - - expected_env = { - 'st2_liveaction_id': str(liveaction2.id), - 'st2_execution_id': str(execution2.id), - '__actions': { - 'st2.action': { - 'st2_context': { - 'api_url': 'http://0.0.0.0:9101/v1', - 'endpoint': 'http://0.0.0.0:9101/v1/actionexecutions', - 'notify': {}, - 'parent': { - 'pack': 'mistral_tests', - 're-run': context['re-run'], - 'execution_id': str(execution2.id) - }, - 'skip_notify_tasks': [] - } - } - }, - 'st2_action_api_url': 'http://0.0.0.0:9101/v1' - } - - tasks.TaskManager.rerun.assert_called_with( - WB1_SUB1_TASK2['id'], - reset=True, - env=expected_env - ) diff --git a/scripts/travis/build.sh b/scripts/travis/build.sh index 81a3e8fdf9..4a4d1aa1d4 100755 --- a/scripts/travis/build.sh +++ b/scripts/travis/build.sh @@ -22,8 +22,6 @@ elif [ ${TASK} == 'unit' ]; then make .unit-tests-coverage-html elif [ ${TASK} == 'integration' ]; then make .itests-coverage-html -elif [ ${TASK} == 'mistral' ]; then - make .mistral-itests-coverage-html elif [ ${TASK} == "packs-tests" ]; then make .packs-tests else diff --git a/scripts/travis/setup-mistral.sh b/scripts/travis/setup-mistral.sh deleted file mode 100755 index 70686553e8..0000000000 --- a/scripts/travis/setup-mistral.sh +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env bash -set -e - -if [ "$(whoami)" != 'root' ]; then - echo 'Please run with sudo' - exit 2 -fi - -function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -V | tail -n 1)" == "$1"; } - -# Determine which mistral version to use -if [[ "${TRAVIS_BRANCH}" == 'master' ]]; then - MISTRAL_STABLE_BRANCH='master' -elif [[ "${TRAVIS_BRANCH}" =~ ^v[0-9] ]]; then - # remove 'v' prefix from version - VER=`echo ${TRAVIS_BRANCH} | cut -c2-` - if version_ge $VER "0.13"; then - MISTRAL_STABLE_BRANCH="st2-0.13.0" - elif version_ge $VER "0.9"; then - MISTRAL_STABLE_BRANCH="st2-0.9.0" - elif version_ge $VER "0.8.1"; then - MISTRAL_STABLE_BRANCH="st2-0.8.1" - elif version_ge $VER "0.8"; then - MISTRAL_STABLE_BRANCH="st2-0.8.0" - else - MISTRAL_STABLE_BRANCH="st2-0.5.1" - fi -else - MISTRAL_STABLE_BRANCH="st2-0.13.0" -fi - -STANCONF="${PWD}/conf/st2.dev.conf" -TYPE="debs" - - -echo "TRAVIS_BRANCH=${TRAVIS_BRANCH}" -echo "Installing Mistral version ${MISTRAL_STABLE_BRANCH}" - -############################################################## -# Copy-pasted from st2_deploy.sh -############################################################## - -setup_mistral_st2_config() -{ - echo "" >> ${STANCONF} - echo "[mistral]" >> ${STANCONF} - echo "v2_base_url = http://127.0.0.1:8989/v2" >> ${STANCONF} -} - -setup_postgresql() { - # Setup the postgresql service on fedora. Ubuntu is already setup by default. - if [[ "$TYPE" == "rpms" ]]; then - echo "Configuring PostgreSQL for Fedora..." - systemctl enable postgresql - sudo postgresql-setup initdb - pg_hba_config=/var/lib/pgsql/data/pg_hba.conf - sed -i 's/^local\s\+all\s\+all\s\+peer/local all all trust/g' ${pg_hba_config} - sed -i 's/^local\s\+all\s\+all\s\+ident/local all all trust/g' ${pg_hba_config} - sed -i 's/^host\s\+all\s\+all\s\+127.0.0.1\/32\s\+ident/host all all 127.0.0.1\/32 md5/g' ${pg_hba_config} - sed -i 's/^host\s\+all\s\+all\s\+::1\/128\s\+ident/host all all ::1\/128 md5/g' ${pg_hba_config} - systemctl start postgresql - fi - - echo "Changing max connections for PostgreSQL..." - config=`sudo -u postgres psql -c "SHOW config_file;" | grep postgresql.conf` - sed -i 's/max_connections = 100/max_connections = 500/' ${config} - service postgresql restart -} - -setup_mistral_config() -{ -config=/etc/mistral/mistral.conf -echo "Writing Mistral configuration file to $config..." -if [ -e "$config" ]; then - rm $config -fi -touch $config -cat <$config -[database] -connection=postgresql://mistral:StackStorm@127.0.0.1/mistral -max_pool_size=50 - -[pecan] -auth_enable=false -mistral_config -} - -setup_mistral_log_config() -{ -log_config=/etc/mistral/wf_trace_logging.conf -echo "Writing Mistral log configuration file to $log_config..." -if [ -e "$log_config" ]; then - rm $log_config -fi -cp /opt/openstack/mistral/etc/wf_trace_logging.conf.sample $log_config -sed -i "s~tmp~var/log~g" $log_config -} - -setup_mistral_db() -{ - echo "Setting up Mistral DB in PostgreSQL..." - sudo -u postgres psql -c "DROP DATABASE IF EXISTS mistral;" - sudo -u postgres psql -c "DROP USER IF EXISTS mistral;" - sudo -u postgres psql -c "CREATE USER mistral WITH ENCRYPTED PASSWORD 'StackStorm';" - sudo -u postgres psql -c "CREATE DATABASE mistral OWNER mistral;" - - echo "Creating and populating DB tables for Mistral..." - config=/etc/mistral/mistral.conf - cd /opt/openstack/mistral - /opt/openstack/mistral/.venv/bin/python ./tools/sync_db.py --config-file ${config} -} - -setup_mistral_upstart() -{ -echo "Setting up upstart for Mistral..." -upstart=/etc/init/mistral.conf -if [ -e "$upstart" ]; then - rm $upstart -fi -touch $upstart -cat <$upstart -description "Mistral Workflow Service" - -start on runlevel [2345] -stop on runlevel [016] -respawn - -exec /opt/openstack/mistral/.venv/bin/python /opt/openstack/mistral/mistral/cmd/launch.py --config-file /etc/mistral/mistral.conf --log-config-append /etc/mistral/wf_trace_logging.conf -mistral_upstart -} - -setup_mistral() { - echo "###########################################################################################" - echo "# Setting up Mistral" - - # Clone mistral from github. - mkdir -p /opt/openstack - cd /opt/openstack - if [ -d "/opt/openstack/mistral" ]; then - rm -r /opt/openstack/mistral - fi - echo "Cloning Mistral branch: ${MISTRAL_STABLE_BRANCH}..." - git clone -b ${MISTRAL_STABLE_BRANCH} https://github.com/StackStorm/mistral.git - - # Setup virtualenv for running mistral. - cd /opt/openstack/mistral - virtualenv .venv - . /opt/openstack/mistral/.venv/bin/activate - pip install -q -r requirements.txt - pip install -q psycopg2 - python setup.py install - - # Setup plugins for actions. - mkdir -p /etc/mistral/actions - if [ -d "/etc/mistral/actions/st2mistral" ]; then - rm -r /etc/mistral/actions/st2mistral - fi - echo "Cloning St2mistral branch: ${MISTRAL_STABLE_BRANCH}..." - cd /etc/mistral/actions - git clone -b ${MISTRAL_STABLE_BRANCH} https://github.com/StackStorm/st2mistral.git - cd /etc/mistral/actions/st2mistral - python setup.py install - - # Create configuration files. - mkdir -p /etc/mistral - setup_mistral_config - setup_mistral_log_config - setup_mistral_st2_config - - # Setup database. - setup_postgresql - setup_mistral_db - - # Setup service. - if [[ "$TYPE" == "debs" ]]; then - setup_mistral_upstart - elif [[ "$TYPE" == "rpms" ]]; then - setup_mistral_systemd - fi - - # Deactivate venv. - deactivate - - # Setup mistral client. - pip install -q -U git+https://github.com/StackStorm/python-mistralclient.git@${MISTRAL_STABLE_BRANCH} -} - -setup_mistral - -start mistral - -echo 'Done!' diff --git a/st2api/tests/unit/controllers/exp/test_validator_mistral.py b/st2api/tests/unit/controllers/exp/test_validator_mistral.py deleted file mode 100644 index 5a1c15b63c..0000000000 --- a/st2api/tests/unit/controllers/exp/test_validator_mistral.py +++ /dev/null @@ -1,306 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from mistralclient.api.v2 import workbooks -from mistralclient.api.v2 import workflows -import mock -import six -import yaml - -from st2common.models.api.action import ActionAPI, RunnerTypeAPI -from st2common.persistence.action import Action -from st2common.persistence.runner import RunnerType -from st2tests.fixturesloader import FixturesLoader -from st2tests.api import FunctionalTest - - -WB_PRE_XFORM_FILE = 'wb_pre_xform.yaml' -WB_POST_XFORM_FILE = 'wb_post_xform.yaml' -WB_INVALID_SYNTAX_FILE = 'wb_invalid_syntax.yaml' -WB_INVALID_YAQL_FILE = 'wb_invalid_yaql.yaml' -WF_PRE_XFORM_FILE = 'wf_pre_xform.yaml' -WF_POST_XFORM_FILE = 'wf_post_xform.yaml' -WF_NO_REQ_PARAM_FILE = 'wf_missing_required_param.yaml' -WF_UNEXP_PARAM_FILE = 'wf_has_unexpected_param.yaml' -WF_INVALID_SYNTAX_FILE = 'wf_invalid_syntax.yaml' -WF_INVALID_YAQL_FILE = 'wf_invalid_yaql.yaml' - -TEST_FIXTURES = { - 'workflows': [ - WB_PRE_XFORM_FILE, - WB_POST_XFORM_FILE, - WB_INVALID_SYNTAX_FILE, - WB_INVALID_YAQL_FILE, - WF_PRE_XFORM_FILE, - WF_POST_XFORM_FILE, - WF_NO_REQ_PARAM_FILE, - WF_UNEXP_PARAM_FILE, - WF_INVALID_SYNTAX_FILE, - WF_INVALID_YAQL_FILE - ], - 'actions': [ - 'a1.yaml', - 'a2.yaml', - 'action1.yaml' - ], - 'runners': [ - 'testrunner1.yaml', - 'testrunner2.yaml' - ] -} - -PACK = 'generic' -LOADER = FixturesLoader() -FIXTURES = LOADER.load_fixtures(fixtures_pack=PACK, fixtures_dict=TEST_FIXTURES) -WB_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_PRE_XFORM_FILE) -WB_INVALID_SYNTAX_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_INVALID_SYNTAX_FILE) -WB_INVALID_YAQL_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_INVALID_YAQL_FILE) -WF_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_PRE_XFORM_FILE) -WF_NO_REQ_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_NO_REQ_PARAM_FILE) -WF_UNEXP_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_UNEXP_PARAM_FILE) -WF_INVALID_SYNTAX_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_INVALID_SYNTAX_FILE) -WF_INVALID_YAQL_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_INVALID_YAQL_FILE) - - -class MistralValidationControllerTest(FunctionalTest): - - @classmethod - def setUpClass(cls): - super(MistralValidationControllerTest, cls).setUpClass() - - for _, fixture in six.iteritems(FIXTURES['runners']): - instance = RunnerTypeAPI(**fixture) - RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) - - for _, fixture in six.iteritems(FIXTURES['actions']): - instance = ActionAPI(**fixture) - Action.add_or_update(ActionAPI.to_model(instance)) - - def _read_file_content(self, path): - with open(path, 'r') as f: - return f.read() - - def _read_yaml_file_as_json(self, path): - def_yaml = self._read_file_content(path) - return yaml.safe_load(def_yaml) - - def __do_post(self, definition, expect_errors=False): - return self.app.post('/exp/validation/mistral', definition, expect_errors=expect_errors, - content_type='text/plain') - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Invalid DSL: \'version\' is a required property\n'})) - def test_missing_version(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - del def_dict['version'] - def_yaml = yaml.safe_dump(def_dict) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': '', - 'message': '\'version\' is a required property' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Invalid DSL: Unsupported DSL version\n'})) - def test_unsupported_version(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - def_dict['version'] = '1.0' - def_yaml = yaml.safe_dump(def_dict) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': '', - 'message': 'Unsupported DSL version' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_required_action_params_failure(self): - def_yaml = self._read_file_content(WF_NO_REQ_PARAM_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': '', - 'message': 'Missing required parameters in "task1" ' - 'for action "wolfpack.action-1": "actionstr"' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_unexpected_action_params_failure(self): - def_yaml = self._read_file_content(WF_UNEXP_PARAM_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': '', - 'message': 'Unexpected parameters in "task1" ' - 'for action "wolfpack.action-1": "foo"' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_deprecated_callback_action(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - def_dict['workflows']['main']['tasks']['callback'] = {'action': 'st2.callback'} - def_yaml = yaml.safe_dump(def_dict) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': '', - 'message': 'st2.callback is deprecated.' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_workbook_valid(self): - def_yaml = self._read_file_content(WB_PRE_XFORM_PATH) - resp = self.__do_post(def_yaml) - self.assertEqual(200, resp.status_int) - self.assertListEqual([], resp.json) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': "Invalid DSL: foobar\n\nEpic fail\nOn instance['tasks']['task1']:\n"})) - def test_workbook_invalid_syntax(self): - def_yaml = self._read_file_content(WB_INVALID_SYNTAX_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': 'tasks.task1', - 'message': 'foobar' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Parse error: unexpected end of statement.'})) - def test_workbook_invalid_yaql(self): - def_yaml = self._read_file_content(WB_INVALID_YAQL_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'yaql', - 'path': '', - 'message': 'unexpected end of statement.' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_workflow_valid(self): - def_yaml = self._read_file_content(WF_PRE_XFORM_PATH) - resp = self.__do_post(def_yaml) - self.assertEqual(200, resp.status_int) - self.assertListEqual([], resp.json) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': "Invalid DSL: foobar\n\nEpic fail\nOn instance['tasks']['task1']:\n"})) - def test_workflow_invalid_syntax(self): - def_yaml = self._read_file_content(WF_INVALID_SYNTAX_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': 'tasks.task1', - 'message': 'foobar' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Parse error: unexpected end of statement.'})) - def test_workflow_invalid_yaql(self): - def_yaml = self._read_file_content(WF_INVALID_YAQL_PATH) - resp = self.__do_post(def_yaml) - - expected = [ - { - 'type': 'yaql', - 'path': '', - 'message': 'unexpected end of statement.' - } - ] - - self.assertEqual(200, resp.status_int) - self.assertListEqual(expected, resp.json) diff --git a/st2common/st2common/util/workflow/__init__.py b/st2common/st2common/util/workflow/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/st2common/st2common/util/workflow/mistral.py b/st2common/st2common/util/workflow/mistral.py deleted file mode 100644 index 1901ff5963..0000000000 --- a/st2common/st2common/util/workflow/mistral.py +++ /dev/null @@ -1,281 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import copy -import json -import re - -import requests -import six -import yaml - -try: - from mistralclient.api.base import APIException -except ImportError: - # Likely running on installation without Mistral - class APIException(Exception): - pass - -from st2common.exceptions.workflow import WorkflowDefinitionException -from st2common import log as logging -from st2common.models.system.common import ResourceReference -from st2common.models.utils import action_param_utils -from st2common.util import action_db as action_utils - - -LOG = logging.getLogger(__name__) - - -CMD_PTRN = re.compile(r"^[\w\.]+[^=\s\"]*") - -INLINE_YAQL = r'<%.*?%>' -_ALL_IN_BRACKETS = r"\[.*\]\s*" -_ALL_IN_QUOTES = r"\"[^\"]*\"\s*" -_ALL_IN_APOSTROPHES = r"'[^']*'\s*" -_DIGITS = r"\d+" -_TRUE = "true" -_FALSE = "false" -_NULL = "null" - -ALL = ( - _ALL_IN_QUOTES, _ALL_IN_APOSTROPHES, INLINE_YAQL, - _ALL_IN_BRACKETS, _TRUE, _FALSE, _NULL, _DIGITS -) - -PARAMS_PTRN = re.compile(r"([\w]+)=(%s)" % "|".join(ALL)) - -SPEC_TYPES = { - 'adhoc': { - 'action_key': 'base', - 'input_key': 'base-input' - }, - 'task': { - 'action_key': 'action', - 'input_key': 'input' - } -} - -JINJA_REGEX_WITH_ST2KV = r'{{st2kv\..*?|.*?\sst2kv\..*?}}' -JINJA_REGEX_WITH_ST2KV_PTRN = re.compile(JINJA_REGEX_WITH_ST2KV) -JINJA_REGEX_WITH_LOCAL_CTX = r'{{.*?_\..*?}}' -JINJA_REGEX_WITH_LOCAL_CTX_PTRN = re.compile(JINJA_REGEX_WITH_LOCAL_CTX) - - -def _parse_cmd_and_input(cmd_str): - cmd_matcher = CMD_PTRN.search(cmd_str) - - if not cmd_matcher: - raise ValueError("Invalid action/workflow task property: %s" % cmd_str) - - cmd = cmd_matcher.group() - - params = {} - for k, v in re.findall(PARAMS_PTRN, cmd_str): - # Remove embracing quotes. - v = v.strip() - if v[0] == '"' or v[0] == "'": - v = v[1:-1] - else: - try: - v = json.loads(v) - except Exception: - pass - - params[k] = v - - return cmd, params - - -def _merge_dicts(left, right): - if left is None: - return right - - if right is None: - return left - - for k, v in six.iteritems(right): - if k not in left: - left[k] = v - else: - left_v = left[k] - - if isinstance(left_v, dict) and isinstance(v, dict): - _merge_dicts(left_v, v) - - return left - - -def _eval_inline_params(spec, action_key, input_key): - action_str = spec.get(action_key) - command, inputs = _parse_cmd_and_input(action_str) - if inputs: - spec[action_key] = command - if input_key not in spec: - spec[input_key] = {} - _merge_dicts(spec[input_key], inputs) - - -def _validate_action_parameters(name, action, action_params): - requires, unexpected = action_param_utils.validate_action_parameters(action.ref, action_params) - - if requires: - raise WorkflowDefinitionException('Missing required parameters in "%s" for action "%s": ' - '"%s"' % (name, action.ref, '", "'.join(requires))) - - if unexpected: - raise WorkflowDefinitionException('Unexpected parameters in "%s" for action "%s": ' - '"%s"' % (name, action.ref, '", "'.join(unexpected))) - - -def _transform_action_param(action_ref, param_name, param_value): - if isinstance(param_value, list): - param_value = [ - _transform_action_param(action_ref, param_name, value) - for value in param_value - ] - - if isinstance(param_value, dict): - param_value = { - name: _transform_action_param(action_ref, name, value) - for name, value in six.iteritems(param_value) - } - - if isinstance(param_value, six.string_types): - st2kv_matches = JINJA_REGEX_WITH_ST2KV_PTRN.findall(param_value) - local_ctx_matches = JINJA_REGEX_WITH_LOCAL_CTX_PTRN.findall(param_value) - - if st2kv_matches and local_ctx_matches: - raise WorkflowDefinitionException('Parameter "%s" for action "%s" containing ' - 'references to both local context (i.e. _.var1) ' - 'and st2kv (i.e. st2kv.system.var1) is not ' - 'supported.' % (param_name, action_ref)) - - if st2kv_matches: - param_value = '{% raw %}' + param_value + '{% endraw %}' - - return param_value - - -def _transform_action(name, spec): - - action_key, input_key = None, None - - for spec_type, spec_meta in six.iteritems(SPEC_TYPES): - if spec_meta['action_key'] in spec: - action_key = spec_meta['action_key'] - input_key = spec_meta['input_key'] - break - - if not action_key: - return - - if spec[action_key] == 'st2.callback': - raise WorkflowDefinitionException('st2.callback is deprecated.') - - # Convert parameters that are inline (i.e. action: some_action var1={$.value1} var2={$.value2}) - # and split it to action name and input dict as illustrated below. - # - # action: some_action - # input: - # var1: <% $.value1 %> - # var2: <% $.value2 %> - # - # This step to separate the action name and the input parameters is required - # to wrap them with the st2.action proxy. - # - # action: st2.action - # input: - # ref: some_action - # parameters: - # var1: <% $.value1 %> - # var2: <% $.value2 %> - _eval_inline_params(spec, action_key, input_key) - - transformed = (spec[action_key] == 'st2.action') - - action_ref = spec[input_key]['ref'] if transformed else spec[action_key] - - action = None - - # Identify if action is a registered StackStorm action. - if action_ref and ResourceReference.is_resource_reference(action_ref): - action = action_utils.get_action_by_ref(ref=action_ref) - - # If action is a registered StackStorm action, then wrap the - # action with the st2 proxy and validate the action input. - if action: - if not transformed: - spec[action_key] = 'st2.action' - action_input = spec.get(input_key) - spec[input_key] = {'ref': action_ref} - if action_input: - spec[input_key]['parameters'] = action_input - - action_input = spec.get(input_key, {}) - action_params = action_input.get('parameters', {}) - _validate_action_parameters(name, action, action_params) - - xformed_action_params = {} - - for param_name in action_params.keys(): - param_value = copy.deepcopy(action_params[param_name]) - xformed_param_value = _transform_action_param( - action_ref, param_name, param_value) - xformed_action_params[param_name] = xformed_param_value - - if xformed_action_params != action_params: - spec[input_key]['parameters'] = xformed_action_params - - -def transform_definition(definition): - # If definition is a dictionary, there is no need to load from YAML. - is_dict = isinstance(definition, dict) - spec = copy.deepcopy(definition) if is_dict else yaml.safe_load(definition) - - # Transform adhoc actions - for action_name, action_spec in six.iteritems(spec.get('actions', {})): - _transform_action(action_name, action_spec) - - # Determine if definition is a workbook or workflow - is_workbook = 'workflows' in spec - - # Transform tasks - if is_workbook: - for workflow_name, workflow_spec in six.iteritems(spec.get('workflows', {})): - if 'tasks' in workflow_spec: - for task_name, task_spec in six.iteritems(workflow_spec.get('tasks')): - _transform_action(task_name, task_spec) - else: - for key, value in six.iteritems(spec): - if 'tasks' in value: - for task_name, task_spec in six.iteritems(value.get('tasks')): - _transform_action(task_name, task_spec) - - # Return the same type as original input. - return spec if is_dict else yaml.safe_dump(spec, default_flow_style=False) - - -def retry_on_exceptions(exc): - LOG.warning('Determining if %s should be retried...', type(exc)) - - is_connection_error = isinstance(exc, requests.exceptions.ConnectionError) - is_duplicate_error = isinstance(exc, APIException) and 'Duplicate' in exc.error_message - is_messaging_error = isinstance(exc, APIException) and 'MessagingTimeout' in exc.error_message - retrying = is_connection_error or is_duplicate_error or is_messaging_error - - if retrying: - LOG.warning('Retrying Mistral API invocation on exception type %s.', type(exc)) - - return retrying diff --git a/st2common/st2common/validators/workflow/mistral/__init__.py b/st2common/st2common/validators/workflow/mistral/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/st2common/st2common/validators/workflow/mistral/v2.py b/st2common/st2common/validators/workflow/mistral/v2.py deleted file mode 100644 index 30e29113fb..0000000000 --- a/st2common/st2common/validators/workflow/mistral/v2.py +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import re - -import six -import yaml - -try: - from mistralclient.api import client as mistral -except ImportError: - # Likely running on installation without Mistral - mistral = None - -from oslo_config import cfg - -from st2common.exceptions.workflow import WorkflowDefinitionException -from st2common import log as logging -from st2common.util.workflow import mistral as utils -from st2common.util.url import get_url_without_trailing_slash -from st2common.validators.workflow.base import WorkflowValidator - - -LOG = logging.getLogger(__name__) - - -def get_validator(): - if not mistral: - # Mistral not available, likely running on distribution without Mistral - return None - - return MistralWorkflowValidator() - - -class MistralWorkflowValidator(WorkflowValidator): - - url = get_url_without_trailing_slash(cfg.CONF.mistral.v2_base_url) - - def __init__(self): - super(MistralWorkflowValidator, self).__init__() - self._client = mistral.client( - mistral_url=self.url, - username=cfg.CONF.mistral.keystone_username, - api_key=cfg.CONF.mistral.keystone_password, - project_name=cfg.CONF.mistral.keystone_project_name, - auth_url=cfg.CONF.mistral.keystone_auth_url, - cacert=cfg.CONF.mistral.cacert, - insecure=cfg.CONF.mistral.insecure) - - @staticmethod - def parse(message): - result = { - 'type': None, - 'path': None, - 'message': message - } - - # Check message for schema specific error. - m1 = re.search('^Invalid DSL: (.+)\n', message) - - if m1: - result['type'] = 'schema' - result['message'] = m1.group(1) - - path = re.search('On instance(.+):', message) - - if path: - result['path'] = path.group(1).strip("[']").replace("']['", ".") - - # Check message for YAQL specific error. - m2 = re.search('^Parse error: (.+)$', message) - - if m2: - result['type'] = 'yaql' - result['message'] = m2.group(1) - - # Check message for action parameters specific error. - if any([candidate in message - for candidate in ['Missing required parameters', - 'Unexpected parameters', - 'st2.callback is deprecated']]): - result['type'] = 'action' - - return result - - def validate(self, definition): - def_dict = yaml.safe_load(definition) - is_workbook = ('workflows' in def_dict) - - if not is_workbook: - # Non-workbook definition containing multiple workflows is not supported. - if len([k for k, _ in six.iteritems(def_dict) if k != 'version']) != 1: - return [self.parse('Multiple workflows is not supported workflow ' - 'only (not a workbook) definition.')] - - # Select validation function. - func = self._client.workbooks.validate if is_workbook else self._client.workflows.validate - - # Validate before custom DSL transformation. - result = func(definition) - - if not result.get('valid', None): - return [self.parse(result.get('error', 'Unknown exception.'))] - - try: - # Run custom DSL transformer to check action parameters. - utils.transform_definition(def_dict) - except WorkflowDefinitionException as e: - return [self.parse(six.text_type(e))] - - return [] diff --git a/st2common/tests/unit/test_util_mistral_dsl_transform.py b/st2common/tests/unit/test_util_mistral_dsl_transform.py deleted file mode 100644 index 1fc44494ad..0000000000 --- a/st2common/tests/unit/test_util_mistral_dsl_transform.py +++ /dev/null @@ -1,194 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import copy -import six -import yaml - -from st2tests import DbTestCase -from st2tests.fixturesloader import FixturesLoader -from st2common.exceptions.workflow import WorkflowDefinitionException -from st2common.models.api.action import ActionAPI, RunnerTypeAPI -from st2common.persistence.action import Action -from st2common.persistence.runner import RunnerType -from st2common.util.workflow import mistral as utils - - -WB_PRE_XFORM_FILE = 'wb_pre_xform.yaml' -WB_POST_XFORM_FILE = 'wb_post_xform.yaml' -WF_PRE_XFORM_FILE = 'wf_pre_xform.yaml' -WF_POST_XFORM_FILE = 'wf_post_xform.yaml' -WF_JINJA_ST2KV_PRE_XFORM_FILE = 'wf_has_jinja_st2kv_pre_xform.yaml' -WF_JINJA_ST2KV_POST_XFORM_FILE = 'wf_has_jinja_st2kv_post_xform.yaml' -WF_JINJA_MIXED_CTX1_FILE = 'wf_jinja_mixed_context_ref1.yaml' -WF_JINJA_MIXED_CTX2_FILE = 'wf_jinja_mixed_context_ref2.yaml' -WF_NO_REQ_PARAM_FILE = 'wf_missing_required_param.yaml' -WF_UNEXP_PARAM_FILE = 'wf_has_unexpected_param.yaml' - -TEST_FIXTURES = { - 'workflows': [ - WB_PRE_XFORM_FILE, - WB_POST_XFORM_FILE, - WF_PRE_XFORM_FILE, - WF_POST_XFORM_FILE, - WF_JINJA_ST2KV_PRE_XFORM_FILE, - WF_JINJA_ST2KV_POST_XFORM_FILE, - WF_JINJA_MIXED_CTX1_FILE, - WF_JINJA_MIXED_CTX2_FILE, - WF_NO_REQ_PARAM_FILE, - WF_UNEXP_PARAM_FILE - ], - 'actions': [ - 'local.yaml', - 'a1.yaml', - 'a2.yaml', - 'action1.yaml' - ], - 'runners': [ - 'run-local.yaml', - 'testrunner1.yaml', - 'testrunner2.yaml' - ] -} - -PACK = 'generic' -LOADER = FixturesLoader() -FIXTURES = LOADER.load_fixtures(fixtures_pack=PACK, fixtures_dict=TEST_FIXTURES) -WB_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_PRE_XFORM_FILE) -WB_PRE_XFORM_DEF = FIXTURES['workflows'][WB_PRE_XFORM_FILE] -WB_POST_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_POST_XFORM_FILE) -WB_POST_XFORM_DEF = FIXTURES['workflows'][WB_POST_XFORM_FILE] -WF_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_PRE_XFORM_FILE) -WF_PRE_XFORM_DEF = FIXTURES['workflows'][WF_PRE_XFORM_FILE] -WF_POST_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_POST_XFORM_FILE) -WF_POST_XFORM_DEF = FIXTURES['workflows'][WF_POST_XFORM_FILE] -WF_JINJA_ST2KV_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs( - PACK, 'workflows', WF_JINJA_ST2KV_PRE_XFORM_FILE) -WF_JINJA_ST2KV_PRE_XFORM_DEF = FIXTURES['workflows'][WF_JINJA_ST2KV_PRE_XFORM_FILE] -WF_JINJA_ST2KV_POST_XFORM_PATH = LOADER.get_fixture_file_path_abs( - PACK, 'workflows', WF_JINJA_ST2KV_POST_XFORM_FILE) -WF_JINJA_MIXED_CTX1_DEF = FIXTURES['workflows'][WF_JINJA_MIXED_CTX1_FILE] -WF_JINJA_MIXED_CTX1_PATH = LOADER.get_fixture_file_path_abs( - PACK, 'workflows', WF_JINJA_MIXED_CTX1_FILE) -WF_JINJA_MIXED_CTX2_DEF = FIXTURES['workflows'][WF_JINJA_MIXED_CTX2_FILE] -WF_JINJA_MIXED_CTX2_PATH = LOADER.get_fixture_file_path_abs( - PACK, 'workflows', WF_JINJA_MIXED_CTX2_FILE) -WF_JINJA_ST2KV_POST_XFORM_DEF = FIXTURES['workflows'][WF_JINJA_ST2KV_POST_XFORM_FILE] -WF_NO_REQ_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_NO_REQ_PARAM_FILE) -WF_NO_REQ_PARAM_DEF = FIXTURES['workflows'][WF_NO_REQ_PARAM_FILE] -WF_UNEXP_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_UNEXP_PARAM_FILE) -WF_UNEXP_PARAM_DEF = FIXTURES['workflows'][WF_UNEXP_PARAM_FILE] - - -class DSLTransformTestCase(DbTestCase): - - @classmethod - def setUpClass(cls): - super(DSLTransformTestCase, cls).setUpClass() - - for _, fixture in six.iteritems(FIXTURES['runners']): - instance = RunnerTypeAPI(**fixture) - RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) - - for _, fixture in six.iteritems(FIXTURES['actions']): - instance = ActionAPI(**fixture) - Action.add_or_update(ActionAPI.to_model(instance)) - - def _read_file_content(self, path): - with open(path, 'r') as f: - return f.read() - - def _read_yaml_file_as_json(self, path): - def_yaml = self._read_file_content(path) - return yaml.safe_load(def_yaml) - - def test_transform_workbook_dsl_yaml(self): - def_yaml = self._read_file_content(WB_PRE_XFORM_PATH) - new_def = utils.transform_definition(def_yaml) - actual = yaml.safe_load(new_def) - expected = copy.deepcopy(WB_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_transform_workbook_dsl_dict(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - actual = utils.transform_definition(def_dict) - expected = copy.deepcopy(WB_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_transform_workflow_dsl_yaml(self): - def_yaml = self._read_file_content(WF_PRE_XFORM_PATH) - new_def = utils.transform_definition(def_yaml) - actual = yaml.safe_load(new_def) - expected = copy.deepcopy(WF_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_transform_workflow_dsl_dict(self): - def_dict = self._read_yaml_file_as_json(WF_PRE_XFORM_PATH) - actual = utils.transform_definition(def_dict) - expected = copy.deepcopy(WF_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_transform_workflow_with_jinja_st2kv_dsl_yaml(self): - def_yaml = self._read_file_content(WF_JINJA_ST2KV_PRE_XFORM_PATH) - new_def = utils.transform_definition(def_yaml) - actual = yaml.safe_load(new_def) - expected = copy.deepcopy(WF_JINJA_ST2KV_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_transform_workflow_with_jinja_st2kv_dsl_dict(self): - def_dict = self._read_yaml_file_as_json(WF_JINJA_ST2KV_PRE_XFORM_PATH) - actual = utils.transform_definition(def_dict) - expected = copy.deepcopy(WF_JINJA_ST2KV_POST_XFORM_DEF) - self.assertDictEqual(actual, expected) - - def test_mixed_jinja_context_same_delimiter(self): - def_dict = self._read_yaml_file_as_json(WF_JINJA_MIXED_CTX1_PATH) - - with self.assertRaises(WorkflowDefinitionException) as cm: - utils.transform_definition(def_dict) - - self.assertIn('strtype', str(cm)) - self.assertIn('references to both local context', str(cm)) - - def test_mixed_jinja_context_separate_delimiters(self): - def_dict = self._read_yaml_file_as_json(WF_JINJA_MIXED_CTX2_PATH) - - with self.assertRaises(WorkflowDefinitionException) as cm: - utils.transform_definition(def_dict) - - self.assertIn('inttype', str(cm)) - self.assertIn('references to both local context', str(cm)) - - def test_required_action_params_failure(self): - def_dict = self._read_yaml_file_as_json(WF_NO_REQ_PARAM_PATH) - - with self.assertRaises(WorkflowDefinitionException) as cm: - utils.transform_definition(def_dict) - - self.assertIn('Missing required parameters', str(cm)) - - def test_unexpected_action_params_failure(self): - def_dict = self._read_yaml_file_as_json(WF_UNEXP_PARAM_PATH) - - with self.assertRaises(WorkflowDefinitionException) as cm: - utils.transform_definition(def_dict) - - self.assertIn('Unexpected parameters', str(cm)) - - def test_deprecated_callback_action(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - def_dict['workflows']['main']['tasks']['callback'] = {'action': 'st2.callback'} - def_yaml = yaml.safe_dump(def_dict) - self.assertRaises(WorkflowDefinitionException, utils.transform_definition, def_yaml) diff --git a/st2common/tests/unit/test_validator_mistral.py b/st2common/tests/unit/test_validator_mistral.py deleted file mode 100644 index b64f9f51ea..0000000000 --- a/st2common/tests/unit/test_validator_mistral.py +++ /dev/null @@ -1,312 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import mock -import six -import yaml -from mistralclient.api.v2 import workbooks -from mistralclient.api.v2 import workflows - -from st2tests import config as test_config -test_config.parse_args() - -from st2tests import DbTestCase -from st2tests.fixturesloader import FixturesLoader -from st2common.models.api.action import ActionAPI, RunnerTypeAPI -from st2common.persistence.action import Action -from st2common.persistence.runner import RunnerType -from st2common.validators.workflow.mistral import v2 as wf_validation_utils - - -WB_PRE_XFORM_FILE = 'wb_pre_xform.yaml' -WB_POST_XFORM_FILE = 'wb_post_xform.yaml' -WB_INVALID_SYNTAX_FILE = 'wb_invalid_syntax.yaml' -WB_INVALID_YAQL_FILE = 'wb_invalid_yaql.yaml' -WF_PRE_XFORM_FILE = 'wf_pre_xform.yaml' -WF_POST_XFORM_FILE = 'wf_post_xform.yaml' -WF_NO_REQ_PARAM_FILE = 'wf_missing_required_param.yaml' -WF_UNEXP_PARAM_FILE = 'wf_has_unexpected_param.yaml' -WF_INVALID_SYNTAX_FILE = 'wf_invalid_syntax.yaml' -WF_INVALID_YAQL_FILE = 'wf_invalid_yaql.yaml' - -TEST_FIXTURES = { - 'workflows': [ - WB_PRE_XFORM_FILE, - WB_POST_XFORM_FILE, - WB_INVALID_SYNTAX_FILE, - WB_INVALID_YAQL_FILE, - WF_PRE_XFORM_FILE, - WF_POST_XFORM_FILE, - WF_NO_REQ_PARAM_FILE, - WF_UNEXP_PARAM_FILE, - WF_INVALID_SYNTAX_FILE, - WF_INVALID_YAQL_FILE - ], - 'actions': [ - 'local.yaml', - 'a1.yaml', - 'a2.yaml', - 'action1.yaml' - ], - 'runners': [ - 'run-local.yaml', - 'testrunner1.yaml', - 'testrunner2.yaml' - ] -} - -PACK = 'generic' -LOADER = FixturesLoader() -FIXTURES = LOADER.load_fixtures(fixtures_pack=PACK, fixtures_dict=TEST_FIXTURES) -WB_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_PRE_XFORM_FILE) -WB_PRE_XFORM_DEF = FIXTURES['workflows'][WB_PRE_XFORM_FILE] -WB_POST_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_POST_XFORM_FILE) -WB_POST_XFORM_DEF = FIXTURES['workflows'][WB_POST_XFORM_FILE] -WB_INVALID_SYNTAX_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_INVALID_SYNTAX_FILE) -WB_INVALID_SYNTAX_DEF = FIXTURES['workflows'][WB_INVALID_SYNTAX_FILE] -WB_INVALID_YAQL_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WB_INVALID_YAQL_FILE) -WB_INVALID_YAQL_DEF = FIXTURES['workflows'][WB_INVALID_YAQL_FILE] -WF_PRE_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_PRE_XFORM_FILE) -WF_PRE_XFORM_DEF = FIXTURES['workflows'][WF_PRE_XFORM_FILE] -WF_POST_XFORM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_POST_XFORM_FILE) -WF_POST_XFORM_DEF = FIXTURES['workflows'][WF_POST_XFORM_FILE] -WF_NO_REQ_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_NO_REQ_PARAM_FILE) -WF_NO_REQ_PARAM_DEF = FIXTURES['workflows'][WF_NO_REQ_PARAM_FILE] -WF_UNEXP_PARAM_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_UNEXP_PARAM_FILE) -WF_UNEXP_PARAM_DEF = FIXTURES['workflows'][WF_UNEXP_PARAM_FILE] -WF_INVALID_SYNTAX_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_INVALID_SYNTAX_FILE) -WF_INVALID_SYNTAX_DEF = FIXTURES['workflows'][WF_INVALID_SYNTAX_FILE] -WF_INVALID_YAQL_PATH = LOADER.get_fixture_file_path_abs(PACK, 'workflows', WF_INVALID_YAQL_FILE) -WF_INVALID_YAQL_DEF = FIXTURES['workflows'][WF_INVALID_YAQL_FILE] - - -class MistralValidationTest(DbTestCase): - - @classmethod - def setUpClass(cls): - super(MistralValidationTest, cls).setUpClass() - - for _, fixture in six.iteritems(FIXTURES['runners']): - instance = RunnerTypeAPI(**fixture) - RunnerType.add_or_update(RunnerTypeAPI.to_model(instance)) - - for _, fixture in six.iteritems(FIXTURES['actions']): - instance = ActionAPI(**fixture) - Action.add_or_update(ActionAPI.to_model(instance)) - - cls.validator = wf_validation_utils.get_validator() - - def _read_file_content(self, path): - with open(path, 'r') as f: - return f.read() - - def _read_yaml_file_as_json(self, path): - def_yaml = self._read_file_content(path) - return yaml.safe_load(def_yaml) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Invalid DSL: \'version\' is a required property\n'})) - def test_missing_version(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - del def_dict['version'] - def_yaml = yaml.safe_dump(def_dict) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': None, - 'message': '\'version\' is a required property' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Invalid DSL: Unsupported DSL version\n'})) - def test_unsupported_version(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - def_dict['version'] = '1.0' - def_yaml = yaml.safe_dump(def_dict) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': None, - 'message': 'Unsupported DSL version' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_required_action_params_failure(self): - def_yaml = self._read_file_content(WF_NO_REQ_PARAM_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': None, - 'message': 'Missing required parameters in "task1" ' - 'for action "wolfpack.action-1": "actionstr"' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_unexpected_action_params_failure(self): - def_yaml = self._read_file_content(WF_UNEXP_PARAM_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': None, - 'message': 'Unexpected parameters in "task1" ' - 'for action "wolfpack.action-1": "foo"' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_deprecated_callback_action(self): - def_dict = self._read_yaml_file_as_json(WB_PRE_XFORM_PATH) - def_dict['workflows']['main']['tasks']['callback'] = {'action': 'st2.callback'} - def_yaml = yaml.safe_dump(def_dict) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'action', - 'path': None, - 'message': 'st2.callback is deprecated.' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_workbook_valid(self): - def_yaml = self._read_file_content(WB_PRE_XFORM_PATH) - result = self.validator.validate(def_yaml) - self.assertEqual(0, len(result)) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': "Invalid DSL: foobar\n\nEpic fail\nOn instance['tasks']['task1']:\n"})) - def test_workbook_invalid_syntax(self): - def_yaml = self._read_file_content(WB_INVALID_SYNTAX_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': 'tasks.task1', - 'message': 'foobar' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workbooks.WorkbookManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Parse error: unexpected end of statement.'})) - def test_workbook_invalid_yaql(self): - def_yaml = self._read_file_content(WB_INVALID_YAQL_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'yaql', - 'path': None, - 'message': 'unexpected end of statement.' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock(return_value={'valid': True})) - def test_workflow_valid(self): - def_yaml = self._read_file_content(WF_PRE_XFORM_PATH) - result = self.validator.validate(def_yaml) - self.assertEqual(0, len(result)) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': "Invalid DSL: foobar\n\nEpic fail\nOn instance['tasks']['task1']:\n"})) - def test_workflow_invalid_syntax(self): - def_yaml = self._read_file_content(WF_INVALID_SYNTAX_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'schema', - 'path': 'tasks.task1', - 'message': 'foobar' - } - ] - - self.assertListEqual(expected, result) - - @mock.patch.object( - workflows.WorkflowManager, 'validate', - mock.MagicMock( - return_value={ - 'valid': False, - 'error': 'Parse error: unexpected end of statement.'})) - def test_workflow_invalid_yaql(self): - def_yaml = self._read_file_content(WF_INVALID_YAQL_PATH) - result = self.validator.validate(def_yaml) - - expected = [ - { - 'type': 'yaql', - 'path': None, - 'message': 'unexpected end of statement.' - } - ] - - self.assertListEqual(expected, result) diff --git a/st2debug/tests/integration/fixtures/configs/mistral.conf b/st2debug/tests/integration/fixtures/configs/mistral.conf deleted file mode 100644 index ca17f2cf91..0000000000 --- a/st2debug/tests/integration/fixtures/configs/mistral.conf +++ /dev/null @@ -1,5 +0,0 @@ -[database] -connection=mysql://mistral:StackStorm@127.0.0.1/mistral - -[pecan] -auth_enable=false diff --git a/st2tests/integration/mistral/__init__.py b/st2tests/integration/mistral/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/st2tests/integration/mistral/base.py b/st2tests/integration/mistral/base.py deleted file mode 100644 index 5061fc7b12..0000000000 --- a/st2tests/integration/mistral/base.py +++ /dev/null @@ -1,122 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import retrying -import six -import unittest2 - -from st2client import client as st2 -from st2client import models -from st2common.constants import action as action_constants - - -LIVEACTION_LAUNCHED_STATUSES = [ - action_constants.LIVEACTION_STATUS_REQUESTED, - action_constants.LIVEACTION_STATUS_SCHEDULED, - action_constants.LIVEACTION_STATUS_RUNNING -] - - -def retry_on_exceptions(exc): - return isinstance(exc, AssertionError) - - -class TestWorkflowExecution(unittest2.TestCase): - - @classmethod - def setUpClass(cls): - cls.st2client = st2.Client(base_url='http://127.0.0.1') - - def _execute_workflow(self, action, parameters=None): - ex = models.LiveAction(action=action, parameters=(parameters or {})) - ex = self.st2client.executions.create(ex) - self.assertIsNotNone(ex.id) - self.assertEqual(ex.action['ref'], action) - self.assertIn(ex.status, LIVEACTION_LAUNCHED_STATUSES) - - return ex - - @retrying.retry( - retry_on_exception=retry_on_exceptions, - wait_fixed=3000, stop_max_delay=900000) - def _wait_for_state(self, ex, states): - if isinstance(states, six.string_types): - states = [states] - - for state in states: - if state not in action_constants.LIVEACTION_STATUSES: - raise ValueError('Status %s is not valid.' % state) - - try: - ex = self.st2client.executions.get_by_id(ex.id) - self.assertIn(ex.status, states) - except: - if ex.status in action_constants.LIVEACTION_COMPLETED_STATES: - raise Exception( - 'Execution is in completed state and does not ' - 'match expected state(s).' - ) - else: - raise - - return ex - - def _get_children(self, ex): - return self.st2client.executions.query(parent=ex.id) - - @retrying.retry( - retry_on_exception=retry_on_exceptions, - wait_fixed=3000, stop_max_delay=900000) - def _wait_for_task(self, ex, task, status, num_task_exs=1): - ex = self.st2client.executions.get_by_id(ex.id) - - task_exs = [ - task_ex for task_ex in self._get_children(ex) - if (task_ex.context.get('mistral', {}).get('task_name', '') == task and - task_ex.status == status) - ] - - try: - self.assertEqual(len(task_exs), num_task_exs) - self.assertTrue(all([task_ex.status == status for task_ex in task_exs])) - except: - if ex.status in action_constants.LIVEACTION_COMPLETED_STATES: - raise Exception( - 'Execution is in completed state and does not ' - 'match expected task.' - ) - else: - raise - - return task_exs - - @retrying.retry( - retry_on_exception=retry_on_exceptions, - wait_fixed=3000, stop_max_delay=900000) - def _wait_for_completion(self, ex): - ex = self._wait_for_state(ex, action_constants.LIVEACTION_COMPLETED_STATES) - - try: - self.assertTrue(hasattr(ex, 'result')) - except: - if ex.status in action_constants.LIVEACTION_COMPLETED_STATES: - raise Exception( - 'Execution is in completed state and does not ' - 'contain expected result.' - ) - else: - raise - - return ex diff --git a/st2tests/integration/mistral/test_errors.py b/st2tests/integration/mistral/test_errors.py deleted file mode 100644 index 16576c4839..0000000000 --- a/st2tests/integration/mistral/test_errors.py +++ /dev/null @@ -1,115 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -from integration.mistral import base - -from st2common.constants import action as action_constants - - -class ExceptionHandlingTest(base.TestWorkflowExecution): - - def test_bad_workflow(self): - with self.assertRaises(Exception) as t: - self._execute_workflow('examples.mistral-foobar', {}) - - self.assertIn('Action "examples.mistral-foobar" cannot be found', t.exception.message) - - def test_bad_action(self): - ex = self._execute_workflow('examples.mistral-error-bad-action', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Failed to find action', ex.result['extra']['state_info']) - - def test_bad_wf_arg(self): - ex = self._execute_workflow('examples.mistral-error-bad-wf-arg', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Invalid input', ex.result['extra']['state_info']) - - def test_bad_task_transition(self): - ex = self._execute_workflow('examples.mistral-error-bad-task-transition', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn("Task 'task3' not found", ex.result['error']) - - def test_bad_with_items(self): - ex = self._execute_workflow('examples.mistral-error-bad-with-items', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Wrong input format', ex.result['extra']['state_info']) - - def test_bad_expr_yaql(self): - ex = self._execute_workflow('examples.mistral-test-yaql-bad-expr', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate YAQL expression', ex.result['extra']['state_info']) - - def test_bad_publish_yaql(self): - ex = self._execute_workflow('examples.mistral-test-yaql-bad-publish', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate YAQL expression', ex.result['extra']['state_info']) - - def test_bad_subworkflow_input_yaql(self): - ex = self._execute_workflow('examples.mistral-test-yaql-bad-subworkflow-input', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate YAQL expression', ex.result['extra']['state_info']) - - def test_bad_task_transition_yaql(self): - ex = self._execute_workflow('examples.mistral-test-yaql-bad-task-transition', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate YAQL expression', ex.result['extra']['state_info']) - - def test_bad_with_items_yaql(self): - ex = self._execute_workflow('examples.mistral-test-yaql-bad-with-items', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate YAQL expression', ex.result['extra']['state_info']) - - def test_bad_expr_jinja(self): - ex = self._execute_workflow('examples.mistral-test-jinja-bad-expr', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - - # TODO: Currently, Mistral returns "UndefinedError ContextView object has no attribute". - # Need to fix Mistral to return "Cannot evaulate Jinja expression." - # self.assertIn('Can not evaluate Jinja expression', - # ex.result['extra']['state_info']) - - def test_bad_publish_jinja(self): - ex = self._execute_workflow('examples.mistral-test-jinja-bad-publish', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate Jinja expression', ex.result['extra']['state_info']) - - def test_bad_subworkflow_input_jinja(self): - ex = self._execute_workflow('examples.mistral-test-jinja-bad-subworkflow-input', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate Jinja expression', ex.result['extra']['state_info']) - - def test_bad_task_transition_jinja(self): - ex = self._execute_workflow('examples.mistral-test-jinja-bad-task-transition', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate Jinja expression', ex.result['extra']['state_info']) - - def test_bad_with_items_jinja(self): - ex = self._execute_workflow('examples.mistral-test-jinja-bad-with-items', {}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertIn('Can not evaluate Jinja expression', ex.result['extra']['state_info']) diff --git a/st2tests/integration/mistral/test_examples.py b/st2tests/integration/mistral/test_examples.py deleted file mode 100644 index 2960ae92fc..0000000000 --- a/st2tests/integration/mistral/test_examples.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import - -from integration.mistral import base - -from st2common.constants import action as action_constants - - -class ExamplesTest(base.TestWorkflowExecution): - - def test_environment(self): - ex = self._execute_workflow('examples.mistral-env-var') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - expected_output = 'http://127.0.0.1:9101/executions/' + ex.id - self.assertEqual(ex.result['url'], expected_output) - - def test_branching(self): - # Execute with path a. - params = {'which': 'a'} - ex = self._execute_workflow('examples.mistral-branching', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['stdout'], 'Took path A.') - - # Execute with path b. - params = {'which': 'b'} - ex = self._execute_workflow('examples.mistral-branching', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['stdout'], 'Took path B.') - - # Execute with path c. - params = {'which': 'c'} - ex = self._execute_workflow('examples.mistral-branching', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['stdout'], 'Took path C.') - - def test_join(self): - ex = self._execute_workflow('examples.mistral-join') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_handle_error(self): - ex = self._execute_workflow('examples.mistral-handle-error') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertTrue(ex.result['error_handled']) - - def test_handle_error_task_default(self): - ex = self._execute_workflow('examples.mistral-handle-error-task-default') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - self.assertTrue(ex.result['error_handled']) - - def test_handle_retry(self): - ex = self._execute_workflow('examples.mistral-handle-retry') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_repeat(self): - params = {'cmd': 'echo "Yo!"', 'count': 3} - ex = self._execute_workflow('examples.mistral-repeat', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result['result']), params['count']) - self.assertListEqual(ex.result['result'], ['Yo!'] * params['count']) - - def test_repeat_with_items(self): - params = {'cmds': ['echo "a"', 'echo "b"', 'echo "c"']} - ex = self._execute_workflow('examples.mistral-repeat-with-items', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result['result']), len(params['cmds'])) - self.assertListEqual(sorted(ex.result['result']), ['a', 'b', 'c']) - - def test_with_items_batch_processing(self): - params = {'cmd': 'date +%s', 'count': 4} - ex = self._execute_workflow('examples.mistral-with-items-concurrency', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result['result']), params['count']) - - timestamps = [int(dt) for dt in ex.result['result']] - self.assertTrue(timestamps[1] - timestamps[0] < 3) - self.assertTrue(timestamps[3] - timestamps[2] < 3) - self.assertTrue(timestamps[2] - timestamps[1] >= 3) - - def test_workbook_multiple_subflows(self): - ex = self._execute_workflow('examples.mistral-workbook-multiple-subflows') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) diff --git a/st2tests/integration/mistral/test_filters.py b/st2tests/integration/mistral/test_filters.py deleted file mode 100644 index 609810b694..0000000000 --- a/st2tests/integration/mistral/test_filters.py +++ /dev/null @@ -1,391 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import json -import yaml - -from integration.mistral import base - -from st2common.constants import action as action_constants - - -REGEX_SEARCH_STRINGS = [ - "Your address is 567 Elsewhere Dr. My address is 123 Somewhere Ave.", - "567 Elsewhere Dr is your address. My address is 123 Somewhere Ave.", - "No address to be found here! Well, maybe 127.0.0.1" -] - -REGEX_PATTERN = '([0-9]{3} \\w+ (?:Ave|St|Dr))' - - -class FromJsonStringFiltersTest(base.TestWorkflowExecution): - - def test_from_json_string(self): - ex = self._execute_workflow( - 'examples.mistral-test-func-from-json-string', - parameters={ - "input_str": '{"a": "b"}' - } - ) - - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = ex.result['result_jinja'] - yaql_dict = ex.result['result_yaql'] - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict["a"], "b") - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict["a"], "b") - - -class FromYamlStringFiltersTest(base.TestWorkflowExecution): - - def test_from_yaml_string(self): - ex = self._execute_workflow( - 'examples.mistral-test-func-from-yaml-string', - parameters={ - "input_str": 'a: b' - } - ) - - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = ex.result['result_jinja'] - yaql_dict = ex.result['result_yaql'] - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict["a"], "b") - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict["a"], "b") - - -class JsonEscapeFiltersTest(base.TestWorkflowExecution): - - def test_json_escape(self): - breaking_str = 'This text """ breaks JSON' - params = {'input_str': breaking_str} - ex = self._execute_workflow('examples.mistral-test-func-json-escape', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = json.loads(ex.result['result_jinja'])[0] - yaql_dict = json.loads(ex.result['result_yaql'])[0] - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict['title'], breaking_str) - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict['title'], breaking_str) - - -class JsonpathQueryFiltersTest(base.TestWorkflowExecution): - - def test_jsonpath_query(self): - - ex = self._execute_workflow( - 'examples.mistral-test-func-jsonpath-query', - parameters={ - "input_obj": {'people': [{'first': 'James', 'last': 'Smith'}, - {'first': 'Jacob', 'last': 'Alberts'}, - {'first': 'Jayden', 'last': 'Davis'}, - {'missing': 'different'}]}, - "input_query": "people[*].last" - } - ) - expected_result = ['Smith', 'Alberts', 'Davis'] - - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_result = ex.result['result_jinja'] - yaql_result = ex.result['result_yaql'] - self.assertIsInstance(jinja_result, list) - self.assertEqual(jinja_result, expected_result) - self.assertIsInstance(yaql_result, list) - self.assertEqual(yaql_result, expected_result) - - -class RegexMatchFiltersTest(base.TestWorkflowExecution): - - def test_regex_match(self): - params = {'input_str': REGEX_SEARCH_STRINGS[1], 'regex_pattern': REGEX_PATTERN} - ex = self._execute_workflow('examples.mistral-test-func-regex-match', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertTrue(ex.result['result_jinja']) - self.assertTrue(ex.result['result_yaql']) - - def test_regex_nomatch(self): - params = {'input_str': REGEX_SEARCH_STRINGS[0], 'regex_pattern': REGEX_PATTERN} - ex = self._execute_workflow('examples.mistral-test-func-regex-match', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertFalse(ex.result['result_jinja']) - self.assertFalse(ex.result['result_yaql']) - - -class RegexReplaceFiltersTest(base.TestWorkflowExecution): - - def test_regex_replace(self): - params = { - 'input_str': REGEX_SEARCH_STRINGS[1], - 'regex_pattern': REGEX_PATTERN, - 'replacement_str': 'foo' - } - - ex = self._execute_workflow('examples.mistral-test-func-regex-replace', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - expected_result = 'foo is your address. My address is foo.' - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class RegexSearchFiltersTest(base.TestWorkflowExecution): - - def test_regex_search(self): - params = {'input_str': REGEX_SEARCH_STRINGS[0], 'regex_pattern': REGEX_PATTERN} - ex = self._execute_workflow('examples.mistral-test-func-regex-search', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertTrue(ex.result['result_jinja']) - self.assertTrue(ex.result['result_yaql']) - - def test_regex_nosearch(self): - params = {'input_str': REGEX_SEARCH_STRINGS[2], 'regex_pattern': REGEX_PATTERN} - ex = self._execute_workflow('examples.mistral-test-func-regex-search', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertFalse(ex.result['result_jinja']) - self.assertFalse(ex.result['result_yaql']) - - -class RegexSubstringFiltersTest(base.TestWorkflowExecution): - - def test_regex_substring(self): - params = {'input_str': REGEX_SEARCH_STRINGS[0], 'regex_pattern': REGEX_PATTERN} - ex = self._execute_workflow('examples.mistral-test-func-regex-substring', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '567 Elsewhere Dr') - self.assertEqual(ex.result['result_yaql'], '567 Elsewhere Dr') - self.assertEqual(ex.result['result_jinja_index_1'], '123 Somewhere Ave') - self.assertEqual(ex.result['result_yaql_index_1'], '123 Somewhere Ave') - - -class ToHumanTimeFromSecondsFiltersTest(base.TestWorkflowExecution): - - def test_to_human_time_from_seconds(self): - action_ref = 'examples.mistral-test-func-to-human-time-from-seconds' - params = {'seconds': 4587} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '1h16m27s') - self.assertEqual(ex.result['result_yaql'], '1h16m27s') - - -class UseNoneFiltersTest(base.TestWorkflowExecution): - - def test_use_none(self): - params = {'input_str': 'foo'} - ex = self._execute_workflow('examples.mistral-test-func-use-none', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['none_result_jinja'], '%*****__%NONE%__*****%') - self.assertEqual(ex.result['none_result_yaql'], '%*****__%NONE%__*****%') - self.assertEqual(ex.result['str_result_jinja'], 'foo') - self.assertEqual(ex.result['str_result_yaql'], 'foo') - - -class ToComplexFiltersTest(base.TestWorkflowExecution): - - def test_to_complex(self): - params = {'input_obj': {'a': 'b'}} - ex = self._execute_workflow('examples.mistral-test-func-to-complex', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = json.loads(ex.result['result_jinja']) - yaql_dict = json.loads(ex.result['result_yaql']) - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict['a'], 'b') - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict['a'], 'b') - - -class ToJsonStringFiltersTest(base.TestWorkflowExecution): - - def test_to_json_string(self): - params = {'input_obj': {'a': 'b'}} - ex = self._execute_workflow('examples.mistral-test-func-to-json-string', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = json.loads(ex.result['result_jinja']) - yaql_dict = json.loads(ex.result['result_yaql']) - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict['a'], 'b') - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict['a'], 'b') - - -class ToYamlStringFiltersTest(base.TestWorkflowExecution): - - def test_to_yaml_string(self): - params = {'input_obj': {'a': 'b'}} - ex = self._execute_workflow('examples.mistral-test-func-to-yaml-string', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - jinja_dict = yaml.safe_load(ex.result['result_jinja']) - yaql_dict = yaml.safe_load(ex.result['result_yaql']) - self.assertIsInstance(jinja_dict, dict) - self.assertEqual(jinja_dict['a'], 'b') - self.assertIsInstance(yaql_dict, dict) - self.assertEqual(yaql_dict['a'], 'b') - - -class VersionCompareFiltersTest(base.TestWorkflowExecution): - - def test_version_compare(self): - versions = { - '0.9.3': 1, - '0.10.1': 0, - '0.10.2': -1 - } - - for compare_version, expected_result in versions.items(): - action_ref = 'examples.mistral-test-func-version-compare' - params = {'version_a': '0.10.1', 'version_b': compare_version} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class VersionMoreThanFiltersTest(base.TestWorkflowExecution): - - def test_version_more_than(self): - versions = { - '0.9.3': True, - '0.10.1': False, - '0.10.2': False - } - - for compare_version, expected_result in versions.items(): - action_ref = 'examples.mistral-test-func-version-more-than' - params = {'version_a': '0.10.1', 'version_b': compare_version} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class VersionLessThanFiltersTest(base.TestWorkflowExecution): - - def test_version_less_than(self): - versions = { - '0.9.3': False, - '0.10.1': False, - '0.10.2': True - } - - for compare_version, expected_result in versions.items(): - action_ref = 'examples.mistral-test-func-version-less-than' - params = {'version_a': '0.10.1', 'version_b': compare_version} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class VersionEqualFiltersTest(base.TestWorkflowExecution): - - def test_version_equal(self): - versions = { - '0.9.3': False, - '0.10.1': True, - '0.10.2': False - } - - for compare_version, expected_result in versions.items(): - action_ref = 'examples.mistral-test-func-version-equal' - params = {'version_a': '0.10.1', 'version_b': compare_version} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class VersionMatchFiltersTest(base.TestWorkflowExecution): - - def test_version_match(self): - versions = { - '>=0.9.3': True, - '>0.11.3': False, - '==0.9.3': False, - '<=0.10.1': True, - '<0.10.2': True - } - - for compare_version, expected_result in versions.items(): - action_ref = 'examples.mistral-test-func-version-match' - params = {'version_a': '0.10.1', 'version_b': compare_version} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], expected_result) - self.assertEqual(ex.result['result_yaql'], expected_result) - - -class VersionBumpMajorFiltersTest(base.TestWorkflowExecution): - - def test_version_bump_major(self): - params = {'version': '0.10.1'} - ex = self._execute_workflow('examples.mistral-test-func-version-bump-major', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '1.0.0') - self.assertEqual(ex.result['result_yaql'], '1.0.0') - - -class VersionBumpMinorFiltersTest(base.TestWorkflowExecution): - - def test_version_bump_minor(self): - params = {'version': '0.10.1'} - ex = self._execute_workflow('examples.mistral-test-func-version-bump-minor', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '0.11.0') - self.assertEqual(ex.result['result_yaql'], '0.11.0') - - -class VersionBumpPatchFiltersTest(base.TestWorkflowExecution): - - def test_version_bump_patch(self): - params = {'version': '0.10.1'} - ex = self._execute_workflow('examples.mistral-test-func-version-bump-patch', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '0.10.2') - self.assertEqual(ex.result['result_yaql'], '0.10.2') - - -class VersionStripPatchFiltersTest(base.TestWorkflowExecution): - - def test_version_strip_patch(self): - params = {'version': '0.10.1'} - ex = self._execute_workflow('examples.mistral-test-func-version-strip-patch', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.result['result_jinja'], '0.10') - self.assertEqual(ex.result['result_yaql'], '0.10') diff --git a/st2tests/integration/mistral/test_st2kv.py b/st2tests/integration/mistral/test_st2kv.py deleted file mode 100644 index 0931b8a523..0000000000 --- a/st2tests/integration/mistral/test_st2kv.py +++ /dev/null @@ -1,105 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -from integration.mistral import base - -from st2client import models -from st2common.constants import action as action_constants - - -class CustomKeyValuePairTest(base.TestWorkflowExecution): - secret = None - - @classmethod - def setUpClass(cls): - super(CustomKeyValuePairTest, cls).setUpClass() - cls.set_kvp('foobar', 'foobar', scope='system', secret=cls.secret) - cls.set_kvp('marco', 'polo', scope='user', secret=cls.secret) - - @classmethod - def tearDownClass(cls): - super(CustomKeyValuePairTest, cls).tearDownClass() - cls.del_kvp('foobar') - cls.del_kvp('marco') - - @classmethod - def set_kvp(cls, name, value, scope='system', secret=False): - kvp = models.KeyValuePair( - id=name, - name=name, - value=value, - scope=scope, - secret=secret - ) - - cls.st2client.keys.update(kvp) - - @classmethod - def del_kvp(cls, name, scope='system'): - kvp = models.KeyValuePair( - id=name, - name=name, - scope=scope - ) - - cls.st2client.keys.delete(kvp) - - -class UnencryptedKeyValuePairTest(CustomKeyValuePairTest): - secret = False - - def test_yaql_system_kvp(self): - ex = self._execute_workflow('examples.mistral-yaql-st2kv-system-scope') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_yaql_user_kvp(self): - ex = self._execute_workflow('examples.mistral-yaql-st2kv-user-scope') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_jinja_system_kvp(self): - ex = self._execute_workflow('examples.mistral-jinja-st2kv-system-scope') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_jinja_user_kvp(self): - # Pending completion of jinja rendering of user scoped variable. - # https://github.com/StackStorm/st2/pull/2931 - pass - - -class EncryptedKeyValuePairTest(CustomKeyValuePairTest): - secret = True - - def test_yaql_system_kvp(self): - ex = self._execute_workflow('examples.mistral-yaql-st2kv-system-scope') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_yaql_user_kvp(self): - ex = self._execute_workflow('examples.mistral-yaql-st2kv-user-scope') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_jinja_system_kvp(self): - ex = self._execute_workflow('examples.mistral-jinja-st2kv-system-scope-encrypted') - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - - def test_jinja_user_kvp(self): - # Per https://docs.stackstorm.com/datastore.html#storing-secrets, - # decrypting user scoped variables is currently unsupported. - pass diff --git a/st2tests/integration/mistral/test_wiring.py b/st2tests/integration/mistral/test_wiring.py deleted file mode 100644 index 058f85dbd0..0000000000 --- a/st2tests/integration/mistral/test_wiring.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import os -import shutil -import tempfile - -import eventlet - -from integration.mistral import base -from six.moves import range - -from st2common.constants import action as action_constants - - -class WiringTest(base.TestWorkflowExecution): - - temp_dir_path = None - - def setUp(self): - super(WiringTest, self).setUp() - - # Create temporary directory used by the tests - _, self.temp_dir_path = tempfile.mkstemp() - os.chmod(self.temp_dir_path, 0o755) # nosec - - def tearDown(self): - if self.temp_dir_path and os.path.exists(self.temp_dir_path): - if os.path.isdir(self.temp_dir_path): - shutil.rmtree(self.temp_dir_path) - else: - os.remove(self.temp_dir_path) - - def test_basic_workflow(self): - ex = self._execute_workflow('examples.mistral-basic', {'cmd': 'date'}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('stdout', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_basic_reverse_workflow(self): - ex = self._execute_workflow('examples.mistral-reverse-basic', {'cmd': 'date'}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('stdout', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_reverse_workflow_with_requires(self): - params = {'question': 'life universe everything'} - ex = self._execute_workflow('examples.mistral-reverse-requires', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('answer', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 5) - - def test_basic_workbook(self): - ex = self._execute_workflow('examples.mistral-workbook-basic', {'cmd': 'date'}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('stdout', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_complex_workbook_with_yaql(self): - params = {'vm_name': 'demo1'} - ex = self._execute_workflow('examples.mistral-workbook-complex', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('vm_id', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 8) - - def test_complex_workbook_with_jinja(self): - params = {'vm_name': 'demo2'} - ex = self._execute_workflow('examples.mistral-jinja-workbook-complex', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('vm_id', ex.result) - self.assertEqual(len(ex.result.get('tasks', [])), 8) - - def test_complex_workbook_subflow_actions(self): - params = {'subject': 'st2', 'adjective': 'cool'} - ex = self._execute_workflow('examples.mistral-workbook-subflows', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('tagline', ex.result) - self.assertEqual(ex.result['tagline'], 'st2 is cool!') - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_with_items(self): - params = {'cmd': 'date', 'count': 8} - ex = self._execute_workflow('examples.mistral-repeat', params) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result['result']), params['count']) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_concurrent_load(self): - wf_name = 'examples.mistral-workbook-complex' - wf_params = {'vm_name': 'demo1'} - exs = [self._execute_workflow(wf_name, wf_params) for i in range(3)] - - eventlet.sleep(20) - - for ex in exs: - e = self._wait_for_completion(ex) - self.assertEqual(e.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertIn('vm_id', e.result) - self.assertEqual(len(e.result.get('tasks', [])), 8) - - def test_execution_failure(self): - ex = self._execute_workflow('examples.mistral-basic', {'cmd': 'foo'}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_FAILED) - - def test_invoke_from_action_chain(self): - ex = self._execute_workflow('examples.invoke-mistral-with-jinja', {'cmd': 'date'}) - ex = self._wait_for_completion(ex) - self.assertEqual(ex.status, action_constants.LIVEACTION_STATUS_SUCCEEDED) diff --git a/st2tests/integration/mistral/test_wiring_cancel.py b/st2tests/integration/mistral/test_wiring_cancel.py deleted file mode 100644 index 2096cd18ec..0000000000 --- a/st2tests/integration/mistral/test_wiring_cancel.py +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import os -import shutil -import tempfile - -from integration.mistral import base - -from st2common.constants import action as action_constants - - -class CancellationWiringTest(base.TestWorkflowExecution): - - temp_dir_path = None - - def setUp(self): - super(CancellationWiringTest, self).setUp() - - # Create temporary directory used by the tests - _, self.temp_dir_path = tempfile.mkstemp() - os.chmod(self.temp_dir_path, 0o755) # nosec - - def tearDown(self): - if self.temp_dir_path and os.path.exists(self.temp_dir_path): - if os.path.isdir(self.temp_dir_path): - shutil.rmtree(self.temp_dir_path) - else: - os.remove(self.temp_dir_path) - - def test_cancellation(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - ex = self._execute_workflow('examples.mistral-test-cancel', params) - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - - # Cancel the workflow before the temp file is created. The workflow will be paused - # but task1 will still be running to allow for graceful exit. - self.st2client.executions.delete(ex) - - # Expecting the ex to be canceling, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the ex to be canceled. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Task is completed successfully for graceful exit. - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_SUCCEEDED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_task_cancellation(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - ex = self._execute_workflow('examples.mistral-test-cancel', params) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - - # Cancel the task execution. - self.st2client.executions.delete(task_exs[0]) - - # Wait for the task and parent workflow to be canceled. - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_cascade_to_subworkflow_action(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-cancel-subworkflow-action' - ex = self._execute_workflow(action_ref, params) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - subwf_ex = task_exs[0] - - # Cancel the workflow before the temp file is created. The workflow will be canceled - # but task1 will still be running to allow for graceful exit. - self.st2client.executions.delete(ex) - - # Expecting the ex to be canceling, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELING) - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_cascade_to_subchain(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-cancel-subworkflow-chain' - ex = self._execute_workflow(action_ref, params) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - subwf_ex = task_exs[0] - - # Cancel the workflow before the temp file is created. The workflow will be canceled - # but task1 will still be running to allow for graceful exit. - self.st2client.executions.delete(ex) - - # Expecting the ex to be canceling, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELING) - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_cascade_from_subworkflow_action(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-cancel-subworkflow-action' - ex = self._execute_workflow(action_ref, params) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - subwf_ex = task_exs[0] - - # Cancel the subworkflow action. - self.st2client.executions.delete(subwf_ex) - - # Expecting task1 and main workflow ex to be canceling. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELING) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_cascade_from_subchain(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-cancel-subworkflow-chain' - ex = self._execute_workflow(action_ref, params) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - subwf_ex = task_exs[0] - - # Cancel the subworkflow action. - self.st2client.executions.delete(subwf_ex) - - # Expecting task1 and main workflow ex to be canceling. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELING) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_chain_cascade_to_subworkflow(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.chain-test-cancel-with-subworkflow' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Cancel the workflow before the temp file is created. The workflow will be canceled - # but task1 will still be running to allow for graceful exit. - self.st2client.executions.delete(ex) - - # Expecting the ex to be cancelinging, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELING) - - # Get the subworkflow ex. Since this is from an Action Chain, the task - # context is not available like task of Mistral workflows. Therefore, query - # for the children executions of the chain to get the task execution. - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 1) - subwf_ex = self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_CANCELING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) - - def test_cancellation_chain_cascade_from_subworkflow(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.chain-test-cancel-with-subworkflow' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Identify and cancel the task ex. - # Get the subworkflow ex. Since this is from an Action Chain, the task - # context is not available like task of Mistral workflows. Therefore, query - # for the children executions of the chain to get the task execution. - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 1) - subwf_ex = self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_RUNNING) - self.st2client.executions.delete(subwf_ex) - - # Expecting task1 and main workflow ex to be canceling. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELING) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be canceled. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_CANCELED) - - # Get the updated execution with task result. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_CANCELED) diff --git a/st2tests/integration/mistral/test_wiring_pause_resume.py b/st2tests/integration/mistral/test_wiring_pause_resume.py deleted file mode 100644 index b4827bc74e..0000000000 --- a/st2tests/integration/mistral/test_wiring_pause_resume.py +++ /dev/null @@ -1,273 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import os -import shutil -import tempfile - -from integration.mistral import base - -from st2common.constants import action as action_constants - - -class PauseResumeWiringTest(base.TestWorkflowExecution): - - temp_dir_path = None - - def setUp(self): - super(PauseResumeWiringTest, self).setUp() - - # Create temporary directory used by the tests - _, self.temp_dir_path = tempfile.mkstemp() - os.chmod(self.temp_dir_path, 0o755) # nosec - - def tearDown(self): - if self.temp_dir_path and os.path.exists(self.temp_dir_path): - if os.path.isdir(self.temp_dir_path): - shutil.rmtree(self.temp_dir_path) - else: - os.remove(self.temp_dir_path) - - def test_pause_resume(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - ex = self._execute_workflow('examples.mistral-test-pause-resume', params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - - # Pause the workflow before the temp file is created. The workflow will be paused - # but task1 will still be running to allow for graceful exit. - ex = self.st2client.executions.pause(ex.id) - - # Expecting the ex to be pausing, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the ex to be paused. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_resume_auto_pause(self): - # Launch the workflow. The workflow will pause automatically after the first task. - params = {'message': 'foobar'} - ex = self._execute_workflow('examples.mistral-test-pause-before-task', params) - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_SUCCEEDED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_resume_auto_pause_cascade_subworkflow_action(self): - # Launch the workflow. The workflow will pause automatically after the first task. - workflow = 'examples.mistral-test-pause-before-task-subworkflow-action' - params = {'message': 'foobar'} - ex = self._execute_workflow(workflow, params) - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_PAUSED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_resume_auto_pause_cascade_workbook_subworkflow(self): - # Launch the workflow. The workflow will pause automatically after the first task. - workflow = 'examples.mistral-test-pause-before-task-subworkflow-workbook' - params = {'message': 'foobar'} - ex = self._execute_workflow(workflow, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Ensure only task1 is executed and task2 is not present. - self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_SUCCEEDED) - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 1) - - # Resume the ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 3) - - def test_pause_resume_cascade_subworkflow_action(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-pause-resume-subworkflow-action' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - - # Pause the workflow before the temp file is created. The workflow will be paused - # but task1 will still be running to allow for graceful exit. - ex = self.st2client.executions.pause(ex.id) - - # Expecting the ex to be pausing, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSING) - subwf_ex = self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_PAUSING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be paused. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_PAUSED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the parent ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_pause_resume_cascade_workbook_subworkflow(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-pause-resume-subworkflow-workbook' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Get the task execution for the workbook subworkflow. - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 1) - self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_RUNNING) - - # Pause the main workflow before the temp file is created. - # The subworkflow will also pause. - ex = self.st2client.executions.pause(ex.id) - - # Expecting the ex to be pausing, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the main workflow to be paused. - self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_SUCCEEDED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the parent ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_pause_resume_cascade_to_subchain(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.mistral-test-pause-resume-subworkflow-chain' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - task_exs = self._wait_for_task(ex, 'task1', action_constants.LIVEACTION_STATUS_RUNNING) - - # Pause the workflow before the temp file is created. The workflow will be paused - # but task1 will still be running to allow for graceful exit. - ex = self.st2client.executions.pause(ex.id) - - # Expecting the ex to be pausing, waiting for task1 to be completed. - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSING) - subwf_ex = self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_PAUSING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be paused. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_PAUSED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the parent ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) - - def test_pause_resume_cascade_subworkflow_from_chain(self): - # A temp file is created during test setup. Ensure the temp file exists. - path = self.temp_dir_path - self.assertTrue(os.path.exists(path)) - - # Launch the workflow. The workflow will wait for the temp file to be deleted. - params = {'tempfile': path, 'message': 'foobar'} - action_ref = 'examples.chain-test-pause-resume-with-subworkflow' - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_RUNNING) - - # Get the execution for the subworkflow in the action chain. - task_exs = self._get_children(ex) - self.assertEqual(len(task_exs), 1) - subwf_ex = self._wait_for_state(task_exs[0], action_constants.LIVEACTION_STATUS_RUNNING) - - # Pause the workflow before the temp file is created. The workflow will be paused - # but task1 will still be running to allow for graceful exit. - ex = self.st2client.executions.pause(ex.id) - - # Expecting the ex to be pausing, waiting for task1 to be completed. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_PAUSING) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSING) - - # Delete the temporary file. - os.remove(path) - self.assertFalse(os.path.exists(path)) - - # Wait for the exs to be paused. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_PAUSED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_PAUSED) - - # Resume the parent ex. - ex = self.st2client.executions.resume(ex.id) - - # Wait for completion. - subwf_ex = self._wait_for_state(subwf_ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(len(ex.result.get('tasks', [])), 2) diff --git a/st2tests/integration/mistral/test_wiring_rerun.py b/st2tests/integration/mistral/test_wiring_rerun.py deleted file mode 100644 index 0fb8934376..0000000000 --- a/st2tests/integration/mistral/test_wiring_rerun.py +++ /dev/null @@ -1,215 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import absolute_import -import os -import shutil -import tempfile - -from integration.mistral import base - -from st2common.constants import action as action_constants - - -class RerunWiringTest(base.TestWorkflowExecution): - - temp_dir_path = None - - def setUp(self): - super(RerunWiringTest, self).setUp() - - # Create temporary directory used by the tests - _, self.temp_dir_path = tempfile.mkstemp() - os.chmod(self.temp_dir_path, 0o755) # nosec - - def tearDown(self): - if self.temp_dir_path and os.path.exists(self.temp_dir_path): - if os.path.isdir(self.temp_dir_path): - shutil.rmtree(self.temp_dir_path) - else: - os.remove(self.temp_dir_path) - - def test_rerun(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - params = {'tempfile': path} - ex = self._execute_workflow('examples.mistral-test-rerun', params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertNotEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_rerun_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - params = {'tempfile': path} - ex = self._execute_workflow('examples.mistral-test-rerun', params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1']) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_rerun_subflow_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - action_ref = 'examples.mistral-test-rerun-subflow' - params = {'tempfile': path} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1.task1']) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - def test_rerun_and_reset_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - action_ref = 'examples.mistral-test-rerun-with-items' - params = {'tempfile': path} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1']) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 4) - - def test_rerun_and_resume_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - action_ref = 'examples.mistral-test-rerun-with-items' - params = {'tempfile': path} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run( - orig_st2_ex_id, - tasks=['task1'], - no_reset=['task1'] - ) - - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 2) - - def test_rerun_subflow_and_reset_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - action_ref = 'examples.mistral-test-rerun-subflow-with-items' - params = {'tempfile': path} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1.task1']) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 4) - - def test_rerun_subflow_and_resume_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - action_ref = 'examples.mistral-test-rerun-subflow-with-items' - params = {'tempfile': path} - ex = self._execute_workflow(action_ref, params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['mistral']['execution_id'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run( - orig_st2_ex_id, - tasks=['task1.task1'], - no_reset=['task1.task1'] - ) - - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['mistral']['execution_id'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 2) diff --git a/st2tests/st2tests/config.py b/st2tests/st2tests/config.py index 169af5117a..5103f2a66e 100644 --- a/st2tests/st2tests/config.py +++ b/st2tests/st2tests/config.py @@ -88,7 +88,6 @@ def _override_common_opts(): CONF.set_override(name='packs_base_paths', override=packs_base_path, group='content') CONF.set_override(name='api_url', override='http://127.0.0.1', group='auth') CONF.set_override(name='mask_secrets', override=True, group='log') - CONF.set_override(name='jitter_interval', override=0, group='mistral') CONF.set_override(name='query_interval', override=0.1, group='resultstracker') CONF.set_override(name='stream_output', override=False, group='actionrunner') diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.api.audit_log_level.conf b/st2tests/st2tests/fixtures/conf/st2.tests.api.audit_log_level.conf index dbe36c36db..feb8afd095 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.api.audit_log_level.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.api.audit_log_level.conf @@ -95,5 +95,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.api.debug_log_level.conf b/st2tests/st2tests/fixtures/conf/st2.tests.api.debug_log_level.conf index caad395240..06e5eb0561 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.api.debug_log_level.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.api.debug_log_level.conf @@ -95,5 +95,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.api.info_log_level.conf b/st2tests/st2tests/fixtures/conf/st2.tests.api.info_log_level.conf index 5cd4e6cd33..dd72dfd1b6 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.api.info_log_level.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.api.info_log_level.conf @@ -95,5 +95,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true.conf b/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true.conf index 3317c11abf..7fa1f26e40 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true.conf @@ -95,5 +95,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true_logging_debug.conf b/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true_logging_debug.conf index 736b62e81c..8172c6650a 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true_logging_debug.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.api.system_debug_true_logging_debug.conf @@ -95,5 +95,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/conf/st2.tests.conf b/st2tests/st2tests/fixtures/conf/st2.tests.conf index bb97039f03..694cfb082c 100644 --- a/st2tests/st2tests/fixtures/conf/st2.tests.conf +++ b/st2tests/st2tests/fixtures/conf/st2.tests.conf @@ -96,5 +96,3 @@ logging = st2actions/conf/logging.notifier.conf [exporter] logging = st2exporter/conf/logging.exporter.conf -[mistral] -jitter_interval = 0 diff --git a/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml b/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml deleted file mode 100644 index acb0e19e9d..0000000000 --- a/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -action: foo.mistral.wf1 -callback: {} -context: - user: system -end_timestamp: '2014-09-01T00:00:05.000000Z' -parameters: {} -result: {} -start_timestamp: '2014-09-01T00:00:01.000000Z' -status: requested diff --git a/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_syntax.yaml b/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_syntax.yaml deleted file mode 100644 index 5eb73b31a4..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_syntax.yaml +++ /dev/null @@ -1,72 +0,0 @@ -version: "2.0" -name: "examples.mistral-complex" - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - create_vm: - workflow: create_vm - input: - name: <% $.vm_name %> - publish: - vm_id: <% $.vm_id %> - on-success: - - reconfig_vm - reconfig_vm: - workflow: reconfig_vm - input: - vm_id: <% $.vm_id %> - cpu_cores: <% $.cpu_cores %> - memory_mb: <% $.memory_mb %> - on-success: - - power_on_vm - power_on_vm: - action: core.local - input: - cmd: "sleep 2; printf 'running'" - publish: - vm_state: <% task(power_on_vm).result.stdout %> - - create_vm: - type: direct - input: - - name - output: - vm_id: <% $.vm_id %> - task-defaults: - on-error: - - fail - tasks: - create: - action: core.local - input: - cmd: "sleep 3; printf 'vm1234'" - publish: - vm_id: <% task(create).result.stdout %> - - reconfig_vm: - type: direct - input: - - vm_id - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - add_disk: - action: core.local - input: - cmd: "sleep 1; printf '<% $.vm_id %>'" - edit_cpu_mem: - action: core.local - input: - cmd: "sleep 1; printf '{\"vm_id\": \"<% $.vm_id %>\", \"cpu\": <% $.cpu_cores %>, \"memory\": <% $.memory_mb %>}'" diff --git a/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_yaql.yaml b/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_yaql.yaml deleted file mode 100644 index cec58f73b6..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wb_invalid_yaql.yaml +++ /dev/null @@ -1,73 +0,0 @@ -version: "2.0" -name: "examples.mistral-complex" - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - create_vm: - workflow: create_vm - input: - name: <% $.vm_name.keys( %> - publish: - vm_id: <% $.vm_id %> - on-success: - - reconfig_vm - reconfig_vm: - workflow: reconfig_vm - input: - vm_id: <% $.vm_id %> - cpu_cores: <% $.cpu_cores %> - memory_mb: <% $.memory_mb %> - on-success: - - power_on_vm - power_on_vm: - action: core.local - input: - cmd: "sleep 2; printf 'running'" - publish: - vm_state: <% task(power_on_vm).result.stdout %> - - create_vm: - type: direct - input: - - name - output: - vm_id: <% $.vm_id %> - task-defaults: - on-error: - - fail - tasks: - create: - action: core.local - input: - cmd: "sleep 3; printf 'vm1234'" - publish: - vm_id: <% task(create).result.stdout %> - - reconfig_vm: - type: direct - input: - - vm_id - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - add_disk: - action: core.local - input: - cmd: "sleep 1; printf '<% $.vm_id %>'" - edit_cpu_mem: - action: core.local - input: - cmd: "sleep 1; printf '{\"vm_id\": \"<% $.vm_id %>\", \"cpu\": <% $.cpu_cores %>, \"memory\": <% $.memory_mb %>}'" diff --git a/st2tests/st2tests/fixtures/generic/workflows/wb_post_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wb_post_xform.yaml deleted file mode 100644 index fc7bd9b112..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wb_post_xform.yaml +++ /dev/null @@ -1,81 +0,0 @@ -version: "2.0" -name: "examples.mistral-complex" - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - create_vm: - workflow: create_vm - input: - name: <% $.vm_name %> - publish: - vm_id: <% $.vm_id %> - on-success: - - reconfig_vm - reconfig_vm: - workflow: reconfig_vm - input: - vm_id: <% $.vm_id %> - cpu_cores: <% $.cpu_cores %> - memory_mb: <% $.memory_mb %> - on-success: - - power_on_vm - power_on_vm: - action: st2.action - input: - ref: core.local - parameters: - cmd: "sleep 2; printf 'running'" - publish: - vm_state: <% task(power_on_vm).result.stdout %> - - create_vm: - type: direct - input: - - name - output: - vm_id: <% $.vm_id %> - task-defaults: - on-error: - - fail - tasks: - create: - action: st2.action - input: - ref: core.local - parameters: - cmd: "sleep 3; printf 'vm1234'" - publish: - vm_id: <% task(create).result.stdout %> - - reconfig_vm: - type: direct - input: - - vm_id - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - add_disk: - action: st2.action - input: - ref: core.local - parameters: - cmd: "sleep 1; printf '<% $.vm_id %>'" - edit_cpu_mem: - action: st2.action - input: - ref: core.local - parameters: - cmd: "sleep 1; printf '{\"vm_id\": \"<% $.vm_id %>\", \"cpu\": <% $.cpu_cores %>, \"memory\": <% $.memory_mb %>}'" diff --git a/st2tests/st2tests/fixtures/generic/workflows/wb_pre_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wb_pre_xform.yaml deleted file mode 100644 index 8c174676b3..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wb_pre_xform.yaml +++ /dev/null @@ -1,73 +0,0 @@ -version: "2.0" -name: "examples.mistral-complex" - -workflows: - - main: - type: direct - input: - - vm_name - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - create_vm: - workflow: create_vm - input: - name: <% $.vm_name %> - publish: - vm_id: <% $.vm_id %> - on-success: - - reconfig_vm - reconfig_vm: - workflow: reconfig_vm - input: - vm_id: <% $.vm_id %> - cpu_cores: <% $.cpu_cores %> - memory_mb: <% $.memory_mb %> - on-success: - - power_on_vm - power_on_vm: - action: core.local - input: - cmd: "sleep 2; printf 'running'" - publish: - vm_state: <% task(power_on_vm).result.stdout %> - - create_vm: - type: direct - input: - - name - output: - vm_id: <% $.vm_id %> - task-defaults: - on-error: - - fail - tasks: - create: - action: core.local - input: - cmd: "sleep 3; printf 'vm1234'" - publish: - vm_id: <% task(create).result.stdout %> - - reconfig_vm: - type: direct - input: - - vm_id - - cpu_cores - - memory_mb - task-defaults: - on-error: - - fail - tasks: - add_disk: - action: core.local - input: - cmd: "sleep 1; printf '<% $.vm_id %>'" - edit_cpu_mem: - action: core.local - input: - cmd: "sleep 1; printf '{\"vm_id\": \"<% $.vm_id %>\", \"cpu\": <% $.cpu_cores %>, \"memory\": <% $.memory_mb %>}'" diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_post_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_post_xform.yaml deleted file mode 100644 index a2af2a31b3..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_post_xform.yaml +++ /dev/null @@ -1,49 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: st2.action - input: - ref: wolfpack.a1 - task_with_inputs: - action: st2.action - input: - ref: wolfpack.a2 - parameters: - strtype: '{% raw %}{{ st2kv.system.var1 }}{% endraw %}' - inttype: '{{ foobarst2kv.system.var2 }}' - arrtype: - - foobar - - <% $.var1 %> - - '{{ _.var2 }}' - - '{% raw %}{{ st2kv.system.var3 }}{% endraw %}' - - '{% raw %}{{st2kv.system.var3}}{% endraw %}' - - '{% raw %}{{ abc and st2kv.system.var3 }}{% endraw %}' - - '{{ foobarst2kv.system.var4 }}' - - '{{foobarst2kv.system.var4}}' - - '{{ st2kv(var1) }}' - objtype: - var11: fubar - var12: <% $.var1 + $.var2 %> - var13: '{{ _.var1 + _.var2 }}' - var14: '{% raw %}{{ st2kv.system.var5 }}{% endraw %}' - var15: '{% raw %}{{st2kv.system.var5}}{% endraw %}' - var16: '{% raw %}{{ abc and st2kv.system.var5 }}{% endraw %}' - var17: '{{ foobarst2kv.system.var6 }}' - var18: '{{foobarst2kv.system.var6}}' - var19: '{{ st2kv(var1) }}' - publish: - var21: <% $.var21 %> - var22: <% $.var22 %> - task_with_inline_inputs: - action: st2.action - input: - ref: wolfpack.a2 - parameters: - strtype: some <% $.var1 %> string - inttype: <% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_pre_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_pre_xform.yaml deleted file mode 100644 index 4bd17a720f..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_has_jinja_st2kv_pre_xform.yaml +++ /dev/null @@ -1,40 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: '{{ st2kv.system.var1 }}' - inttype: '{{ foobarst2kv.system.var2 }}' - arrtype: - - foobar - - <% $.var1 %> - - '{{ _.var2 }}' - - '{{ st2kv.system.var3 }}' - - '{{st2kv.system.var3}}' - - '{{ abc and st2kv.system.var3 }}' - - '{{ foobarst2kv.system.var4 }}' - - '{{foobarst2kv.system.var4}}' - - '{{ st2kv(var1) }}' - objtype: - var11: fubar - var12: <% $.var1 + $.var2 %> - var13: '{{ _.var1 + _.var2 }}' - var14: '{{ st2kv.system.var5 }}' - var15: '{{st2kv.system.var5}}' - var16: '{{ abc and st2kv.system.var5 }}' - var17: '{{ foobarst2kv.system.var6 }}' - var18: '{{foobarst2kv.system.var6}}' - var19: '{{ st2kv(var1) }}' - publish: - var21: <% $.var21 %> - var22: <% $.var22 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_has_unexpected_param.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_has_unexpected_param.yaml deleted file mode 100644 index b37cfb396d..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_has_unexpected_param.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task1: - action: wolfpack.action-1 - input: - actionstr: <% $.var1 %> - foo: <% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_syntax.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_syntax.yaml deleted file mode 100644 index 3f04e8e33b..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_syntax.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: <% $.var1 %> - inttype: <% $.var2 %> - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_yaql.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_yaql.yaml deleted file mode 100644 index 02dc5b7055..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_invalid_yaql.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: <% $.var1.keys( %> - inttype: <% $.var2 %> - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref1.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref1.yaml deleted file mode 100644 index eab9e8c0a7..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref1.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: '{{ st2kv.system.var1a }} and {{ _.var1b }}' - inttype: '{{ st2kv.user.var2 }}' - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref2.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref2.yaml deleted file mode 100644 index 79d0a98b77..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_jinja_mixed_context_ref2.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: '{{ st2kv.system.var1 }}' - inttype: '{{ st2kv.user.var2a + _.var2b }}' - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_missing_required_param.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_missing_required_param.yaml deleted file mode 100644 index 4d67d5d0d2..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_missing_required_param.yaml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task1: - action: wolfpack.action-1 - input: - inttype: <% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_post_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_post_xform.yaml deleted file mode 100644 index 1c4953b1ba..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_post_xform.yaml +++ /dev/null @@ -1,29 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: st2.action - input: - ref: wolfpack.a1 - task_with_inputs: - action: st2.action - input: - ref: wolfpack.a2 - parameters: - strtype: <% $.var1 %> - inttype: <% $.var2 %> - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: st2.action - input: - ref: wolfpack.a2 - parameters: - strtype: some <% $.var1 %> string - inttype: <% $.var2 %> diff --git a/st2tests/st2tests/fixtures/generic/workflows/wf_pre_xform.yaml b/st2tests/st2tests/fixtures/generic/workflows/wf_pre_xform.yaml deleted file mode 100644 index 12c5554dac..0000000000 --- a/st2tests/st2tests/fixtures/generic/workflows/wf_pre_xform.yaml +++ /dev/null @@ -1,20 +0,0 @@ -version: '2.0' - -demo: - type: direct - input: - - var1 - - var2 - tasks: - task_with_no_input: - action: wolfpack.a1 - task_with_inputs: - action: wolfpack.a2 - input: - strtype: <% $.var1 %> - inttype: <% $.var2 %> - publish: - var3: <% $.var3 %> - var4: <% $.var4 %> - task_with_inline_inputs: - action: wolfpack.a2 strtype="some <% $.var1 %> string" inttype=<% $.var2 %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2.yaml deleted file mode 100644 index 223883c021..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workbook_v2.yaml -name: workbook_v2 -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_call_workflow_action.yaml deleted file mode 100644 index cc28341eca..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_call_workflow_action.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: workbook_v2_call_workflow_action -pack: mistral_tests -description: Say hi to friend! -enabled: true -runner_type: mistral-v2 -entry_point: workflows/workbook_v2_call_workflow_action.yaml -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows.yaml deleted file mode 100644 index 915987f198..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows.yaml +++ /dev/null @@ -1,17 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workbook_v2_many_workflows.yaml -name: workbook_v2_many_workflows -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string - workflow: - default: generic.workbook_v2_many_workflows.main - immutable: true -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows_no_default.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows_no_default.yaml deleted file mode 100644 index a1fc91bd90..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_many_workflows_no_default.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workbook_v2_many_workflows_no_default.yaml -name: workbook_v2_many_workflows_no_default -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_name_mismatch.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_name_mismatch.yaml deleted file mode 100644 index b21856e6ca..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workbook_v2_name_mismatch.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workbook_v2.yaml -name: workbook_v2_name_mismatch -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2.yaml deleted file mode 100644 index 245213848f..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workflow_v2.yaml -name: workflow_v2 -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_call_workflow_action.yaml deleted file mode 100644 index bc4b749321..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_call_workflow_action.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: workflow_v2_call_workflow_action -pack: mistral_tests -description: Say hi to friend! -enabled: true -runner_type: mistral-v2 -entry_point: workflows/workflow_v2_call_workflow_action.yaml -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_many_workflows.yaml deleted file mode 100644 index 3eca03d3bd..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_many_workflows.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workflow_v2_many_workflows.yaml -name: workflow_v2_many_workflows -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_name_mismatch.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_name_mismatch.yaml deleted file mode 100644 index a3df8899d1..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_name_mismatch.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workflow_v2.yaml -name: workflow_v2_name_mismatch -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string -runner_type: mistral-v2 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_reverse.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_reverse.yaml deleted file mode 100644 index 6fbf820ecf..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflow_v2_reverse.yaml +++ /dev/null @@ -1,19 +0,0 @@ ---- -description: Say hi to friend! -enabled: true -entry_point: workflows/workflow_v2_reverse.yaml -name: workflow_v2_reverse -pack: mistral_tests -parameters: - count: - default: '3' - type: string - friend: - required: true - type: string - task_name: - immutable: true - default: say-friend - type: string -runner_type: mistral-v2 - diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2.yaml deleted file mode 100644 index f2febda69b..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: 'mistral_tests.workbook_v2' -version: '2.0' - -workflows: - - workflow-v2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_call_workflow_action.yaml deleted file mode 100644 index 56e5f1f351..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_call_workflow_action.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: 'mistral_tests.workbook_v2_call_workflow_action' -version: '2.0' - -workflows: - - main: - type: direct - input: - - count - - friend - tasks: - task1: - action: mistral_tests.workflow_v2 - input: - count: <% $.count %> - friend: <% $.friend %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows.yaml deleted file mode 100644 index 2e04ed0cb6..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows.yaml +++ /dev/null @@ -1,38 +0,0 @@ -name: 'mistral_tests.workbook_v2_many_workflows' -version: '2.0' - -workflows: - - main: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - subflow1: - type: direct - input: - - count - - friend - output: - towhom: <% $.towhom %> - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows_no_default.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows_no_default.yaml deleted file mode 100644 index a5fd4802b9..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workbook_v2_many_workflows_no_default.yaml +++ /dev/null @@ -1,49 +0,0 @@ -name: 'mistral_tests.workbook_v2_many_workflows_no_default' -version: '2.0' - -workflows: - - main1: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - main2: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - subflow1: - type: direct - input: - - count - - friend - output: - towhom: <% $.towhom %> - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2.yaml deleted file mode 100644 index 3e5bbe8255..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2.yaml +++ /dev/null @@ -1,22 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_call_workflow_action.yaml deleted file mode 100644 index ffec31e9d6..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_call_workflow_action.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_call_workflow_action: - type: direct - input: - - count - - friend - tasks: - task1: - action: mistral_tests.workflow_v2 - input: - count: <% $.count %> - friend: <% $.friend %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_many_workflows.yaml deleted file mode 100644 index 27cc651ada..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_many_workflows.yaml +++ /dev/null @@ -1,43 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_many_workflows.main1: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> - -mistral_tests.workflow_v2_many_workflows.main2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_reverse.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_reverse.yaml deleted file mode 100644 index 53f325b48b..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/workflow_v2_reverse.yaml +++ /dev/null @@ -1,21 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_reverse: - type: reverse - input: - - count - - friend - tasks: - say-greeting: - action: core.local - input: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - say-friend: - requires: [say-greeting] - action: core.local - input: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2.yaml deleted file mode 100644 index 8f6c955ed3..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: 'mistral_tests.workbook_v2' -version: '2.0' - -workflows: - - workflow-v2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_call_workflow_action.yaml deleted file mode 100644 index 112782ecc7..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_call_workflow_action.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: 'mistral_tests.workbook_v2_call_workflow_action' -version: '2.0' - -workflows: - - main: - type: direct - input: - - count - - friend - tasks: - task1: - action: st2.action - input: - ref: mistral_tests.workflow_v2 - parameters: - count: <% $.count %> - friend: <% $.friend %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows.yaml deleted file mode 100644 index 0fdace7c18..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: 'mistral_tests.workbook_v2_many_workflows' -version: '2.0' - -workflows: - - main: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - subflow1: - type: direct - input: - - count - - friend - output: - towhom: <% $.towhom %> - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows_no_default.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows_no_default.yaml deleted file mode 100644 index 2e576516fa..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workbook_v2_many_workflows_no_default.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: 'mistral_tests.workbook_v2_many_workflows_no_default' -version: '2.0' - -workflows: - - main1: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - main2: - type: direct - input: - - count - - friend - tasks: - greet: - workflow: subflow1 count=<% $.count %> friend=<% $.friend %> - publish: - towhom: <% task(greet).result.towhom %> - - subflow1: - type: direct - input: - - count - - friend - output: - towhom: <% $.towhom %> - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2.yaml deleted file mode 100644 index c1a2fd0660..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2.yaml +++ /dev/null @@ -1,26 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_call_workflow_action.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_call_workflow_action.yaml deleted file mode 100644 index ccf4c03388..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_call_workflow_action.yaml +++ /dev/null @@ -1,15 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_call_workflow_action: - type: direct - input: - - count - - friend - tasks: - task1: - action: st2.action - input: - ref: mistral_tests.workflow_v2 - parameters: - count: <% $.count %> - friend: <% $.friend %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_many_workflows.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_many_workflows.yaml deleted file mode 100644 index 87c8921843..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_many_workflows.yaml +++ /dev/null @@ -1,51 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_many_workflows.main1: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> - -mistral_tests.workflow_v2_many_workflows.main2: - type: direct - input: - - count - - friend - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - on-success: - - say-friend - say-friend: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_reverse.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_reverse.yaml deleted file mode 100644 index a9a63eb6af..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/actions/workflows/xformed_workflow_v2_reverse.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: '2.0' - -mistral_tests.workflow_v2_reverse: - type: reverse - input: - - count - - friend - tasks: - say-greeting: - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.count %> - publish: - greet: <% task(say-greeting).result.stdout %> - say-friend: - requires: [say-greeting] - action: st2.action - input: - ref: core.local - parameters: - cmd: <% $.friend %> - publish: - towhom: <% task(say-friend).result.stdout %> diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/pack.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/pack.yaml deleted file mode 100644 index 6bbc5e04e5..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/pack.yaml +++ /dev/null @@ -1,6 +0,0 @@ ---- -name : mistral_tests -description : Content pack for mistral tests -version : 0.1.0 -author : st2-dev -email : info@stackstorm.com diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency.yaml deleted file mode 100644 index 3ab80939c0..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -name: cancel_on_concurrency -pack: mistral_tests -description: Cancels the execution when the concurrent threshold is reached -enabled: true -resource_ref: mistral_tests.workflow_v2 -policy_type: action.concurrency -parameters: - action: cancel - threshold: 3 diff --git a/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency_by_attr.yaml b/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency_by_attr.yaml deleted file mode 100644 index 5428bcc033..0000000000 --- a/st2tests/st2tests/fixtures/packs/mistral_tests/policies/cancel_on_concurrency_by_attr.yaml +++ /dev/null @@ -1,12 +0,0 @@ ---- -name: cancel_on_concurrency_by_attr -pack: mistral_tests -description: Cancels the execution when the concurrent threshold is reached -enabled: true -resource_ref: mistral_tests.workflow_v2 -policy_type: action.concurrency.attr -parameters: - action: cancel - threshold: 1 - attributes: - - friend diff --git a/tools/db_cleanup.sh b/tools/db_cleanup.sh index c46269e2d5..385cc2177c 100755 --- a/tools/db_cleanup.sh +++ b/tools/db_cleanup.sh @@ -6,16 +6,5 @@ ROOT_PASSWORD=${MYSQL_PASSWORD:StackStorm} echo "Cleaning MongoDB Database..." mongo st2 --eval "db.dropDatabase();" -echo "Cleaning Mistral Database..." -SQL_QUERY="DROP DATABASE IF EXISTS mistral; \ - CREATE DATABASE mistral; \ - GRANT ALL PRIVILEGES ON mistral.* TO 'mistral'@'127.0.0.1' IDENTIFIED BY '$ROOT_PASSWORD'; \ - FLUSH PRIVILEGES;" - -mysql -uroot -p$ROOT_PASSWORD -e $SQL_QUERY - -cd /opt/openstack/mistral -python ./tools/sync_db.py --config-file /etc/mistral/mistral.conf - echo "Re-initializing DBs..." st2ctl reload diff --git a/tools/launchdev.sh b/tools/launchdev.sh index ad2e5d9dec..ac3471ca8f 100755 --- a/tools/launchdev.sh +++ b/tools/launchdev.sh @@ -12,7 +12,6 @@ use_gunicorn=true copy_test_packs=false load_content=true use_ipv6=false -include_mistral=false while getopts ":r:s:w:gxcu6m" o; do case "${o}" in @@ -37,9 +36,6 @@ while getopts ":r:s:w:gxcu6m" o; do 6) use_ipv6=true ;; - m) - include_mistral=true - ;; \?) echo "Invalid option: -$OPTARG" >&2 usage @@ -87,66 +83,6 @@ function init(){ exit 1 fi - # Optionally, initialize mistral - if [ "${include_mistral}" = true ]; then - init_mistral - fi -} - -function init_mistral(){ - - echo "Initializing Mistral..." - - # Both the mistral and st2mistral repos must be present alongside the st2 repo - MISTRAL_REPO="${ST2_REPO}/../mistral" - ST2MISTRAL_REPO="${ST2_REPO}/../st2mistral" - - if [ ! -d "$MISTRAL_REPO" ] || [ ! -d "$ST2MISTRAL_REPO" ] ; then - echo "You specified the Mistral option, but either the mistral or st2mistral directories were not found." - echo "Please place a clone of both mistral and st2mistral repositories alongside the st2 repository." - exit 1 - fi - - if [ -z "$MISTRAL_CONF" ]; then - MISTRAL_CONF=${ST2_REPO}/conf/mistral.dev/mistral.dev.conf - fi - echo "Using mistral config file: $MISTRAL_CONF" - - if [ ! -f "$MISTRAL_CONF" ]; then - echo "Config file $MISTRAL_CONF does not exist." - exit 1 - fi - - # Create mistral virtualenv if doesn't exist - if [[ ! -d "${MISTRAL_REPO}/.venv" ]]; then - virtualenv ${MISTRAL_REPO}/.venv > /dev/null - fi - - # Install Mistral and st2 plugins - echo "Installing mistral, st2mistral, and all dependencies..." - source "${MISTRAL_REPO}/.venv/bin/activate" - cd "${MISTRAL_REPO}" - - # There's something funky going on with installation of Babel in mistral/requirements.txt - # I noticed that the install script in mistral_dev is doing some replacements for Babel to set - # the version but installation of Babel still fails for me even with that code. Only - # thing I've managed to get working is manually installing pytz myself here. - pip install pytz - - pip install -r requirements.txt > /dev/null - python setup.py install > /dev/null - cd "${ST2MISTRAL_REPO}" - pip install -r requirements.txt > /dev/null - python setup.py install > /dev/null - deactivate - - MISTRAL_DB_COUNT=$(PGUSER=mistral PGPASSWORD=StackStorm PGDATABASE=mistral PGHOST=127.0.0.1 PGPORT=5432 psql mistral -c "select count(*) from action_definitions_v2" | grep -oP '\d{4}') - if [ ! $? -eq 0 ]; then - MISTRAL_DB_COUNT=0 - fi - if [ "$MISTRAL_DB_COUNT" -lt 1200 ] ; then - setup_mistral_db - fi } function exportsdir(){ @@ -239,12 +175,6 @@ function st2start(){ screen -ls | grep st2 | cut -d. -f1 | awk '{print $1}' | xargs kill fi - screen -ls | grep mistral &> /dev/null - if [ $? == 0 ]; then - echo 'Killing existing mistral screen sessions...' - screen -ls | grep mistral | cut -d. -f1 | awk '{print $1}' | xargs kill - fi - # NOTE: We can't rely on latest version of screen with "-Logfile path" # option so we need to use screen config file per screen window @@ -372,26 +302,6 @@ function st2start(){ --config-file $ST2_CONF fi - if [ "${include_mistral}" = true ]; then - LOGDIR=${ST2_REPO}/logs - - # Run mistral-server - echo 'Starting screen session mistral-server...' - screen -L -Logfile logs/screen-mistral-server.log -d -m -S mistral-server ${MISTRAL_REPO}/.venv/bin/python \ - ${MISTRAL_REPO}/.venv/bin/mistral-server \ - --server engine,executor \ - --config-file $MISTRAL_CONF \ - --log-file "$LOGDIR/mistral-server.log" - - # Run mistral-api - echo 'Starting screen session mistral-api...' - screen -L -Logfile logs/screen-mistral-server.log -d -m -S mistral-api ${MISTRAL_REPO}/.venv/bin/python \ - ${MISTRAL_REPO}/.venv/bin/mistral-server \ - --server api \ - --config-file $MISTRAL_CONF \ - --log-file "$LOGDIR/mistral-api.log" - fi - # Check whether screen sessions are started SCREENS=( "st2-api" @@ -407,11 +317,6 @@ function st2start(){ "st2-garbagecollector" ) - if [ "${include_mistral}" = true ]; then - SCREENS+=("mistral-server") - SCREENS+=("mistral-api") - fi - echo for s in "${SCREENS[@]}" do @@ -447,12 +352,6 @@ function st2stop(){ screen -ls | grep st2 | cut -d. -f1 | awk '{print $1}' | xargs -L 1 pkill -P fi - screen -ls | grep mistral &> /dev/null - if [ $? == 0 ]; then - echo 'Killing existing mistral screen sessions...' - screen -ls | grep mistral | cut -d. -f1 | awk '{print $1}' | xargs -L 1 pkill -9 -P - fi - if [ "${use_gunicorn}" = true ]; then pids=`ps -ef | grep "wsgi:application" | awk '{print $2}'` if [ -n "$pids" ]; then @@ -484,29 +383,8 @@ function st2clean(){ rm -rf ${EXPORTS_DIR} fi - setup_mistral_db } -function setup_mistral_db(){ - # Ensure services are stopped, so DB script will work - st2stop - - if [ -f /etc/lsb-release ]; then - DISTRO="ubuntu" - else - DISTRO="fedora" - fi - - ${ST2_REPO}/tools/setup_mistral_db.sh \ - "${MISTRAL_REPO}" \ - "${MISTRAL_CONF}" \ - "${DISTRO}" \ - postgresql \ - mistral \ - mistral \ - StackStorm \ - StackStorm -} case ${subcommand} in start) diff --git a/tools/setup_mistral_db.sh b/tools/setup_mistral_db.sh deleted file mode 100755 index 8ef668d614..0000000000 --- a/tools/setup_mistral_db.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/bash -set -e - -# This script lovingly "borrowed" from https://github.com/StackStorm/mistral_dev/blob/master/actions/setup_db.sh - -MISTRAL_PATH=$1 -MISTRAL_CONFIG=$2 -DISTRO=$3 -DB_TYPE=$4 -DB_NAME=$5 -DB_USER_NAME=$6 -DB_USER_PASS=$7 -DB_ROOT_PASS=$8 - -if [[ ! -e "${MISTRAL_CONFIG}" ]]; then - >&2 echo "ERROR: ${MISTRAL_CONFIG} does not exist." - exit 1 -fi - -if [[ ! -d "${MISTRAL_PATH}" ]]; then - >&2 echo "ERROR: ${MISTRAL_PATH} does not exist." - exit 1 -fi - -if [[ ! -d "${MISTRAL_PATH}/.venv" ]]; then - >&2 echo "ERROR: ${MISTRAL_PATH}/.venv does not exist." - exit 1 -fi - -if [[ "${DISTRO}" != "ubuntu" && "${DISTRO}" != "fedora" ]]; then - >&2 echo "ERROR: ${DISTRO} is an unsupported Linux distribution." - exit 1 -fi - -if [[ "${DB_TYPE}" != "postgresql" && "${DB_TYPE}" != "mysql" ]]; then - >&2 echo "ERROR: ${DB_TYPE} is an unsupported database type." - exit 1 -fi - -echo "Setup database in ${DB_TYPE} on ${DISTRO}..." - -# Create the database and user. Restart DB server first in case of active user sessions. -if [ "${DB_TYPE}" == "mysql" ]; then - sudo service mysql restart - mysql -uroot -p${DB_ROOT_PASS} -e "DROP DATABASE IF EXISTS ${DB_NAME}" - mysql -uroot -p${DB_ROOT_PASS} -e "CREATE DATABASE ${DB_NAME}" - mysql -uroot -p${DB_ROOT_PASS} -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER_NAME}'@'%' IDENTIFIED BY '${DB_USER_PASS}'" - mysql -uroot -p${DB_ROOT_PASS} -e "FLUSH PRIVILEGES" -elif [ "${DB_TYPE}" == "postgresql" ]; then - sudo service postgresql restart - sudo -u postgres psql -c "DROP DATABASE IF EXISTS ${DB_NAME};" - sudo -u postgres psql -c "DROP USER IF EXISTS ${DB_USER_NAME};" - sudo -u postgres psql -c "CREATE USER ${DB_USER_NAME} WITH ENCRYPTED PASSWORD '${DB_USER_PASS}';" - sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER_NAME};" -fi - -# Install requirements for the client lib. -if [[ "${DISTRO}" == "ubuntu" && "${DB_TYPE}" == "postgresql" ]]; then - echo "Installing requirement libpg-dev..." - sudo apt-get install -y libpq-dev -elif [[ "${DISTRO}" == "fedora" && "${DB_TYPE}" == "postgresql" ]]; then - echo "Installing requirement postgresql-devel..." - sudo yum install -y postgresql-devel -elif [[ "${DISTRO}" == "ubuntu" && "${DB_TYPE}" == "mysql" ]]; then - echo "Installing requirement libmysqlclient-dev..." - sudo apt-get install -y libmysqlclient-dev -elif [[ "${DISTRO}" == "fedora" && "${DB_TYPE}" == "mysql" ]]; then - echo "Installing requirement mysql-devel..." - sudo yum install -y mysql-devel -fi - -# Install the client lib. -echo "Installing client lib for ${DB_TYPE}..." -. ${MISTRAL_PATH}/.venv/bin/activate - -if [ "${DB_TYPE}" == "mysql" ]; then - pip install -q mysql-python -elif [ "${DB_TYPE}" == "postgresql" ]; then - pip install -q psycopg2 -fi - -deactivate - -echo "Creating tables..." -${MISTRAL_PATH}/.venv/bin/mistral-db-manage --config-file ${MISTRAL_CONFIG} upgrade head > /dev/null -echo "Populating tables..." -${MISTRAL_PATH}/.venv/bin/mistral-db-manage --config-file ${MISTRAL_CONFIG} populate > /dev/null -echo "========================" -echo "Database setup complete." -echo "========================" \ No newline at end of file diff --git a/tools/submit-per-service-metrics-to-statsd b/tools/submit-per-service-metrics-to-statsd index d35e2b6cc7..7765d1ed22 100755 --- a/tools/submit-per-service-metrics-to-statsd +++ b/tools/submit-per-service-metrics-to-statsd @@ -79,15 +79,10 @@ def get_name_for_stackstorm_service(pinfo): name = 'sensor_process.%s' % (sensor_name) return name elif pinfo['name'] == 'gunicorn': - # st2api / st2auth / st2stream, mistral-api process - if 'mistral.api.wsgi' in ' '.join(pinfo['cmdline']): - return 'mistral-api' - + # st2api / st2auth / st2stream process for arg in pinfo['cmdline']: if arg.endswith('.wsgi:application'): return arg.split('.wsgi:application')[0] - elif pinfo['name'] in ['mistral-server']: - return pinfo['name'] return False diff --git a/tools/upgrade-mistral-wf-0.8 b/tools/upgrade-mistral-wf-0.8 deleted file mode 100755 index c3e82d7084..0000000000 --- a/tools/upgrade-mistral-wf-0.8 +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env bash -# -## Mistral YAQL Migration tool -# -# This tool inspects a given Mistral workflow, parses it using a few -# regex filters, and attempts to rewrite the file to adhere to the -# updated YAQL syntax introduced in https://review.openstack.org/#/c/157741/ -# -# There appear to be two different ways that the old style YAQL is -# represented in workflows. This includes: -# * bare - (node: $.node) -# * interpolated - (node: 'Node: {$.node}') -# * functions - (node: range(0, $.nodes).list() ) -# -# This command runs sed with two passes attempting to clean up a given -# workflow. This command will also ensure a backup exists in the event -# that things do not go as expected to prevent data loss. -####################################################################### - -function usage { - echo "Usage: `basename $0` " -} - -# Exit Codes -OK=0 -E_BADARGS=2 -E_NOTAFILE=3 -E_UNKNOWNOS=4 -E_SEDMISSING=5 - -# Let's figure out what OS we're on to pass the right flags -# to sed. Silly GNU vs BSD! -if [[ "$OSTYPE" == "linux-gnu" ]]; then - SED_ARGS="" -elif [[ "$OSTYPE" == "darwin"* ]]; then - SED_ARGS="-E" -else - echo "Not sure how best to handle sed on your system... unknown OS" - exit $E_UNKNOWNOS -fi - -SED=`which sed` -if [[ $? -ne 0 ]]; then - echo "sed not found on this system... exiting" - exit $E_SEDMISSING -fi - -# Check for a proper number of command line args: -EXPECTED_ARGS=1 -if [[ $# -ne $EXPECTED_ARGS ]]; then - usage - exit $E_BADARGS -else - WORKFLOW=$1 -fi - -# Make sure any arguments are actually files that exist -if [[ ! -f $WORKFLOW ]]; then - echo "Argument supplied is not a file..." - usage - exit $E_NOTAFILE -fi - -# Great, got this far. Let's actually start to slice and dice. -## First, make a backup -cp $WORKFLOW ${WORKFLOW}.bak - -## Pass through in phases, because a few too many variables to make a master regex. -cat $WORKFLOW | \ - sed $SED_ARGS 's/{([][_$.0-9a-z+\s]+)}/<% \1 %>/g' | \ - sed $SED_ARGS 's/([][_$.0-9a-z]+\(.*\))/<% \1 %>/g' | \ - sed $SED_ARGS 's/(\$\.[][a-z0-9_.]+)/<% \1 %>/g' | \ - sed $SED_ARGS 's/<% (<% [][a-z0-9._$]+ %>) %>/\1/g' | \ - sed $SED_ARGS 's/<% ([][$.a-z0-9_]+) %>\)/\1)/g' > ${WORKFLOW}.new - -## And put our file back where it belongs... -mv ${WORKFLOW}.new $WORKFLOW - diff --git a/tox.ini b/tox.ini index 4e6070fe5a..48593e0cf7 100644 --- a/tox.ini +++ b/tox.ini @@ -21,7 +21,7 @@ deps = -r{toxinidir}/requirements.txt # Python 3 tasks [testenv:py36-unit] basepython = python3.6 -setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/mistral_v2:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner +setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner VIRTUALENV_DIR = {envdir} passenv = NOSE_WITH_TIMER TRAVIS install_command = pip install -U --force-reinstall {opts} {packages} @@ -50,22 +50,9 @@ commands = nosetests --rednose --immediate -sv contrib/runners/python_runner/tests/unit/ nosetests --rednose --immediate -sv contrib/runners/winrm_runner/tests/unit/ -[testenv:py36-unit-nightly] -basepython = python3.6 -setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/mistral_v2:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner - VIRTUALENV_DIR = {envdir} -passenv = NOSE_WITH_TIMER TRAVIS -install_command = pip install -U --force-reinstall {opts} {packages} -deps = virtualenv - -r{toxinidir}/requirements.txt - -e{toxinidir}/st2client - -e{toxinidir}/st2common -commands = - nosetests --rednose --immediate -sv contrib/runners/mistral_v2/tests/unit/ - [testenv:py36-packs] basepython = python3.6 -setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/mistral_v2:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner +setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner VIRTUALENV_DIR = {envdir} passenv = NOSE_WITH_TIMER TRAVIS install_command = pip install -U --force-reinstall {opts} {packages} @@ -84,7 +71,7 @@ commands = [testenv:py36-integration] basepython = python3.6 -setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2auth:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/mistral_v2:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner +setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2auth:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner VIRTUALENV_DIR = {envdir} passenv = NOSE_WITH_TIMER TRAVIS install_command = pip install -U --force-reinstall {opts} {packages} @@ -101,7 +88,6 @@ commands = nosetests --rednose --immediate -sv st2reactor/tests/integration/ nosetests --rednose --immediate -sv contrib/runners/action_chain_runner/tests/integration/ nosetests --rednose --immediate -sv contrib/runners/local_runner/tests/integration/ - nosetests --rednose --immediate -sv contrib/runners/mistral_v2/tests/integration/ nosetests --rednose --immediate -sv contrib/runners/orquesta_runner/tests/integration/ nosetests --rednose --immediate -sv st2tests/integration/orquesta/ nosetests --rednose --immediate -sv contrib/runners/python_runner/tests/integration/ From ebd4e65f8a747df584338aa0c821c6826df02f4e Mon Sep 17 00:00:00 2001 From: amanda Date: Tue, 4 Aug 2020 19:50:47 +0100 Subject: [PATCH 02/26] Add some more changes --- .circle/configure-postgres.sh | 9 - conf/HA/nginx/st2.conf.blueprint.sample | 20 -- conf/HA/nginx/st2.conf.controller.sample | 18 - conf/HA/st2.conf.sample | 4 - conf/st2.conf.sample | 28 -- conf/st2.dev.conf | 4 - conf/st2.tests.conf | 2 - conf/st2.tests2.conf | 2 - .../chain-test-cancel-with-subworkflow.yaml | 2 +- ...in-test-pause-resume-with-subworkflow.yaml | 2 +- .../chain_test_cancel_with_subworkflow.yaml | 2 +- ...in_test_pause_resume_with_subworkflow.yaml | 2 +- .../actions/orquesta-test-pause-resume.yaml | 14 + .../tests/orquesta-test-pause-resume.yaml | 22 ++ .../inquirer_runner/inquirer_runner.py | 2 +- requirements.txt | 1 - st2actions/in-requirements.txt | 1 - st2actions/requirements.txt | 1 - st2actions/st2actions/container/base.py | 2 +- .../test_paramiko_remote_script_runner.py | 12 +- st2api/in-requirements.txt | 1 - st2api/requirements.txt | 1 - st2api/st2api/controllers/exp/validation.py | 54 --- .../st2api/controllers/v1/actionexecutions.py | 4 +- .../unit/controllers/v1/test_executions.py | 4 +- st2client/st2client/commands/action.py | 12 +- .../execution_result_has_carriage_return.json | 2 +- .../execution_result_has_carriage_return.txt | 2 - ...ecution_result_has_carriage_return_py3.txt | 2 - .../tests/unit/test_execution_tail_command.py | 338 ------------------ st2common/bin/st2-self-check | 41 +-- st2common/bin/st2-track-result | 7 - st2common/bin/st2ctl | 18 +- .../st2common/bootstrap/actionsregistrar.py | 5 - st2common/st2common/config.py | 51 +-- st2common/st2common/constants/action.py | 1 - st2common/st2common/openapi.yaml | 26 -- st2common/st2common/openapi.yaml.j2 | 26 -- st2common/st2common/router.py | 9 +- st2common/st2common/services/inquiry.py | 2 +- st2common/st2common/util/api.py | 17 - st2common/st2common/util/jinja.py | 3 - st2common/tests/unit/test_dist_utils.py | 2 - st2common/tests/unit/test_param_utils.py | 12 +- .../tests/unit/test_policies_registrar.py | 4 +- st2common/tests/unit/test_query_base.py | 24 +- st2common/tests/unit/test_runners_base.py | 8 +- .../unit/test_shell_action_system_model.py | 12 +- st2common/tests/unit/test_util_api.py | 15 - st2debug/st2debug/cmd/submit_debug_info.py | 25 +- st2debug/st2debug/processors.py | 30 -- .../integration/test_submit_debug_info.py | 14 - .../generic/liveactions/liveaction2.yaml | 10 + 53 files changed, 97 insertions(+), 835 deletions(-) delete mode 100755 .circle/configure-postgres.sh create mode 100644 contrib/examples/actions/orquesta-test-pause-resume.yaml create mode 100644 contrib/examples/actions/workflows/tests/orquesta-test-pause-resume.yaml delete mode 100644 st2api/st2api/controllers/exp/validation.py create mode 100644 st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml diff --git a/.circle/configure-postgres.sh b/.circle/configure-postgres.sh deleted file mode 100755 index ce76a517fc..0000000000 --- a/.circle/configure-postgres.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -CONFIG=$(cat <' ]; do sleep 0.1; done" + timeout: 300 + next: + - when: <% succeeded() %> + publish: var1=<% ctx().message %> + do: task2 + task2: + action: core.local + input: + cmd: 'echo "<% $.var1 %>"' diff --git a/contrib/runners/inquirer_runner/inquirer_runner/inquirer_runner.py b/contrib/runners/inquirer_runner/inquirer_runner/inquirer_runner.py index f552f31d74..57c65aa145 100644 --- a/contrib/runners/inquirer_runner/inquirer_runner/inquirer_runner.py +++ b/contrib/runners/inquirer_runner/inquirer_runner/inquirer_runner.py @@ -114,7 +114,7 @@ def post_run(self, status, result): not workflow_service.is_action_execution_under_workflow_context(self.liveaction) ) - # For action execution under Action Chain and Mistral workflows, request the entire + # For action execution under Action Chain workflows, request the entire # workflow to pause. Orquesta handles pause differently and so does not require parent # to pause. Orquesta allows for other branches to keep running. When there is no other # active branches, the conductor will see there is only the pending task and will know diff --git a/requirements.txt b/requirements.txt index 9b37cadde2..740333180f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,6 @@ eventlet==0.25.1 flex==6.14.0 git+https://github.com/StackStorm/logshipper.git@stackstorm_patched#egg=logshipper git+https://github.com/StackStorm/orquesta.git@v1.1.1#egg=orquesta -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient git+https://github.com/StackStorm/st2-auth-backend-flat-file.git@master#egg=st2-auth-backend-flat-file gitpython==2.1.15 greenlet==0.4.15 diff --git a/st2actions/in-requirements.txt b/st2actions/in-requirements.txt index 2d47af1e0b..dcc00c6cf3 100644 --- a/st2actions/in-requirements.txt +++ b/st2actions/in-requirements.txt @@ -4,7 +4,6 @@ python-dateutil eventlet jinja2 kombu -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient oslo.config oslo.utils requests diff --git a/st2actions/requirements.txt b/st2actions/requirements.txt index 958215c561..80d3661f38 100755 --- a/st2actions/requirements.txt +++ b/st2actions/requirements.txt @@ -8,7 +8,6 @@ apscheduler==3.6.3 eventlet==0.25.1 git+https://github.com/StackStorm/logshipper.git@stackstorm_patched#egg=logshipper -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient gitpython==2.1.15 jinja2==2.10.3 kombu==4.6.6 diff --git a/st2actions/st2actions/container/base.py b/st2actions/st2actions/container/base.py index a1fd1331b7..2e1e0f6572 100644 --- a/st2actions/st2actions/container/base.py +++ b/st2actions/st2actions/container/base.py @@ -249,7 +249,7 @@ def _clean_up_auth_token(self, runner, status): it doesn't throw. """ # Deletion of the runner generated auth token is delayed until the token expires. - # Async actions such as Mistral workflows uses the auth token to launch other + # Async actions use the auth token to launch other # actions in the workflow. If the auth token is deleted here, then the actions # in the workflow will fail with unauthorized exception. is_async_runner = isinstance(runner, AsyncActionRunner) diff --git a/st2actions/tests/unit/test_paramiko_remote_script_runner.py b/st2actions/tests/unit/test_paramiko_remote_script_runner.py index 803d7054f4..25e03b3194 100644 --- a/st2actions/tests/unit/test_paramiko_remote_script_runner.py +++ b/st2actions/tests/unit/test_paramiko_remote_script_runner.py @@ -129,19 +129,14 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'position': 3, 'default': 'master', }, - 'update_mistral': { - 'type': 'boolean', - 'position': 4, - 'default': False - }, 'update_changelog': { 'type': 'boolean', - 'position': 5, + 'position': 4, 'default': False }, 'local_repo': { 'type': 'string', - 'position': 6, + 'position': 5, } } context = {} @@ -170,7 +165,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.0.0', 'fork': 'StackStorm', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repo' }) @@ -211,7 +205,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.1.0', 'fork': 'StackStorm1', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': True, # default value used 'local_repo': '/tmp/repob' }) @@ -252,7 +245,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.2.0', 'fork': 'StackStorm2', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repoc' }) diff --git a/st2api/in-requirements.txt b/st2api/in-requirements.txt index 76ea3129ee..1b1bd859d4 100644 --- a/st2api/in-requirements.txt +++ b/st2api/in-requirements.txt @@ -8,5 +8,4 @@ oslo.config oslo.utils pymongo six -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient gunicorn diff --git a/st2api/requirements.txt b/st2api/requirements.txt index 854a05e273..7a920a843f 100644 --- a/st2api/requirements.txt +++ b/st2api/requirements.txt @@ -6,7 +6,6 @@ # in-requirements.txt for that component and then run 'make requirements' to # update the component requirements.txt eventlet==0.25.1 -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient gunicorn==19.9.0 jsonschema==2.6.0 kombu==4.6.6 diff --git a/st2api/st2api/controllers/exp/validation.py b/st2api/st2api/controllers/exp/validation.py deleted file mode 100644 index 875c11d0ce..0000000000 --- a/st2api/st2api/controllers/exp/validation.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2019 Extreme Networks, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -try: - from mistralclient.api import client as mistral -except ImportError: - # Likely running on installation without Mistral - mistral = None - -import six - -from st2common import log as logging -from st2common.router import Response -from st2common.router import abort -from st2common.validators.workflow.mistral import v2 as mistral_validation_utils - - -LOG = logging.getLogger(__name__) - -http_client = six.moves.http_client - - -class MistralValidationController(object): - - def __init__(self): - super(MistralValidationController, self).__init__() - self.validator = mistral_validation_utils.get_validator() - - def post(self, def_yaml): - if not mistral: - abort(http_client.NOT_FOUND) - return - - result = self.validator.validate(def_yaml) - - for error in result: - if not error.get('path', None): - error['path'] = '' - - return Response(json=result) - - -mistral_validation_controller = MistralValidationController() diff --git a/st2api/st2api/controllers/v1/actionexecutions.py b/st2api/st2api/controllers/v1/actionexecutions.py index 5032ad33da..9427c77f8c 100644 --- a/st2api/st2api/controllers/v1/actionexecutions.py +++ b/st2api/st2api/controllers/v1/actionexecutions.py @@ -425,9 +425,9 @@ def post(self, spec_api, id, requester_user, no_merge=False, show_secrets=False) requester_user=requester_user, permission_type=PermissionType.EXECUTION_VIEW) - if spec_api.tasks and existing_execution.runner['name'] != 'mistral-v2' and \ + if spec_api.tasks and \ existing_execution.runner['name'] != 'orquesta': - raise ValueError('Task option is only supported for Orquesta and Mistral workflows.') + raise ValueError('Task option is only supported for Orquesta workflows.') # Merge in any parameters provided by the user new_parameters = {} diff --git a/st2api/tests/unit/controllers/v1/test_executions.py b/st2api/tests/unit/controllers/v1/test_executions.py index 7ab63dc65d..e62a024387 100644 --- a/st2api/tests/unit/controllers/v1/test_executions.py +++ b/st2api/tests/unit/controllers/v1/test_executions.py @@ -129,7 +129,7 @@ 'enabled': True, 'entry_point': '/tmp/test/workflows/action4.yaml', 'pack': 'starterpack', - 'runner_type': 'mistral-v2', + 'runner_type': 'orquesta-runner', 'parameters': { 'a': { 'type': 'string', @@ -942,7 +942,7 @@ def test_re_run_failure_tasks_option_for_non_workflow(self): self.assertEqual(re_run_resp.status_int, 400) - expected_substring = 'only supported for Orquesta and Mistral workflows' + expected_substring = 'only supported for Orquesta workflows' self.assertIn(expected_substring, re_run_resp.json['faultstring']) def test_re_run_workflow_failure_given_both_params_and_tasks(self): diff --git a/st2client/st2client/commands/action.py b/st2client/st2client/commands/action.py index f458303bc0..540c0cd368 100644 --- a/st2client/st2client/commands/action.py +++ b/st2client/st2client/commands/action.py @@ -95,7 +95,6 @@ WORKFLOW_RUNNER_TYPES = [ 'action-chain', - 'mistral-v2', 'orquesta' ] @@ -866,15 +865,13 @@ def _format_child_instances(self, children, parent_id): def _format_for_common_representation(self, task): ''' - Formats a task for common representation between mistral and action-chain. + Formats a task for common representation for action-chain. ''' # This really needs to be better handled on the back-end but that would be a bigger # change so handling in cli. context = getattr(task, 'context', None) if context and 'chain' in context: task_name_key = 'context.chain.name' - elif context and 'mistral' in context: - task_name_key = 'context.mistral.task_name' elif context and 'orquesta' in context: task_name_key = 'context.orquesta.task_name' # Use Execution as the object so that the formatter lookup does not change. @@ -1591,12 +1588,7 @@ def get_normalized_context_execution_task_event(cls, event): 'task_name': None } - if 'mistral' in context: - # Mistral workflow - result['parent_execution_id'] = context.get('parent', {}).get('execution_id', None) - result['execution_id'] = event['id'] - result['task_name'] = context.get('mistral', {}).get('task_name', 'unknown') - elif 'orquesta' in context: + if 'orquesta' in context: result['parent_execution_id'] = context.get('parent', {}).get('execution_id', None) result['execution_id'] = event['id'] result['task_name'] = context.get('orquesta', {}).get('task_name', 'unknown') diff --git a/st2client/tests/fixtures/execution_result_has_carriage_return.json b/st2client/tests/fixtures/execution_result_has_carriage_return.json index 76fb60516e..c57bfc883e 100644 --- a/st2client/tests/fixtures/execution_result_has_carriage_return.json +++ b/st2client/tests/fixtures/execution_result_has_carriage_return.json @@ -19,7 +19,7 @@ "stderr": "", "return_code": 0, "succeeded": true, - "stdout": "restarting service sensor_containesr with 1 process(es).\r\nsensor_containesr is not running\r\nactionrunner PID: 16604\r\nactionrunner PID: 16605\r\nactionrunner PID: 16606\r\nactionrunner PID: 16607\r\nactionrunner PID: 16608\r\nactionrunner PID: 16609\r\nactionrunner PID: 16610\r\nactionrunner PID: 16611\r\nactionrunner PID: 16612\r\nactionrunner PID: 16613\r\nactionrunner PID: 19916\r\nst2api PID: 16614\r\nsensor_container is not running\r\nhistory PID: 16616\r\nrules_engine PID: 16617\r\nmistral PID: 16624\r\nmistral PID: 16625" + "stdout": "restarting service sensor_containesr with 1 process(es).\r\nsensor_containesr is not running\r\nactionrunner PID: 16604\r\nactionrunner PID: 16605\r\nactionrunner PID: 16606\r\nactionrunner PID: 16607\r\nactionrunner PID: 16608\r\nactionrunner PID: 16609\r\nactionrunner PID: 16610\r\nactionrunner PID: 16611\r\nactionrunner PID: 16612\r\nactionrunner PID: 16613\r\nactionrunner PID: 19916\r\nst2api PID: 16614\r\nsensor_container is not running\r\nhistory PID: 16616\r\nrules_engine PID: 16617" } }, "delete": { diff --git a/st2client/tests/fixtures/execution_result_has_carriage_return.txt b/st2client/tests/fixtures/execution_result_has_carriage_return.txt index efdbac7e8f..749bcb3a72 100644 --- a/st2client/tests/fixtures/execution_result_has_carriage_return.txt +++ b/st2client/tests/fixtures/execution_result_has_carriage_return.txt @@ -47,8 +47,6 @@ | | sensor_container is not running | | | history PID: 16616 | | | rules_engine PID: 16617 | -| | mistral PID: 16624 | -| | mistral PID: 16625" | | | } | | | }, | | | "delete": { | diff --git a/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt b/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt index 7a10e63a52..46b730fbd3 100644 --- a/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt +++ b/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt @@ -47,8 +47,6 @@ | | sensor_container is not running | | | history PID: 16616 | | | rules_engine PID: 16617 | -| | mistral PID: 16624 | -| | mistral PID: 16625" | | | } | | | }, | | | "delete": { | diff --git a/st2client/tests/unit/test_execution_tail_command.py b/st2client/tests/unit/test_execution_tail_command.py index bbd18b735d..9be6c356b1 100644 --- a/st2client/tests/unit/test_execution_tail_command.py +++ b/st2client/tests/unit/test_execution_tail_command.py @@ -130,130 +130,6 @@ 'status': LIVEACTION_STATUS_SUCCEEDED } -# Mock objects for Mistral workflow execution -MOCK_LIVEACTION_4_RUNNING = { - 'id': 'idfoo4', - 'status': LIVEACTION_STATUS_RUNNING -} - -MOCK_LIVEACTION_4_CHILD_1_RUNNING = { - 'id': 'idmistralchild1', - 'context': { - 'mistral': { - 'task_name': 'task_1' - }, - 'parent': { - 'execution_id': 'idfoo4' - } - }, - 'status': LIVEACTION_STATUS_RUNNING -} - -MOCK_LIVEACTION_4_CHILD_1_1_RUNNING = { - 'id': 'idmistralchild1_1', - 'context': { - 'mistral': { - 'task_name': 'task_1' - }, - 'parent': { - 'execution_id': 'idmistralchild1' - } - }, - 'status': LIVEACTION_STATUS_RUNNING -} - -MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED = { - 'id': 'idmistralchild1', - 'context': { - 'mistral': { - 'task_name': 'task_1', - }, - 'parent': { - 'execution_id': 'idfoo4' - } - }, - 'status': LIVEACTION_STATUS_SUCCEEDED -} - -MOCK_LIVEACTION_4_CHILD_1_1_SUCCEEDED = { - 'id': 'idmistralchild1_1', - 'context': { - 'mistral': { - 'task_name': 'task_1', - }, - 'parent': { - 'execution_id': 'idmistralchild1' - } - }, - 'status': LIVEACTION_STATUS_SUCCEEDED -} - -MOCK_LIVEACTION_4_CHILD_1_OUTPUT_1 = { - 'execution_id': 'idmistralchild1', - 'timestamp': '1505732598', - 'output_type': 'stdout', - 'data': 'line mistral 4\n' -} - -MOCK_LIVEACTION_4_CHILD_1_OUTPUT_2 = { - 'execution_id': 'idmistralchild1', - 'timestamp': '1505732598', - 'output_type': 'stderr', - 'data': 'line mistral 5\n' -} - -MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_1 = { - 'execution_id': 'idmistralchild1_1', - 'timestamp': '1505732598', - 'output_type': 'stdout', - 'data': 'line mistral 4\n' -} - -MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_2 = { - 'execution_id': 'idmistralchild1_1', - 'timestamp': '1505732598', - 'output_type': 'stderr', - 'data': 'line mistral 5\n' -} - -MOCK_LIVEACTION_4_CHILD_2_RUNNING = { - 'id': 'idmistralchild2', - 'context': { - 'mistral': { - 'task_name': 'task_2', - }, - 'parent': { - 'execution_id': 'idfoo4' - } - }, - 'status': LIVEACTION_STATUS_RUNNING -} - -MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT = { - 'id': 'idmistralchild2', - 'context': { - 'mistral': { - 'task_name': 'task_2', - }, - 'parent': { - 'execution_id': 'idfoo4' - } - }, - 'status': LIVEACTION_STATUS_TIMED_OUT -} - -MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1 = { - 'execution_id': 'idmistralchild2', - 'timestamp': '1505732598', - 'output_type': 'stdout', - 'data': 'line mistral 100\n' -} - -MOCK_LIVEACTION_4_SUCCEDED = { - 'id': 'idfoo4', - 'status': LIVEACTION_STATUS_SUCCEEDED -} - # Mock objects for simple actions MOCK_OUTPUT_1 = { 'execution_id': 'idfoo3', @@ -440,217 +316,3 @@ def test_tail_action_chain_workflow_execution(self, mock_stream_manager): """.lstrip() self.assertEqual(stdout, expected_result) self.assertEqual(stderr, '') - - @mock.patch.object( - httpclient.HTTPClient, 'get', - mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_RUNNING), - 200, 'OK'))) - @mock.patch('st2client.client.StreamManager', autospec=True) - def test_tail_mistral_workflow_execution(self, mock_stream_manager): - argv = ['execution', 'tail', 'idfoo4'] - - MOCK_EVENTS = [ - # Workflow started running - MOCK_LIVEACTION_4_RUNNING, - - # Child task 1 started running - MOCK_LIVEACTION_4_CHILD_1_RUNNING, - - # Output produced by the child task - MOCK_LIVEACTION_4_CHILD_1_OUTPUT_1, - MOCK_LIVEACTION_4_CHILD_1_OUTPUT_2, - - # Child task 1 finished - MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, - - # Child task 2 started running - MOCK_LIVEACTION_4_CHILD_2_RUNNING, - - # Output produced by child task - MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, - - # Child task 2 finished - MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT, - - # Parent workflow task finished - MOCK_LIVEACTION_4_SUCCEDED - ] - - mock_cls = mock.Mock() - mock_cls.listen = mock.Mock() - mock_listen_generator = mock.Mock() - mock_listen_generator.return_value = MOCK_EVENTS - mock_cls.listen.side_effect = mock_listen_generator - mock_stream_manager.return_value = mock_cls - - self.assertEqual(self.shell.run(argv), 0) - self.assertEqual(mock_listen_generator.call_count, 1) - - stdout = self.stdout.getvalue() - stderr = self.stderr.getvalue() - - expected_result = """ -Execution idfoo4 has started. - -Child execution (task=task_1) idmistralchild1 has started. - -line mistral 4 -line mistral 5 - -Child execution (task=task_1) idmistralchild1 has finished (status=succeeded). -Child execution (task=task_2) idmistralchild2 has started. - -line mistral 100 - -Child execution (task=task_2) idmistralchild2 has finished (status=timeout). - -Execution idfoo4 has completed (status=succeeded). -""".lstrip() - self.assertEqual(stdout, expected_result) - self.assertEqual(stderr, '') - - @mock.patch.object( - httpclient.HTTPClient, 'get', - mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_RUNNING), - 200, 'OK'))) - @mock.patch('st2client.client.StreamManager', autospec=True) - def test_tail_double_nested_mistral_workflow_execution(self, mock_stream_manager): - argv = ['execution', 'tail', 'idfoo4'] - - MOCK_EVENTS = [ - # Workflow started running - MOCK_LIVEACTION_4_RUNNING, - - # Child task 1 started running (sub workflow) - MOCK_LIVEACTION_4_CHILD_1_RUNNING, - - # Child task 1 started running - MOCK_LIVEACTION_4_CHILD_1_1_RUNNING, - - # Output produced by the child task - MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_1, - MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_2, - - # Another execution has started, this output should not be included - MOCK_LIVEACTION_3_RUNNING, - - # Child task 1 started running - MOCK_LIVEACTION_3_CHILD_1_RUNNING, - - # Output produced by the child task - MOCK_LIVEACTION_3_CHILD_1_OUTPUT_1, - MOCK_LIVEACTION_3_CHILD_1_OUTPUT_2, - - # Child task 1 finished - MOCK_LIVEACTION_3_CHILD_1_SUCCEEDED, - - # Parent workflow task finished - MOCK_LIVEACTION_3_SUCCEDED, - # End another execution - - # Child task 1 has finished - MOCK_LIVEACTION_4_CHILD_1_1_SUCCEEDED, - - # Child task 1 finished (sub workflow) - MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, - - # Child task 2 started running - MOCK_LIVEACTION_4_CHILD_2_RUNNING, - - # Output produced by child task - MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, - - # Child task 2 finished - MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT, - - # Parent workflow task finished - MOCK_LIVEACTION_4_SUCCEDED - ] - - mock_cls = mock.Mock() - mock_cls.listen = mock.Mock() - mock_listen_generator = mock.Mock() - mock_listen_generator.return_value = MOCK_EVENTS - mock_cls.listen.side_effect = mock_listen_generator - mock_stream_manager.return_value = mock_cls - - self.assertEqual(self.shell.run(argv), 0) - self.assertEqual(mock_listen_generator.call_count, 1) - - stdout = self.stdout.getvalue() - stderr = self.stderr.getvalue() - - expected_result = """ -Execution idfoo4 has started. - -Child execution (task=task_1) idmistralchild1 has started. - -Child execution (task=task_1) idmistralchild1_1 has started. - -line mistral 4 -line mistral 5 - -Child execution (task=task_1) idmistralchild1_1 has finished (status=succeeded). - -Child execution (task=task_1) idmistralchild1 has finished (status=succeeded). -Child execution (task=task_2) idmistralchild2 has started. - -line mistral 100 - -Child execution (task=task_2) idmistralchild2 has finished (status=timeout). - -Execution idfoo4 has completed (status=succeeded). -""".lstrip() - - self.assertEqual(stdout, expected_result) - self.assertEqual(stderr, '') - - @mock.patch.object( - httpclient.HTTPClient, 'get', - mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_CHILD_2_RUNNING), - 200, 'OK'))) - @mock.patch('st2client.client.StreamManager', autospec=True) - def test_tail_child_execution_directly(self, mock_stream_manager): - argv = ['execution', 'tail', 'idfoo4'] - - MOCK_EVENTS = [ - # Child task 2 started running - MOCK_LIVEACTION_4_CHILD_2_RUNNING, - - # Output produced by child task - MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, - - # Other executions should not interfere - # Child task 1 started running - MOCK_LIVEACTION_3_CHILD_1_RUNNING, - - # Child task 1 finished (sub workflow) - MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, - - # Child task 2 finished - MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT - ] - - mock_cls = mock.Mock() - mock_cls.listen = mock.Mock() - mock_listen_generator = mock.Mock() - mock_listen_generator.return_value = MOCK_EVENTS - mock_cls.listen.side_effect = mock_listen_generator - mock_stream_manager.return_value = mock_cls - - self.assertEqual(self.shell.run(argv), 0) - self.assertEqual(mock_listen_generator.call_count, 1) - - stdout = self.stdout.getvalue() - stderr = self.stderr.getvalue() - - expected_result = """ -Child execution (task=task_2) idmistralchild2 has started. - -line mistral 100 - -Child execution (task=task_2) idmistralchild2 has finished (status=timeout). -""".lstrip() - - self.assertEqual(stdout, expected_result) - self.assertEqual(stderr, '') diff --git a/st2common/bin/st2-self-check b/st2common/bin/st2-self-check index 9a2edb7162..32e37b49ad 100755 --- a/st2common/bin/st2-self-check +++ b/st2common/bin/st2-self-check @@ -20,7 +20,6 @@ function usage() { echo "" echo "Options:" echo " -o Skip Orquesta tests" - echo " -m Skip Mistral tests" echo " -w Run Windows tests" echo " -b Which branch of st2tests to use (defaults to master)" echo "" @@ -28,11 +27,10 @@ function usage() { } RUN_ORQUESTA_TESTS=true -RUN_MISTRAL_TESTS=true RUN_WINDOWS_TESTS=false ST2_TESTS_BRANCH="master" -while getopts "b:wom" o +while getopts "b:wo" o do case "${o}" in b) @@ -41,9 +39,6 @@ do o) RUN_ORQUESTA_TESTS=false ;; - m) - RUN_MISTRAL_TESTS=false - ;; w) RUN_WINDOWS_TESTS=true ;; @@ -66,13 +61,6 @@ if [[ `id -u` != 0 ]]; then exit 1 fi -# Installations which use Python 3 (e.g. Ubuntu Bionic) ship without Mistral -PYTHON_VERSION=$(/opt/stackstorm/st2/bin/python --version 2>&1 | awk '{print $2'} | awk -F"." '{print $1}') - -if [ "${PYTHON_VERSION}" = "3" ]; then - RUN_MISTRAL_TESTS=false -fi - ERRORS=0 PACKS="tests examples" @@ -141,12 +129,6 @@ do continue fi - # Skip Mistral Inquiry test if we're not running Mistral tests - if [ ${RUN_MISTRAL_TESTS} = "false" ] && [ ${TEST} = "tests.test_inquiry_mistral" ]; then - echo "Skipping ${TEST}..." - continue - fi - echo -n "Attempting Test ${TEST}..." START_TS=$(date +%s) @@ -165,27 +147,6 @@ do fi done -if [ ${RUN_MISTRAL_TESTS} = "true" ]; then - echo -n "Attempting Example examples.mistral_examples..." - - START_TS=$(date +%s) - OUTPUT=$(st2 run examples.mistral_examples) - echo ${OUTPUT} | grep "status" | grep -q "succeeded" - EXIT_CODE=$? - END_TS=$(date +%s) - DURATION=$(expr ${END_TS} - ${START_TS}) - - if [ ${EXIT_CODE} -ne 0 ]; then - echo -e "ERROR! (${DURATION}s)" - echo "Test output: ${OUTPUT}" - ((ERRORS++)) - else - echo "OK! (${DURATION}s)" - fi -else - echo "Skipping examples.mistral_examples..." -fi - if [ ${RUN_ORQUESTA_TESTS} = "true" ]; then echo -n "Attempting Example examples.orquesta-examples..." diff --git a/st2common/bin/st2-track-result b/st2common/bin/st2-track-result index 3a604d627e..890c40d7a9 100755 --- a/st2common/bin/st2-track-result +++ b/st2common/bin/st2-track-result @@ -52,10 +52,6 @@ def add_result_tracker(exec_id): # Check runner type. runner_type = exec_db.action.get('runner_type') - if runner_type != 'mistral-v2': - LOG.error('Result tracker is only supported for Mistral workflows.') - return - # Skip if action execution is completed. if exec_db.status in action_constants.LIVEACTION_COMPLETED_STATES: LOG.info('Action execution "%s" is already in a completed state.', exec_id) @@ -85,9 +81,6 @@ def add_result_tracker(exec_id): # Add result tracker for children workflows. for child_exec_id in exec_db.children: child_exec = ActionExecution.get(id=child_exec_id, raise_exception=True) - if child_exec.runner['name'] == 'mistral-v2': - LOG.info('Adding result tracker for children "%s"...', child_exec_id) - add_result_tracker(child_exec_id) def del_result_tracker(exec_id): diff --git a/st2common/bin/st2ctl b/st2common/bin/st2ctl index 3cab368cf4..bfa521f66f 100755 --- a/st2common/bin/st2ctl +++ b/st2common/bin/st2ctl @@ -14,16 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -COMPONENTS="st2actionrunner st2api st2stream st2auth st2garbagecollector st2notifier st2resultstracker st2rulesengine st2sensorcontainer st2chatops st2timersengine st2workflowengine st2scheduler mistral" +COMPONENTS="st2actionrunner st2api st2stream st2auth st2garbagecollector st2notifier st2resultstracker st2rulesengine st2sensorcontainer st2chatops st2timersengine st2workflowengine st2scheduler" ST2_CONF="/etc/st2/st2.conf" -# Installations which use Python 3 (e.g. Ubuntu Bionic) ship without Mistral -PYTHON_VERSION=$(/opt/stackstorm/st2/bin/python --version 2>&1 | awk '{print $2'} | awk -F"." '{print $1}') - -if [ "${PYTHON_VERSION}" = "3" ]; then - COMPONENTS=${COMPONENTS/mistral} -fi - # Ensure global environment is sourced if exists # Does not happen consistently with all OSes we support. [ -r /etc/environment ] && source /etc/environment @@ -46,7 +39,7 @@ function print_usage() { echo "Usage: st2ctl {reopen-log-files}" echo "positional arguments:" echo " component Name of the st2 service to reopen the log files for." - echo " ${COMPONENTS/mistral}" + echo " ${COMPONENTS}" echo echo "Usage: st2ctl {reload, clean}" echo "optional arguments:" @@ -126,11 +119,6 @@ function service_manager() { function reopen_component_log_files() { COM=${1} - if [[ "$COM" == "mistral" ]]; then - echo "Sorry, Mistral does not yet support gracefully reopening log files" - return 1 - fi - PID=`ps ax | grep -v grep | grep -v st2ctl | grep -E "(${COM}\.wsgi)|(bin/${COM})|(hubot .*${COM})" | awk '{print $1}'` if [[ ! -z ${PID} ]]; then for p in ${PID}; do @@ -188,7 +176,7 @@ function clean_logs() { function getpids() { echo "##### st2 components status #####" - COMPONENTS=${COMPONENTS/mistral/mistral-server mistral.api} + COMPONENTS=${COMPONENTS} for COM in ${COMPONENTS}; do PID=`ps ax | grep -v grep | grep -v st2ctl | grep -E "(${COM}\.wsgi)|(bin/${COM})|(hubot .*${COM})" | awk '{print $1}'` diff --git a/st2common/st2common/bootstrap/actionsregistrar.py b/st2common/st2common/bootstrap/actionsregistrar.py index 074f48b7cf..77d59da408 100644 --- a/st2common/st2common/bootstrap/actionsregistrar.py +++ b/st2common/st2common/bootstrap/actionsregistrar.py @@ -193,11 +193,6 @@ def _register_actions_from_pack(self, pack, actions): LOG.debug('Loading action from %s.', action) self._register_action(pack=pack, action=action) except Exception as e: - # We ignore mistral-v2 runner not found errors since those represent installations - # without Mistral - if 'mistral-v2 is not found' in six.text_type(e): - continue - if self._fail_on_failure: msg = ('Failed to register action "%s" from pack "%s": %s' % (action, pack, six.text_type(e))) diff --git a/st2common/st2common/config.py b/st2common/st2common/config.py index 18da4c594b..a7fb3329d6 100644 --- a/st2common/st2common/config.py +++ b/st2common/st2common/config.py @@ -471,57 +471,8 @@ def register_opts(ignore_errors=False): do_register_opts(coord_opts, 'coordination', ignore_errors) - # Mistral options - mistral_opts = [ - cfg.StrOpt( - 'v2_base_url', default='http://127.0.0.1:8989/v2', - help='v2 API root endpoint.'), - cfg.IntOpt( - 'retry_exp_msec', default=1000, - help='Multiplier for the exponential backoff.'), - cfg.IntOpt( - 'retry_exp_max_msec', default=300000, - help='Max time for each set of backoff.'), - cfg.IntOpt( - 'retry_stop_max_msec', default=600000, - help='Max time to stop retrying.'), - cfg.StrOpt( - 'keystone_username', default=None, - help='Username for authentication.'), - cfg.StrOpt( - 'keystone_password', default=None, - help='Password for authentication.'), - cfg.StrOpt( - 'keystone_project_name', default=None, - help='OpenStack project scope.'), - cfg.StrOpt( - 'keystone_auth_url', default=None, - help='Auth endpoint for Keystone.'), - cfg.StrOpt( - 'cacert', default=None, - help='Optional certificate to validate endpoint.'), - cfg.BoolOpt( - 'insecure', default=False, - help='Allow insecure communication with Mistral.'), - cfg.BoolOpt( - 'enable_polling', default=False, - help='Enable results tracking and disable callbacks.'), - cfg.FloatOpt( - 'jitter_interval', default=0.1, - help='Jitter interval to smooth out HTTP requests ' - 'to mistral tasks and executions API.'), - cfg.StrOpt( - 'api_url', default=None, - help='URL Mistral uses to talk back to the API.' - 'If not provided it defaults to public API URL. ' - 'Note: This needs to be a base URL without API ' - 'version (e.g. http://127.0.0.1:9101)') - ] - - do_register_opts(mistral_opts, group='mistral', ignore_errors=ignore_errors) - # Results Tracker query module options - # Note that these are currently used only by mistral query module. + # Note that these are currently not used query_opts = [ cfg.IntOpt( 'thread_pool_size', default=10, diff --git a/st2common/st2common/constants/action.py b/st2common/st2common/constants/action.py index 0946fe300e..0be2f57780 100644 --- a/st2common/st2common/constants/action.py +++ b/st2common/st2common/constants/action.py @@ -139,7 +139,6 @@ WORKFLOW_RUNNER_TYPES = [ 'action-chain', - 'mistral-v2', 'orquesta' ] diff --git a/st2common/st2common/openapi.yaml b/st2common/st2common/openapi.yaml index 0896532f74..f504b377b9 100644 --- a/st2common/st2common/openapi.yaml +++ b/st2common/st2common/openapi.yaml @@ -4296,32 +4296,6 @@ paths: schema: $ref: '#/definitions/Error' - /api/exp/validation/mistral: - post: - operationId: st2api.controllers.exp.validation:mistral_validation_controller.post - description: | - Validate Mistral YAML definition. - parameters: - - name: def_yaml - in: body - description: Mistral definition - schema: - type: string - responses: - '200': - description: List of validation errors - schema: - type: array - items: - $ref: '#/definitions/ValidationError' - examples: - application/json: - ref: 'core.local' - # and stuff - default: - description: Unexpected error - schema: - $ref: '#/definitions/Error' /api/v1/service_registry/groups: get: operationId: st2api.controllers.v1.service_registry:groups_controller.get_all diff --git a/st2common/st2common/openapi.yaml.j2 b/st2common/st2common/openapi.yaml.j2 index 3387564e8a..5149741504 100644 --- a/st2common/st2common/openapi.yaml.j2 +++ b/st2common/st2common/openapi.yaml.j2 @@ -4292,32 +4292,6 @@ paths: schema: $ref: '#/definitions/Error' - /api/exp/validation/mistral: - post: - operationId: st2api.controllers.exp.validation:mistral_validation_controller.post - description: | - Validate Mistral YAML definition. - parameters: - - name: def_yaml - in: body - description: Mistral definition - schema: - type: string - responses: - '200': - description: List of validation errors - schema: - type: array - items: - $ref: '#/definitions/ValidationError' - examples: - application/json: - ref: 'core.local' - # and stuff - default: - description: Unexpected error - schema: - $ref: '#/definitions/Error' /api/v1/service_registry/groups: get: operationId: st2api.controllers.v1.service_registry:groups_controller.get_all diff --git a/st2common/st2common/router.py b/st2common/st2common/router.py index 83b4c12362..f6cab7aea9 100644 --- a/st2common/st2common/router.py +++ b/st2common/st2common/router.py @@ -378,15 +378,14 @@ def __call__(self, req): # NOTE: HACK: Workaround for eventlet wsgi server which sets Content-Type to # text/plain if Content-Type is not provided in the request. - # All ouf our API endpoints except /v1/workflows/inspection and - # /exp/validation/mistral expect application/json so we explicitly set it to that + # All ouf our API endpoints except /v1/workflows/inspection + # expect application/json so we explicitly set it to that # if not provided (set to text/plain by the base http server) and if it's not - # /v1/workflows/inspection and /exp/validation/mistral API endpoints. + # /v1/workflows/inspection API endpoints. if not self.is_gunicorn and content_type == 'text/plain': operation_id = endpoint['operationId'] - if ('workflow_inspection_controller' not in operation_id and - 'mistral_validation_controller' not in operation_id): + if ('workflow_inspection_controller' not in operation_id): content_type = 'application/json' # Note: We also want to perform validation if no body is explicitly provided - in a diff --git a/st2common/st2common/services/inquiry.py b/st2common/st2common/services/inquiry.py index e31612c022..90bf746ec3 100644 --- a/st2common/st2common/services/inquiry.py +++ b/st2common/st2common/services/inquiry.py @@ -129,7 +129,7 @@ def respond(inquiry, response, requester=None): if liveaction_db.context.get('parent'): LOG.debug('Resuming workflow parent(s) for inquiry "%s".' % str(inquiry.id)) - # For action execution under Action Chain and Mistral workflows, request the entire + # For action execution under Action Chain workflows, request the entire # workflow to resume. Orquesta handles resume differently and so does not require root # to resume. Orquesta allows for specifc branches to resume while other is paused. When # there is no other paused branches, the conductor will resume the rest of the workflow. diff --git a/st2common/st2common/util/api.py b/st2common/st2common/util/api.py index 4e96c56121..1b84b25af5 100644 --- a/st2common/st2common/util/api.py +++ b/st2common/st2common/util/api.py @@ -22,7 +22,6 @@ __all__ = [ 'get_base_public_api_url', 'get_full_public_api_url', - 'get_mistral_api_url' ] LOG = logging.getLogger(__name__) @@ -54,19 +53,3 @@ def get_full_public_api_url(api_version=DEFAULT_API_VERSION): api_url = get_base_public_api_url() api_url = '%s/%s' % (api_url, api_version) return api_url - - -def get_mistral_api_url(api_version=DEFAULT_API_VERSION): - """ - Return a URL which Mistral uses to talk back to the StackStorm API. - - Note: If not provided it defaults to the public API url. - """ - if cfg.CONF.mistral.api_url: - api_url = get_url_without_trailing_slash(cfg.CONF.mistral.api_url) - api_url = '%s/%s' % (api_url, api_version) - else: - LOG.warn('"mistral.api_url" not set, using auth.api_url') - api_url = get_full_public_api_url(api_version=api_version) - - return api_url diff --git a/st2common/st2common/util/jinja.py b/st2common/st2common/util/jinja.py index 75efdbdd76..e63b8a9f7c 100644 --- a/st2common/st2common/util/jinja.py +++ b/st2common/st2common/util/jinja.py @@ -51,9 +51,6 @@ def get_filters(): from st2common.expressions.functions import version from st2common.expressions.functions import path - # IMPORTANT NOTE - these filters were recently duplicated in st2mistral so that - # they are also available in Mistral workflows. Please ensure any additions you - # make here are also made there so that feature parity is maintained. return { 'decrypt_kv': datastore.decrypt_kv, diff --git a/st2common/tests/unit/test_dist_utils.py b/st2common/tests/unit/test_dist_utils.py index 1427818a62..34dcf87091 100644 --- a/st2common/tests/unit/test_dist_utils.py +++ b/st2common/tests/unit/test_dist_utils.py @@ -109,7 +109,6 @@ def test_fetch_requirements(self): 'flex==6.14.0', 'logshipper', 'orquesta', - 'python-mistralclient', 'st2-auth-backend-flat-file', 'logshipper-editable', 'python_runner', @@ -125,7 +124,6 @@ def test_fetch_requirements(self): expected_links = [ 'git+https://github.com/Kami/logshipper.git@stackstorm_patched#egg=logshipper', 'git+https://github.com/StackStorm/orquesta.git@224c1a589a6007eb0598a62ee99d674e7836d369#egg=orquesta', # NOQA - 'git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient', 'git+https://github.com/StackStorm/st2-auth-backend-flat-file.git@master#egg=st2-auth-backend-flat-file', # NOQA 'git+https://github.com/Kami/logshipper.git@stackstorm_patched#egg=logshipper-editable', 'git+https://github.com/StackStorm/st2.git#egg=python_runner&subdirectory=contrib/runners/python_runner', # NOQA diff --git a/st2common/tests/unit/test_param_utils.py b/st2common/tests/unit/test_param_utils.py index cdd5acddb4..e3202ca849 100644 --- a/st2common/tests/unit/test_param_utils.py +++ b/st2common/tests/unit/test_param_utils.py @@ -889,19 +889,14 @@ def test_render_final_params_and_shell_script_action_command_strings(self): 'position': 3, 'default': 'master', }, - 'update_mistral': { - 'type': 'boolean', - 'position': 4, - 'default': False - }, 'update_changelog': { 'type': 'boolean', - 'position': 5, + 'position': 4, 'default': False }, 'local_repo': { 'type': 'string', - 'position': 6, + 'position': 5, } } context = {} @@ -924,7 +919,6 @@ def test_render_final_params_and_shell_script_action_command_strings(self): 'version': '3.0.0', 'fork': 'StackStorm', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repo' }) @@ -948,7 +942,6 @@ def test_render_final_params_and_shell_script_action_command_strings(self): 'version': '3.1.0', 'fork': 'StackStorm1', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': True, # default value used 'local_repo': '/tmp/repob' }) @@ -972,7 +965,6 @@ def test_render_final_params_and_shell_script_action_command_strings(self): 'version': '3.2.0', 'fork': 'StackStorm2', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repoc' }) diff --git a/st2common/tests/unit/test_policies_registrar.py b/st2common/tests/unit/test_policies_registrar.py index 54f7f139c0..0dae958523 100644 --- a/st2common/tests/unit/test_policies_registrar.py +++ b/st2common/tests/unit/test_policies_registrar.py @@ -88,7 +88,7 @@ def test_register_all_policies(self): } }, 'cancel_on_concurrency': { - 'pack': 'mistral_tests', + 'pack': 'orquesta_tests', 'type': 'action.concurrency', 'parameters': { 'action': 'cancel', @@ -96,7 +96,7 @@ def test_register_all_policies(self): } }, 'cancel_on_concurrency_by_attr': { - 'pack': 'mistral_tests', + 'pack': 'orquesta_tests', 'type': 'action.concurrency.attr', 'parameters': { 'action': 'cancel', diff --git a/st2common/tests/unit/test_query_base.py b/st2common/tests/unit/test_query_base.py index 69c12f9247..b5f2ff70fb 100644 --- a/st2common/tests/unit/test_query_base.py +++ b/st2common/tests/unit/test_query_base.py @@ -40,9 +40,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orqesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -52,9 +52,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_2 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orquesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb3' } @@ -64,9 +64,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_3 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orquesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb4' } @@ -108,9 +108,9 @@ def test_query_rescheduled(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orquesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -156,9 +156,9 @@ def test_query_completed(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orquesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -200,9 +200,9 @@ def test_state_db_entry_deleted(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'mistral_v2', + 'orquesta_runner', { - 'mistral': { + 'orquesta': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } diff --git a/st2common/tests/unit/test_runners_base.py b/st2common/tests/unit/test_runners_base.py index 1ba9c3d223..8faefc3099 100644 --- a/st2common/tests/unit/test_runners_base.py +++ b/st2common/tests/unit/test_runners_base.py @@ -36,9 +36,9 @@ def test_get_runner_failure_not_found(self): get_runner, 'invalid-name-not-found') def test_get_query_module_success(self): - query_module = get_query_module('mistral-v2') + query_module = get_query_module('orquesta_runner') - self.assertEqual(query_module.__name__, 'mistral_v2.query') + self.assertEqual(query_module.__name__, 'orquesta_runner.query') self.assertTrue(query_module.get_instance()) def test_get_query_module_failure_not_found(self): @@ -47,9 +47,9 @@ def test_get_query_module_failure_not_found(self): get_query_module, 'invalid-name-not-found') def test_get_callback_module_success(self): - callback_module = get_callback_module('mistral-v2') + callback_module = get_callback_module('orquesta_runner') - self.assertEqual(callback_module.__name__, 'mistral_v2.callback') + self.assertEqual(callback_module.__name__, 'orquesta_runner.callback') self.assertTrue(callback_module.get_instance()) def test_get_callback_module_failure_not_found(self): diff --git a/st2common/tests/unit/test_shell_action_system_model.py b/st2common/tests/unit/test_shell_action_system_model.py index 397ef62d06..29e53e7066 100644 --- a/st2common/tests/unit/test_shell_action_system_model.py +++ b/st2common/tests/unit/test_shell_action_system_model.py @@ -366,19 +366,14 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'position': 3, 'default': 'master', }, - 'update_mistral': { - 'type': 'boolean', - 'position': 4, - 'default': False - }, 'update_changelog': { 'type': 'boolean', - 'position': 5, + 'position': 4, 'default': False }, 'local_repo': { 'type': 'string', - 'position': 6, + 'position': 5, } } context = {} @@ -407,7 +402,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.0.0', 'fork': 'StackStorm', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repo' }) @@ -444,7 +438,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.1.0', 'fork': 'StackStorm1', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': True, # default value used 'local_repo': '/tmp/repob' }) @@ -481,7 +474,6 @@ def test_command_construction_correct_default_parameter_values_are_used(self): 'version': '3.2.0', 'fork': 'StackStorm2', 'branch': 'master', # default value used - 'update_mistral': False, # default value used 'update_changelog': False, # default value used 'local_repo': '/tmp/repoc' }) diff --git a/st2common/tests/unit/test_util_api.py b/st2common/tests/unit/test_util_api.py index 78e1b0ce12..99949532a1 100644 --- a/st2common/tests/unit/test_util_api.py +++ b/st2common/tests/unit/test_util_api.py @@ -20,7 +20,6 @@ from st2common.constants.api import DEFAULT_API_VERSION from st2common.util.api import get_base_public_api_url from st2common.util.api import get_full_public_api_url -from st2common.util.api import get_mistral_api_url from st2tests.config import parse_args from six.moves import zip parse_args() @@ -68,17 +67,3 @@ def test_get_full_public_api_url(self): cfg.CONF.auth.api_url = mock_value actual = get_full_public_api_url() self.assertEqual(actual, expected_result) - - def test_get_mistral_api_url(self): - cfg.CONF.set_override(name='api_url', override='http://127.0.0.1:9999', group='auth') - cfg.CONF.set_override(name='api_url', override=None, group='mistral') - - # No URL set, should fall back to auth.api_url - result = get_mistral_api_url() - self.assertEqual(result, 'http://127.0.0.1:9999/' + DEFAULT_API_VERSION) - - # mistral.api_url provided, should use that - cfg.CONF.set_override(name='api_url', override='http://10.0.0.0:9999', group='mistral') - - result = get_mistral_api_url() - self.assertEqual(result, 'http://10.0.0.0:9999/' + DEFAULT_API_VERSION) diff --git a/st2debug/st2debug/cmd/submit_debug_info.py b/st2debug/st2debug/cmd/submit_debug_info.py index 6fee8e6f73..5cfde304f7 100644 --- a/st2debug/st2debug/cmd/submit_debug_info.py +++ b/st2debug/st2debug/cmd/submit_debug_info.py @@ -19,10 +19,10 @@ By default the following information is included: - Logs from /var/log/st2 -- StackStorm and mistral config file (/etc/st2/st2.conf, /etc/mistral/mistral.conf) +- StackStorm config file (/etc/st2/st2.conf) - All the content (integration packs). - Information about your system and StackStorm installation (Operating system, - Python version, StackStorm version, Mistral version) + Python version, StackStorm version) Note: This script currently assumes it's running on Linux. """ @@ -64,7 +64,6 @@ from st2debug.utils.system_info import get_package_list from st2debug.utils.git_utils import get_repo_latest_revision_hash from st2debug.processors import process_st2_config -from st2debug.processors import process_mistral_config from st2debug.processors import process_content_pack_dir LOG = logging.getLogger(__name__) @@ -74,11 +73,9 @@ LOG_FILE_PATHS = [ '/var/log/st2/*.log', - '/var/log/mistral*.log' ] ST2_CONFIG_FILE_PATH = '/etc/st2/st2.conf' -MISTRAL_CONFIG_FILE_PATH = '/etc/mistral/mistral.conf' SHELL_COMMANDS = [] @@ -165,8 +162,6 @@ def __init__(self, include_logs, include_configs, include_content, include_syste config_file = config_file or {} self.st2_config_file_path = config_file.get('st2_config_file_path', ST2_CONFIG_FILE_PATH) - self.mistral_config_file_path = config_file.get('mistral_config_file_path', - MISTRAL_CONFIG_FILE_PATH) self.log_file_paths = config_file.get('log_file_paths', LOG_FILE_PATHS[:]) self.gpg_key = config_file.get('gpg_key', GPG_KEY) self.gpg_key_fingerprint = config_file.get('gpg_key_fingerprint', GPG_KEY_FINGERPRINT) @@ -175,10 +170,8 @@ def __init__(self, include_logs, include_configs, include_content, include_syste self.shell_commands = config_file.get('shell_commands', SHELL_COMMANDS) self.st2_config_file_name = os.path.basename(self.st2_config_file_path) - self.mistral_config_file_name = os.path.basename(self.mistral_config_file_path) self.config_file_paths = [ - self.st2_config_file_path, - self.mistral_config_file_path + self.st2_config_file_path ] def run(self, encrypt=False, upload=False, existing_file=None): @@ -354,9 +347,6 @@ def collect_config_files(self, output_path): st2_config_path = os.path.join(output_path, self.st2_config_file_name) process_st2_config(config_path=st2_config_path) - mistral_config_path = os.path.join(output_path, self.mistral_config_file_name) - process_mistral_config(config_path=mistral_config_path) - @staticmethod def collect_pack_content(output_path): """ @@ -510,8 +500,7 @@ def get_system_information(): 'memory': {} }, 'python': {}, - 'stackstorm': {}, - 'mistral': {} + 'stackstorm': {} } # Operating system information @@ -576,12 +565,6 @@ def get_system_information(): system_information['stackstorm']['installation_method'] = 'package' system_information['stackstorm']['packages'] = package_list - # Mistral information - repo_path = '/opt/openstack/mistral' - revision_hash = get_repo_latest_revision_hash(repo_path=repo_path) - system_information['mistral']['installation_method'] = 'source' - system_information['mistral']['revision_hash'] = revision_hash - return system_information diff --git a/st2debug/st2debug/processors.py b/st2debug/st2debug/processors.py index 1ed1fcab76..884d468198 100644 --- a/st2debug/st2debug/processors.py +++ b/st2debug/st2debug/processors.py @@ -18,7 +18,6 @@ __all__ = [ 'process_st2_config', - 'process_mistral_config', 'process_content_pack_dir' ] @@ -29,11 +28,6 @@ } -# Options which should be removed from the st2 config -MISTRAL_CONF_OPTIONS_TO_REMOVE = { - 'database': ['connection'] -} - REMOVED_VALUE_NAME = '**removed**' @@ -61,30 +55,6 @@ def process_st2_config(config_path): config.write(fp) -def process_mistral_config(config_path): - """ - Remove sensitive data (credentials) from the Mistral config. - - :param config_path: Full absolute path to the mistral config inside /tmp. - :type config_path: ``str`` - """ - assert config_path.startswith('/tmp') - - if not os.path.isfile(config_path): - return - - config = ConfigParser() - config.read(config_path) - - for section, options in MISTRAL_CONF_OPTIONS_TO_REMOVE.items(): - for option in options: - if config.has_option(section, option): - config.set(section, option, REMOVED_VALUE_NAME) - - with open(config_path, 'w') as fp: - config.write(fp) - - def process_content_pack_dir(pack_dir): """ Remove config.yaml from the pack directory. diff --git a/st2debug/tests/integration/test_submit_debug_info.py b/st2debug/tests/integration/test_submit_debug_info.py index 78158d6941..2e18cd782f 100644 --- a/st2debug/tests/integration/test_submit_debug_info.py +++ b/st2debug/tests/integration/test_submit_debug_info.py @@ -44,8 +44,6 @@ def setUp(self): configs_dir = os.path.join(FIXTURES_DIR, 'configs/') st2debug.cmd.submit_debug_info.ST2_CONFIG_FILE_PATH = os.path.join(configs_dir, 'st2.conf') - st2debug.cmd.submit_debug_info.MISTRAL_CONFIG_FILE_PATH = os.path.join(configs_dir, - 'mistral.conf') # Mock get_packs_base_paths content_dir = os.path.join(FIXTURES_DIR, 'content/') @@ -80,7 +78,6 @@ def test_config_option_overrides_defaults(self): 'log/path/1' ], 'st2_config_file_path': 'st2/config/path', - 'mistral_config_file_path': 'mistral/config/path', 's3_bucket_url': 'my_s3_url', 'gpg_key_fingerprint': 'my_gpg_fingerprint', 'gpg_key': 'my_gpg_key', @@ -99,8 +96,6 @@ def test_config_option_overrides_defaults(self): self.assertEqual(debug_collector.log_file_paths, ['log/path/1', 'log/path/1']) self.assertEqual(debug_collector.st2_config_file_path, 'st2/config/path') self.assertEqual(debug_collector.st2_config_file_name, 'path') - self.assertEqual(debug_collector.mistral_config_file_path, 'mistral/config/path') - self.assertEqual(debug_collector.mistral_config_file_name, 'path') self.assertEqual(debug_collector.s3_bucket_url, 'my_s3_url') self.assertEqual(debug_collector.gpg_key, 'my_gpg_key') self.assertEqual(debug_collector.gpg_key_fingerprint, 'my_gpg_fingerprint') @@ -235,9 +230,7 @@ def _verify_archive(self, archive_path, extract_path, required_directories): # Verify configs have been copied st2_config_path = os.path.join(extract_path, 'configs', 'st2.conf') - mistral_config_path = os.path.join(extract_path, 'configs', 'mistral.conf') self.assertTrue(os.path.isfile(st2_config_path)) - self.assertTrue(os.path.isfile(mistral_config_path)) # Verify packs have been copied content_path = os.path.join(extract_path, 'content/dir-1') @@ -248,17 +241,11 @@ def _verify_archive(self, archive_path, extract_path, required_directories): with open(st2_config_path, 'r') as fp: st2_config_content = fp.read() - with open(mistral_config_path, 'r') as fp: - mistral_config_content = fp.read() - self.assertNotIn('ponies', st2_config_content) self.assertIn('username = **removed**', st2_config_content) self.assertIn('password = **removed**', st2_config_content) self.assertIn('url = **removed**', st2_config_content) - self.assertNotIn('StackStorm', mistral_config_content) - self.assertIn('connection = **removed**', mistral_config_content) - # Very config.yaml has been removed from the content pack directories pack_dir = os.path.join(content_path, 'twilio') config_path = os.path.join(pack_dir, 'config.yaml') @@ -272,7 +259,6 @@ def _get_yaml_config(self): os.path.join(FIXTURES_DIR, 'logs/st2*.log') ], 'st2_config_file_path': os.path.join(FIXTURES_DIR, 'configs/st2.conf'), - 'mistral_config_file_path': os.path.join(FIXTURES_DIR, 'configs/mistral.conf'), 's3_bucket_url': S3_BUCKET_URL, 'gpg_key_fingerprint': GPG_KEY_FINGERPRINT, 'gpg_key': GPG_KEY, diff --git a/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml b/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml new file mode 100644 index 0000000000..acb0e19e9d --- /dev/null +++ b/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml @@ -0,0 +1,10 @@ +--- +action: foo.mistral.wf1 +callback: {} +context: + user: system +end_timestamp: '2014-09-01T00:00:05.000000Z' +parameters: {} +result: {} +start_timestamp: '2014-09-01T00:00:01.000000Z' +status: requested From 75037973a06e7104ae1eee1afd94357187dadeea Mon Sep 17 00:00:00 2001 From: Cloud User Date: Thu, 6 Aug 2020 17:01:46 +0000 Subject: [PATCH 03/26] Fix some unit-tests --- lint-configs/python/.pylintrc | 2 +- .../unit/test_paramiko_remote_script_runner.py | 6 +++--- .../unit/controllers/v1/test_executions.py | 2 +- st2api/tests/unit/controllers/v1/test_packs.py | 6 +++--- .../execution_result_has_carriage_return.txt | 2 +- .../tests/unit/test_execution_tail_command.py | 1 - st2common/tests/unit/test_policies_registrar.py | 17 ----------------- st2common/tests/unit/test_runners_base.py | 12 ------------ .../unit/test_shell_action_system_model.py | 6 +++--- 9 files changed, 12 insertions(+), 42 deletions(-) diff --git a/lint-configs/python/.pylintrc b/lint-configs/python/.pylintrc index 3bca8cefb4..8f3ff52af3 100644 --- a/lint-configs/python/.pylintrc +++ b/lint-configs/python/.pylintrc @@ -26,7 +26,7 @@ property-classes=abc.abstractproperty [TYPECHECK] # Note: This modules are manipulated during the runtime so we can't detect all the properties during # static analysis -ignored-modules=distutils,eventlet.green.subprocess,six,six.moves,mistralclient.api.v2.executions +ignored-modules=distutils,eventlet.green.subprocess,six,six.moves [FORMAT] max-line-length=100 diff --git a/st2actions/tests/unit/test_paramiko_remote_script_runner.py b/st2actions/tests/unit/test_paramiko_remote_script_runner.py index 25e03b3194..389e8b3a82 100644 --- a/st2actions/tests/unit/test_paramiko_remote_script_runner.py +++ b/st2actions/tests/unit/test_paramiko_remote_script_runner.py @@ -183,7 +183,7 @@ def test_command_construction_correct_default_parameter_values_are_used(self): ) command_string = remote_action.get_full_command_string() - expected = 'cd /test/cwd/ && /tmp/script.sh st2flow 3.0.0 StackStorm master 0 0 /tmp/repo' + expected = 'cd /test/cwd/ && /tmp/script.sh st2flow 3.0.0 StackStorm master 0 /tmp/repo' self.assertEqual(command_string, expected) # 2. Some default values used @@ -223,7 +223,7 @@ def test_command_construction_correct_default_parameter_values_are_used(self): ) command_string = remote_action.get_full_command_string() - expected = 'cd /test/cwd/ && /tmp/script.sh st2web 3.1.0 StackStorm1 master 0 1 /tmp/repob' + expected = 'cd /test/cwd/ && /tmp/script.sh st2web 3.1.0 StackStorm1 master 1 /tmp/repob' self.assertEqual(command_string, expected) # 3. None is specified for a boolean parameter, should use a default @@ -263,5 +263,5 @@ def test_command_construction_correct_default_parameter_values_are_used(self): ) command_string = remote_action.get_full_command_string() - expected = 'cd /test/cwd/ && /tmp/script.sh st2rbac 3.2.0 StackStorm2 master 0 0 /tmp/repoc' + expected = 'cd /test/cwd/ && /tmp/script.sh st2rbac 3.2.0 StackStorm2 master 0 /tmp/repoc' self.assertEqual(command_string, expected) diff --git a/st2api/tests/unit/controllers/v1/test_executions.py b/st2api/tests/unit/controllers/v1/test_executions.py index e62a024387..099abf6ae2 100644 --- a/st2api/tests/unit/controllers/v1/test_executions.py +++ b/st2api/tests/unit/controllers/v1/test_executions.py @@ -129,7 +129,7 @@ 'enabled': True, 'entry_point': '/tmp/test/workflows/action4.yaml', 'pack': 'starterpack', - 'runner_type': 'orquesta-runner', + 'runner_type': 'orquesta', 'parameters': { 'a': { 'type': 'string', diff --git a/st2api/tests/unit/controllers/v1/test_packs.py b/st2api/tests/unit/controllers/v1/test_packs.py index 7c7d8cc5d5..78b0e6fef6 100644 --- a/st2api/tests/unit/controllers/v1/test_packs.py +++ b/st2api/tests/unit/controllers/v1/test_packs.py @@ -539,14 +539,14 @@ def test_packs_register_endpoint(self, mock_get_packs): {'packs': ['dummy_pack_1'], 'types': ['action']}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) + self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) # Verify that plural name form also works resp = self.app.post_json('/v1/packs/register', {'packs': ['dummy_pack_1'], 'types': ['actions']}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) + self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) # Register single resource from a single pack specified multiple times - verify that # resources from the same pack are only registered once @@ -556,7 +556,7 @@ def test_packs_register_endpoint(self, mock_get_packs): 'fail_on_failure': False}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) + self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) # Register resources from a single (non-existent pack) resp = self.app.post_json('/v1/packs/register', {'packs': ['doesntexist']}, diff --git a/st2client/tests/fixtures/execution_result_has_carriage_return.txt b/st2client/tests/fixtures/execution_result_has_carriage_return.txt index 749bcb3a72..d081a67a42 100644 --- a/st2client/tests/fixtures/execution_result_has_carriage_return.txt +++ b/st2client/tests/fixtures/execution_result_has_carriage_return.txt @@ -46,7 +46,7 @@ | | st2api PID: 16614 | | | sensor_container is not running | | | history PID: 16616 | -| | rules_engine PID: 16617 | +| | rules_engine PID: 16617" | | | } | | | }, | | | "delete": { | diff --git a/st2client/tests/unit/test_execution_tail_command.py b/st2client/tests/unit/test_execution_tail_command.py index 9be6c356b1..0acc3289bb 100644 --- a/st2client/tests/unit/test_execution_tail_command.py +++ b/st2client/tests/unit/test_execution_tail_command.py @@ -23,7 +23,6 @@ from st2client.commands.action import LIVEACTION_STATUS_RUNNING from st2client.commands.action import LIVEACTION_STATUS_SUCCEEDED from st2client.commands.action import LIVEACTION_STATUS_FAILED -from st2client.commands.action import LIVEACTION_STATUS_TIMED_OUT from st2client.shell import Shell __all__ = [ diff --git a/st2common/tests/unit/test_policies_registrar.py b/st2common/tests/unit/test_policies_registrar.py index 0dae958523..62340642fc 100644 --- a/st2common/tests/unit/test_policies_registrar.py +++ b/st2common/tests/unit/test_policies_registrar.py @@ -87,23 +87,6 @@ def test_register_all_policies(self): 'max_retry_count': 5 } }, - 'cancel_on_concurrency': { - 'pack': 'orquesta_tests', - 'type': 'action.concurrency', - 'parameters': { - 'action': 'cancel', - 'threshold': 3 - } - }, - 'cancel_on_concurrency_by_attr': { - 'pack': 'orquesta_tests', - 'type': 'action.concurrency.attr', - 'parameters': { - 'action': 'cancel', - 'threshold': 1, - 'attributes': ['friend'] - } - }, 'sequential.retry_on_failure': { 'pack': 'orquesta_tests', 'type': 'action.retry', diff --git a/st2common/tests/unit/test_runners_base.py b/st2common/tests/unit/test_runners_base.py index 8faefc3099..2587a792a8 100644 --- a/st2common/tests/unit/test_runners_base.py +++ b/st2common/tests/unit/test_runners_base.py @@ -35,23 +35,11 @@ def test_get_runner_failure_not_found(self): self.assertRaisesRegexp(ActionRunnerCreateError, expected_msg, get_runner, 'invalid-name-not-found') - def test_get_query_module_success(self): - query_module = get_query_module('orquesta_runner') - - self.assertEqual(query_module.__name__, 'orquesta_runner.query') - self.assertTrue(query_module.get_instance()) - def test_get_query_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' self.assertRaisesRegexp(NoMatches, expected_msg, get_query_module, 'invalid-name-not-found') - def test_get_callback_module_success(self): - callback_module = get_callback_module('orquesta_runner') - - self.assertEqual(callback_module.__name__, 'orquesta_runner.callback') - self.assertTrue(callback_module.get_instance()) - def test_get_callback_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' self.assertRaisesRegexp(NoMatches, expected_msg, diff --git a/st2common/tests/unit/test_shell_action_system_model.py b/st2common/tests/unit/test_shell_action_system_model.py index 29e53e7066..70e7fff805 100644 --- a/st2common/tests/unit/test_shell_action_system_model.py +++ b/st2common/tests/unit/test_shell_action_system_model.py @@ -416,7 +416,7 @@ def test_command_construction_correct_default_parameter_values_are_used(self): positional_args=positional_args) command_string = shell_script_action.get_full_command_string() - expected = '/tmp/local.sh st2flow 3.0.0 StackStorm master 0 0 /tmp/repo' + expected = '/tmp/local.sh st2flow 3.0.0 StackStorm master 0 /tmp/repo' self.assertEqual(command_string, expected) # 2. Some default values used @@ -452,7 +452,7 @@ def test_command_construction_correct_default_parameter_values_are_used(self): positional_args=positional_args) command_string = shell_script_action.get_full_command_string() - expected = '/tmp/local.sh st2web 3.1.0 StackStorm1 master 0 1 /tmp/repob' + expected = '/tmp/local.sh st2web 3.1.0 StackStorm1 master 1 /tmp/repob' self.assertEqual(command_string, expected) # 3. None is specified for a boolean parameter, should use a default @@ -488,5 +488,5 @@ def test_command_construction_correct_default_parameter_values_are_used(self): positional_args=positional_args) command_string = shell_script_action.get_full_command_string() - expected = '/tmp/local.sh st2rbac 3.2.0 StackStorm2 master 0 0 /tmp/repoc' + expected = '/tmp/local.sh st2rbac 3.2.0 StackStorm2 master 0 /tmp/repoc' self.assertEqual(command_string, expected) From 085fc7afa5fd8b10ed312e269ae9c7d30860158b Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 08:59:49 +0100 Subject: [PATCH 04/26] Amend name in test action --- st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml b/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml index acb0e19e9d..3f1c80cde5 100644 --- a/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml +++ b/st2tests/st2tests/fixtures/generic/liveactions/liveaction2.yaml @@ -1,5 +1,5 @@ --- -action: foo.mistral.wf1 +action: foo.orquesta.wf1 callback: {} context: user: system From c688c7193adfbcca66e7aa98fa453c04d8033d1d Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 09:58:25 +0100 Subject: [PATCH 05/26] Update requirements-used-for-tests --- st2common/tests/fixtures/requirements-used-for-tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/st2common/tests/fixtures/requirements-used-for-tests.txt b/st2common/tests/fixtures/requirements-used-for-tests.txt index 40cfdfe356..3fbf5f14d0 100644 --- a/st2common/tests/fixtures/requirements-used-for-tests.txt +++ b/st2common/tests/fixtures/requirements-used-for-tests.txt @@ -9,7 +9,6 @@ flex==6.14.0 # commments.... git+https://github.com/Kami/logshipper.git@stackstorm_patched#egg=logshipper git+https://github.com/StackStorm/orquesta.git@224c1a589a6007eb0598a62ee99d674e7836d369#egg=orquesta -git+https://github.com/StackStorm/python-mistralclient.git#egg=python-mistralclient git+https://github.com/StackStorm/st2-auth-backend-flat-file.git@master#egg=st2-auth-backend-flat-file -e git+https://github.com/Kami/logshipper.git@stackstorm_patched#egg=logshipper-editable git+https://github.com/StackStorm/st2.git#egg=python_runner&subdirectory=contrib/runners/python_runner From 3e53e6b9200892fee0563e536dba8de112b62d86 Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 12:25:00 +0100 Subject: [PATCH 06/26] Add integration orquesta re-run test, as only had mistral before --- .../orquesta-test-rerun-with-items.yaml | 11 ++++ .../tests/orquesta-test-rerun-with-items.yaml | 13 +++++ .../integration/orquesta/test_wiring_rerun.py | 53 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 contrib/examples/actions/orquesta-test-rerun-with-items.yaml create mode 100644 contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml diff --git a/contrib/examples/actions/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/orquesta-test-rerun-with-items.yaml new file mode 100644 index 0000000000..43336262c3 --- /dev/null +++ b/contrib/examples/actions/orquesta-test-rerun-with-items.yaml @@ -0,0 +1,11 @@ +--- +name: orquesta-test-rerun-with-items +description: A sample workflow used to test the rerun feature. +pack: examples +runner_type: orquesta +entry_point: workflows/tests/orquesta-test-rerun-with-items.yaml +enabled: true +parameters: + tempfile: + type: string + required: true diff --git a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml new file mode 100644 index 0000000000..1fd694fbda --- /dev/null +++ b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml @@ -0,0 +1,13 @@ +version: '1.0' + +description: A sample workflow used to test the rerun feature. + +input: + - tempfile + +tasks: + task1: + with: [0, 1, 2, 3] + action: core.local + input: + cmd: 'x=`cat <% $.tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' diff --git a/st2tests/integration/orquesta/test_wiring_rerun.py b/st2tests/integration/orquesta/test_wiring_rerun.py index 7be73dfc19..72f036f887 100644 --- a/st2tests/integration/orquesta/test_wiring_rerun.py +++ b/st2tests/integration/orquesta/test_wiring_rerun.py @@ -95,3 +95,56 @@ def test_rerun_task_of_workflow_already_succeeded(self): self.assertNotEqual(ex.id, orig_st2_ex_id) ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + + def test_rerun_and_reset_with_items_task(self): + path = self.temp_dir_path + + with open(path, 'w') as f: + f.write('1') + + params = {'tempfile': path} + ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) + orig_st2_ex_id = ex.id + orig_wf_ex_id = ex.context['workflow_execution'] + + with open(path, 'w') as f: + f.write('0') + + ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1']) + self.assertNotEqual(ex.id, orig_st2_ex_id) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) + self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + self.assertEqual(len(ex.result.get('tasks', [])), 1) + + children = self.st2client.executions.get_property(ex.id, 'children') + self.assertEqual(len(children), 4) + + + def test_rerun_and_resume_with_items_task(self): + path = self.temp_dir_path + + with open(path, 'w') as f: + f.write('1') + + params = {'tempfile': path} + ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) + orig_st2_ex_id = ex.id + orig_wf_ex_id = ex.context['workflow_execution'] + + with open(path, 'w') as f: + f.write('0') + + ex = self.st2client.executions.re_run( + orig_st2_ex_id, + tasks=['task1'], + no_reset=['task1'] + ) + self.assertNotEqual(ex.id, orig_st2_ex_id) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) + self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + self.assertEqual(len(ex.result.get('tasks', [])), 1) + + children = self.st2client.executions.get_property(ex.id, 'children') + self.assertEqual(len(children), 2) From 07629756d2463f5bf50aed77575b50ddf173305c Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 12:51:02 +0100 Subject: [PATCH 07/26] Fix lint and amend new test yaml --- .../workflows/tests/orquesta-test-rerun-with-items.yaml | 6 +++--- st2tests/integration/orquesta/test_wiring_rerun.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml index 1fd694fbda..08837c061d 100644 --- a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml +++ b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml @@ -1,13 +1,13 @@ -version: '1.0' +version: 1.0 description: A sample workflow used to test the rerun feature. input: - tempfile - + tasks: task1: with: [0, 1, 2, 3] action: core.local input: - cmd: 'x=`cat <% $.tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' + cmd: 'x=`cat <% ctx().tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' diff --git a/st2tests/integration/orquesta/test_wiring_rerun.py b/st2tests/integration/orquesta/test_wiring_rerun.py index 72f036f887..4385b92fd7 100644 --- a/st2tests/integration/orquesta/test_wiring_rerun.py +++ b/st2tests/integration/orquesta/test_wiring_rerun.py @@ -120,7 +120,6 @@ def test_rerun_and_reset_with_items_task(self): children = self.st2client.executions.get_property(ex.id, 'children') self.assertEqual(len(children), 4) - def test_rerun_and_resume_with_items_task(self): path = self.temp_dir_path From 54738081b38088f9526d22916cb0e01a53217e43 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Fri, 7 Aug 2020 12:52:04 +0000 Subject: [PATCH 08/26] Amend new orquesta test yaml file --- .../actions/workflows/tests/orquesta-test-rerun-with-items.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml index 08837c061d..6cad01beea 100644 --- a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml +++ b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml @@ -7,7 +7,7 @@ input: tasks: task1: - with: [0, 1, 2, 3] + with: <% range(0,4) %> action: core.local input: cmd: 'x=`cat <% ctx().tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' From d443efa0a8755d99adedd84c508a39de2d4edec7 Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 16:56:33 +0100 Subject: [PATCH 09/26] Removing re-run orquesta with items due to https://github.com/StackStorm/st2/issues/5016 --- .../orquesta-test-rerun-with-items.yaml | 11 ---- .../tests/orquesta-test-rerun-with-items.yaml | 13 ----- .../integration/orquesta/test_wiring_rerun.py | 52 ------------------- 3 files changed, 76 deletions(-) delete mode 100644 contrib/examples/actions/orquesta-test-rerun-with-items.yaml delete mode 100644 contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml diff --git a/contrib/examples/actions/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/orquesta-test-rerun-with-items.yaml deleted file mode 100644 index 43336262c3..0000000000 --- a/contrib/examples/actions/orquesta-test-rerun-with-items.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: orquesta-test-rerun-with-items -description: A sample workflow used to test the rerun feature. -pack: examples -runner_type: orquesta -entry_point: workflows/tests/orquesta-test-rerun-with-items.yaml -enabled: true -parameters: - tempfile: - type: string - required: true diff --git a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml deleted file mode 100644 index 6cad01beea..0000000000 --- a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml +++ /dev/null @@ -1,13 +0,0 @@ -version: 1.0 - -description: A sample workflow used to test the rerun feature. - -input: - - tempfile - -tasks: - task1: - with: <% range(0,4) %> - action: core.local - input: - cmd: 'x=`cat <% ctx().tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' diff --git a/st2tests/integration/orquesta/test_wiring_rerun.py b/st2tests/integration/orquesta/test_wiring_rerun.py index 4385b92fd7..7be73dfc19 100644 --- a/st2tests/integration/orquesta/test_wiring_rerun.py +++ b/st2tests/integration/orquesta/test_wiring_rerun.py @@ -95,55 +95,3 @@ def test_rerun_task_of_workflow_already_succeeded(self): self.assertNotEqual(ex.id, orig_st2_ex_id) ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) - - def test_rerun_and_reset_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - params = {'tempfile': path} - ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['workflow_execution'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1']) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 4) - - def test_rerun_and_resume_with_items_task(self): - path = self.temp_dir_path - - with open(path, 'w') as f: - f.write('1') - - params = {'tempfile': path} - ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) - orig_st2_ex_id = ex.id - orig_wf_ex_id = ex.context['workflow_execution'] - - with open(path, 'w') as f: - f.write('0') - - ex = self.st2client.executions.re_run( - orig_st2_ex_id, - tasks=['task1'], - no_reset=['task1'] - ) - self.assertNotEqual(ex.id, orig_st2_ex_id) - ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) - self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) - self.assertEqual(len(ex.result.get('tasks', [])), 1) - - children = self.st2client.executions.get_property(ex.id, 'children') - self.assertEqual(len(children), 2) From eab2c0809212513673fd62613be6c7e4e64061ce Mon Sep 17 00:00:00 2001 From: amanda Date: Fri, 7 Aug 2020 18:04:07 +0100 Subject: [PATCH 10/26] Create orquesta with-items re-run test as validated that issue seen was only if ALL tasks passed --- .../orquesta-test-rerun-with-items.yaml | 11 ++++ .../tests/orquesta-test-rerun-with-items.yaml | 14 ++++++ st2client/st2client/commands/action.py | 2 +- .../integration/orquesta/test_wiring_rerun.py | 50 +++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 contrib/examples/actions/orquesta-test-rerun-with-items.yaml create mode 100644 contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml diff --git a/contrib/examples/actions/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/orquesta-test-rerun-with-items.yaml new file mode 100644 index 0000000000..43336262c3 --- /dev/null +++ b/contrib/examples/actions/orquesta-test-rerun-with-items.yaml @@ -0,0 +1,11 @@ +--- +name: orquesta-test-rerun-with-items +description: A sample workflow used to test the rerun feature. +pack: examples +runner_type: orquesta +entry_point: workflows/tests/orquesta-test-rerun-with-items.yaml +enabled: true +parameters: + tempfile: + type: string + required: true diff --git a/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml new file mode 100644 index 0000000000..fb4045d724 --- /dev/null +++ b/contrib/examples/actions/workflows/tests/orquesta-test-rerun-with-items.yaml @@ -0,0 +1,14 @@ +version: 1.0 + +description: A sample workflow used to test the rerun feature. + +input: + - tempfile + +tasks: + task1: + with: <% range(0,4) %> + action: core.local + input: + cmd: 'x=`cat <% ctx().tempfile %>`; y=`echo "$x * <% item() %> % 2" | bc`; exit `echo $y`' + diff --git a/st2client/st2client/commands/action.py b/st2client/st2client/commands/action.py index 540c0cd368..a9a562258b 100644 --- a/st2client/st2client/commands/action.py +++ b/st2client/st2client/commands/action.py @@ -1266,7 +1266,7 @@ def __init__(self, resource, *args, **kwargs): help='Name of the workflow tasks to re-run.') self.parser.add_argument('--no-reset', dest='no_reset', nargs='*', help='Name of the with-items tasks to not reset. This only ' - 'applies to Mistral workflows. By default, all iterations ' + 'applies to Orquesta workflows. By default, all iterations ' 'for with-items tasks is rerun. If no reset, only failed ' ' iterations are rerun.') self.parser.add_argument('-a', '--async', diff --git a/st2tests/integration/orquesta/test_wiring_rerun.py b/st2tests/integration/orquesta/test_wiring_rerun.py index 7be73dfc19..8d83e99838 100644 --- a/st2tests/integration/orquesta/test_wiring_rerun.py +++ b/st2tests/integration/orquesta/test_wiring_rerun.py @@ -95,3 +95,53 @@ def test_rerun_task_of_workflow_already_succeeded(self): self.assertNotEqual(ex.id, orig_st2_ex_id) ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + + def test_rerun_and_reset_with_items_task(self): + path = self.temp_dir_path + + with open(path, 'w') as f: + f.write('1') + + params = {'tempfile': path} + ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) + orig_st2_ex_id = ex.id + orig_wf_ex_id = ex.context['workflow_execution'] + + with open(path, 'w') as f: + f.write('0') + + ex = self.st2client.executions.re_run(orig_st2_ex_id, tasks=['task1']) + self.assertNotEqual(ex.id, orig_st2_ex_id) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) + self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + + children = self.st2client.executions.get_property(ex.id, 'children') + self.assertEqual(len(children), 4) + + def test_rerun_and_resume_with_items_task(self): + path = self.temp_dir_path + + with open(path, 'w') as f: + f.write('1') + + params = {'tempfile': path} + ex = self._execute_workflow('examples.orquesta-test-rerun-with-items', params) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_FAILED) + orig_st2_ex_id = ex.id + orig_wf_ex_id = ex.context['workflow_execution'] + + with open(path, 'w') as f: + f.write('0') + + ex = self.st2client.executions.re_run( + orig_st2_ex_id, + tasks=['task1'], + no_reset=['task1'] + ) + self.assertNotEqual(ex.id, orig_st2_ex_id) + ex = self._wait_for_state(ex, action_constants.LIVEACTION_STATUS_SUCCEEDED) + self.assertEqual(ex.context['workflow_execution'], orig_wf_ex_id) + + children = self.st2client.executions.get_property(ex.id, 'children') + self.assertEqual(len(children), 2) From c2d38a41b63693575dacc36e4fe8a9b514e81061 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Mon, 10 Aug 2020 15:03:17 +0000 Subject: [PATCH 11/26] Minor fixes --- st2common/bin/st2-track-result | 61 ---------------------------------- 1 file changed, 61 deletions(-) diff --git a/st2common/bin/st2-track-result b/st2common/bin/st2-track-result index 890c40d7a9..121b46bb98 100755 --- a/st2common/bin/st2-track-result +++ b/st2common/bin/st2-track-result @@ -44,66 +44,5 @@ def setup(): script_setup.setup(config, register_mq_exchanges=False) -def add_result_tracker(exec_id): - LOG.info('Retrieving action execution record...') - exec_db = ActionExecution.get_by_id(exec_id) - LOG.info('Found action execution record for "%s".', exec_id) - - # Check runner type. - runner_type = exec_db.action.get('runner_type') - - # Skip if action execution is completed. - if exec_db.status in action_constants.LIVEACTION_COMPLETED_STATES: - LOG.info('Action execution "%s" is already in a completed state.', exec_id) - LOG.info('Result tracker entry is not created.') - return - - LOG.info('Retrieving runner type and liveaction records...') - runnertype_db = action_db.get_runnertype_by_name(exec_db.action.get('runner_type')) - liveaction_db = action_db.get_liveaction_by_id(exec_db.liveaction['id']) - - # Skip if liveaction is completed. - if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: - LOG.info('Liveaction "%s" is already in a completed state.', liveaction_db.id) - LOG.info('Result tracker entry is not created.') - return - - # Add query into action execution state DB - try: - LOG.info('Inserting new request tracker entry...') - queries.setup_query(liveaction_db.id, runnertype_db, liveaction_db.context) - LOG.info('Successfully inserted the result tracker entry.') - except (db_exc.StackStormDBObjectConflictError, me.NotUniqueError): - LOG.error('Action execution "%s" already has a result tracker entry.', exec_id) - except Exception as e: - LOG.error('Unable to create result tracker entry for "%s". %s', exec_id, str(e)) - - # Add result tracker for children workflows. - for child_exec_id in exec_db.children: - child_exec = ActionExecution.get(id=child_exec_id, raise_exception=True) - - -def del_result_tracker(exec_id): - LOG.info('Retrieving action execution record...') - exec_db = ActionExecution.get_by_id(exec_id) - LOG.info('Found action execution record for "%s".', exec_id) - - LOG.info('Retrieving runner type and liveaction records...') - liveaction_db = action_db.get_liveaction_by_id(exec_db.liveaction['id']) - - LOG.info('Removing result tracker entry...') - removed = queries.remove_query(liveaction_db.id) - - if removed: - LOG.info('Successfully removed the result tracker entry.') - else: - LOG.info('There is no result tracker entry to remove.') - - if __name__ == '__main__': setup() - - if not cfg.CONF.delete: - add_result_tracker(cfg.CONF.id) - else: - del_result_tracker(cfg.CONF.id) From 71ad684462d412a75df14aab2f6da1d77a99c867 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Mon, 10 Aug 2020 15:24:14 +0000 Subject: [PATCH 12/26] tools/launchdev.sh --- tools/launchdev.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/launchdev.sh b/tools/launchdev.sh index 0086a77885..74c22af430 100755 --- a/tools/launchdev.sh +++ b/tools/launchdev.sh @@ -13,7 +13,7 @@ copy_test_packs=false load_content=true use_ipv6=false -while getopts ":r:s:w:gxcu6m" o; do +while getopts ":r:s:w:gxcu6" o; do case "${o}" in r) runner_count=${OPTARG} From a20f9dc7f31a6eacca25306db834ed42cad5aeee Mon Sep 17 00:00:00 2001 From: Cloud User Date: Mon, 10 Aug 2020 17:22:46 +0000 Subject: [PATCH 13/26] Add simple JSON --- st2api/in-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/st2api/in-requirements.txt b/st2api/in-requirements.txt index 1b1bd859d4..fcb639a58b 100644 --- a/st2api/in-requirements.txt +++ b/st2api/in-requirements.txt @@ -9,3 +9,4 @@ oslo.utils pymongo six gunicorn +simplejson From 446642deac3a4b049190de7efff04571afe832e0 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Mon, 10 Aug 2020 17:31:33 +0000 Subject: [PATCH 14/26] Add requirements after rebuilt --- requirements.txt | 1 + st2api/requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index 740333180f..8dd7ad0e55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -56,6 +56,7 @@ requests[security]==2.23.0 retrying==1.3.3 routes==2.4.1 semver==2.9.0 +simplejson six==1.13.0 sseclient-py==1.7 stevedore==1.30.1 diff --git a/st2api/requirements.txt b/st2api/requirements.txt index 7a920a843f..051999210c 100644 --- a/st2api/requirements.txt +++ b/st2api/requirements.txt @@ -13,4 +13,5 @@ mongoengine==0.18.2 oslo.config<1.13,>=1.12.1 oslo.utils<=3.37.0,>=3.36.2 pymongo==3.10.0 +simplejson six==1.13.0 From ff67a999adc4669c011ccd1552bd1d760d3f0165 Mon Sep 17 00:00:00 2001 From: amanda Date: Mon, 10 Aug 2020 19:51:25 +0100 Subject: [PATCH 15/26] Put back result tracker --- st2common/bin/st2-track-result | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/st2common/bin/st2-track-result b/st2common/bin/st2-track-result index 121b46bb98..44a33cc1d6 100755 --- a/st2common/bin/st2-track-result +++ b/st2common/bin/st2-track-result @@ -44,5 +44,76 @@ def setup(): script_setup.setup(config, register_mq_exchanges=False) +def add_result_tracker(exec_id): + LOG.info('Retrieving action execution record...') + exec_db = ActionExecution.get_by_id(exec_id) + LOG.info('Found action execution record for "%s".', exec_id) + + # Check runner type. + runner_type = exec_db.action.get('runner_type') + + # Although mistral runner is removed, we want to leave in the result + # tracker so it can be enabled for other runners easily. Adjust this + # if when runners that support result tracker are added. + if runner_type != 'mistral-v2': + LOG.error('Result tracker is only supported for Mistral workflows.') + return + + # Skip if action execution is completed. + if exec_db.status in action_constants.LIVEACTION_COMPLETED_STATES: + LOG.info('Action execution "%s" is already in a completed state.', exec_id) + LOG.info('Result tracker entry is not created.') + return + + LOG.info('Retrieving runner type and liveaction records...') + runnertype_db = action_db.get_runnertype_by_name(exec_db.action.get('runner_type')) + liveaction_db = action_db.get_liveaction_by_id(exec_db.liveaction['id']) + + # Skip if liveaction is completed. + if liveaction_db.status in action_constants.LIVEACTION_COMPLETED_STATES: + LOG.info('Liveaction "%s" is already in a completed state.', liveaction_db.id) + LOG.info('Result tracker entry is not created.') + return + + # Add query into action execution state DB + try: + LOG.info('Inserting new request tracker entry...') + queries.setup_query(liveaction_db.id, runnertype_db, liveaction_db.context) + LOG.info('Successfully inserted the result tracker entry.') + except (db_exc.StackStormDBObjectConflictError, me.NotUniqueError): + LOG.error('Action execution "%s" already has a result tracker entry.', exec_id) + except Exception as e: + LOG.error('Unable to create result tracker entry for "%s". %s', exec_id, str(e)) + + # Add result tracker for children workflows. + for child_exec_id in exec_db.children: + child_exec = ActionExecution.get(id=child_exec_id, raise_exception=True) + if child_exec.runner['name'] == 'mistral-v2': + LOG.info('Adding result tracker for children "%s"...', child_exec_id) + add_result_tracker(child_exec_id) + + +def del_result_tracker(exec_id): + LOG.info('Retrieving action execution record...') + exec_db = ActionExecution.get_by_id(exec_id) + LOG.info('Found action execution record for "%s".', exec_id) + + LOG.info('Retrieving runner type and liveaction records...') + liveaction_db = action_db.get_liveaction_by_id(exec_db.liveaction['id']) + + LOG.info('Removing result tracker entry...') + removed = queries.remove_query(liveaction_db.id) + + if removed: + LOG.info('Successfully removed the result tracker entry.') + else: + LOG.info('There is no result tracker entry to remove.') + + if __name__ == '__main__': setup() + + if not cfg.CONF.delete: + add_result_tracker(cfg.CONF.id) + else: + del_result_tracker(cfg.CONF.id) From f11876f719a20c819e4760de44d81438f85bdd8d Mon Sep 17 00:00:00 2001 From: amanda Date: Mon, 10 Aug 2020 22:46:55 +0100 Subject: [PATCH 16/26] Update py3 expected text --- .../tests/fixtures/execution_result_has_carriage_return_py3.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt b/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt index 46b730fbd3..533dbc36ca 100644 --- a/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt +++ b/st2client/tests/fixtures/execution_result_has_carriage_return_py3.txt @@ -46,7 +46,7 @@ | | st2api PID: 16614 | | | sensor_container is not running | | | history PID: 16616 | -| | rules_engine PID: 16617 | +| | rules_engine PID: 16617" | | | } | | | }, | | | "delete": { | From 11aec441c661fcf7dd8907308656ede0f8b32774 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Tue, 11 Aug 2020 16:53:47 +0000 Subject: [PATCH 17/26] Added get_query_module and get_callback_modules but as commented out tests --- st2common/tests/unit/test_runners_base.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/st2common/tests/unit/test_runners_base.py b/st2common/tests/unit/test_runners_base.py index 2587a792a8..73249b5dff 100644 --- a/st2common/tests/unit/test_runners_base.py +++ b/st2common/tests/unit/test_runners_base.py @@ -35,11 +35,27 @@ def test_get_runner_failure_not_found(self): self.assertRaisesRegexp(ActionRunnerCreateError, expected_msg, get_runner, 'invalid-name-not-found') + # Leave test commented so can uncomment when get a query runner, but + # could not find way to get stevedore to find runners from fixtures + #def test_get_query_module_success(self): + # query_module = get_query_module('mistral-v2') + # + # self.assertEqual(query_module.__name__, 'mistral_v2.query') + # self.assertTrue(query_module.get_instance()) + def test_get_query_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' self.assertRaisesRegexp(NoMatches, expected_msg, get_query_module, 'invalid-name-not-found') + # Leave test commented so can uncomment when get a query runner, but + # could not find way to get stevedore to find runners from fixtures + #def test_get_callback_module_success(self): + # callback_module = get_callback_module('mistral-v2') + # + # self.assertEqual(callback_module.__name__, 'mistral_v2.callback') + # self.assertTrue(callback_module.get_instance()) + def test_get_callback_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' self.assertRaisesRegexp(NoMatches, expected_msg, From c7a35c345fe0199fff7b9ffe595ad7b1471292bd Mon Sep 17 00:00:00 2001 From: Cloud User Date: Tue, 11 Aug 2020 17:15:36 +0000 Subject: [PATCH 18/26] Put in orquesta execution tail --- .../tests/unit/test_execution_tail_command.py | 339 ++++++++++++++++++ 1 file changed, 339 insertions(+) diff --git a/st2client/tests/unit/test_execution_tail_command.py b/st2client/tests/unit/test_execution_tail_command.py index 0acc3289bb..83b9933858 100644 --- a/st2client/tests/unit/test_execution_tail_command.py +++ b/st2client/tests/unit/test_execution_tail_command.py @@ -23,6 +23,7 @@ from st2client.commands.action import LIVEACTION_STATUS_RUNNING from st2client.commands.action import LIVEACTION_STATUS_SUCCEEDED from st2client.commands.action import LIVEACTION_STATUS_FAILED +from st2client.commands.action import LIVEACTION_STATUS_TIMED_OUT from st2client.shell import Shell __all__ = [ @@ -129,6 +130,130 @@ 'status': LIVEACTION_STATUS_SUCCEEDED } +# Mock objects for Orquesta workflow execution +MOCK_LIVEACTION_4_RUNNING = { + 'id': 'idfoo4', + 'status': LIVEACTION_STATUS_RUNNING +} + +MOCK_LIVEACTION_4_CHILD_1_RUNNING = { + 'id': 'idorquestachild1', + 'context': { + 'orquesta': { + 'task_name': 'task_1' + }, + 'parent': { + 'execution_id': 'idfoo4' + } + }, + 'status': LIVEACTION_STATUS_RUNNING +} + +MOCK_LIVEACTION_4_CHILD_1_1_RUNNING = { + 'id': 'idorquestachild1_1', + 'context': { + 'orquesta': { + 'task_name': 'task_1' + }, + 'parent': { + 'execution_id': 'idorquestachild1' + } + }, + 'status': LIVEACTION_STATUS_RUNNING +} + +MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED = { + 'id': 'idorquestachild1', + 'context': { + 'orquesta': { + 'task_name': 'task_1', + }, + 'parent': { + 'execution_id': 'idfoo4' + } + }, + 'status': LIVEACTION_STATUS_SUCCEEDED +} + +MOCK_LIVEACTION_4_CHILD_1_1_SUCCEEDED = { + 'id': 'idorquestachild1_1', + 'context': { + 'orquesta': { + 'task_name': 'task_1', + }, + 'parent': { + 'execution_id': 'idorquestachild1' + } + }, + 'status': LIVEACTION_STATUS_SUCCEEDED +} + +MOCK_LIVEACTION_4_CHILD_1_OUTPUT_1 = { + 'execution_id': 'idorquestachild1', + 'timestamp': '1505732598', + 'output_type': 'stdout', + 'data': 'line orquesta 4\n' +} + +MOCK_LIVEACTION_4_CHILD_1_OUTPUT_2 = { + 'execution_id': 'idorquestachild1', + 'timestamp': '1505732598', + 'output_type': 'stderr', + 'data': 'line orquesta 5\n' +} + +MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_1 = { + 'execution_id': 'idorquestachild1_1', + 'timestamp': '1505732598', + 'output_type': 'stdout', + 'data': 'line orquesta 4\n' +} + +MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_2 = { + 'execution_id': 'idorquestachild1_1', + 'timestamp': '1505732598', + 'output_type': 'stderr', + 'data': 'line orquesta 5\n' +} + +MOCK_LIVEACTION_4_CHILD_2_RUNNING = { + 'id': 'idorquestachild2', + 'context': { + 'orquesta': { + 'task_name': 'task_2', + }, + 'parent': { + 'execution_id': 'idfoo4' + } + }, + 'status': LIVEACTION_STATUS_RUNNING +} + +MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT = { + 'id': 'idorquestachild2', + 'context': { + 'orquesta': { + 'task_name': 'task_2', + }, + 'parent': { + 'execution_id': 'idfoo4' + } + }, + 'status': LIVEACTION_STATUS_TIMED_OUT +} + +MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1 = { + 'execution_id': 'idorquestachild2', + 'timestamp': '1505732598', + 'output_type': 'stdout', + 'data': 'line orquesta 100\n' +} + +MOCK_LIVEACTION_4_SUCCEDED = { + 'id': 'idfoo4', + 'status': LIVEACTION_STATUS_SUCCEEDED +} + # Mock objects for simple actions MOCK_OUTPUT_1 = { 'execution_id': 'idfoo3', @@ -315,3 +440,217 @@ def test_tail_action_chain_workflow_execution(self, mock_stream_manager): """.lstrip() self.assertEqual(stdout, expected_result) self.assertEqual(stderr, '') + + @mock.patch.object( + httpclient.HTTPClient, 'get', + mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_RUNNING), + 200, 'OK'))) + @mock.patch('st2client.client.StreamManager', autospec=True) + def test_tail_orquesta_workflow_execution(self, mock_stream_manager): + argv = ['execution', 'tail', 'idfoo4'] + + MOCK_EVENTS = [ + # Workflow started running + MOCK_LIVEACTION_4_RUNNING, + + # Child task 1 started running + MOCK_LIVEACTION_4_CHILD_1_RUNNING, + + # Output produced by the child task + MOCK_LIVEACTION_4_CHILD_1_OUTPUT_1, + MOCK_LIVEACTION_4_CHILD_1_OUTPUT_2, + + # Child task 1 finished + MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, + + # Child task 2 started running + MOCK_LIVEACTION_4_CHILD_2_RUNNING, + + # Output produced by child task + MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, + + # Child task 2 finished + MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT, + + # Parent workflow task finished + MOCK_LIVEACTION_4_SUCCEDED + ] + + mock_cls = mock.Mock() + mock_cls.listen = mock.Mock() + mock_listen_generator = mock.Mock() + mock_listen_generator.return_value = MOCK_EVENTS + mock_cls.listen.side_effect = mock_listen_generator + mock_stream_manager.return_value = mock_cls + + self.assertEqual(self.shell.run(argv), 0) + self.assertEqual(mock_listen_generator.call_count, 1) + + stdout = self.stdout.getvalue() + stderr = self.stderr.getvalue() + + expected_result = """ +Execution idfoo4 has started. + +Child execution (task=task_1) idorquestachild1 has started. + +line orquesta 4 +line orquesta 5 + +Child execution (task=task_1) idorquestachild1 has finished (status=succeeded). +Child execution (task=task_2) idorquestachild2 has started. + +line orquesta 100 + +Child execution (task=task_2) idorquestachild2 has finished (status=timeout). + +Execution idfoo4 has completed (status=succeeded). +""".lstrip() + self.assertEqual(stdout, expected_result) + self.assertEqual(stderr, '') + + @mock.patch.object( + httpclient.HTTPClient, 'get', + mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_RUNNING), + 200, 'OK'))) + @mock.patch('st2client.client.StreamManager', autospec=True) + def test_tail_double_nested_orquesta_workflow_execution(self, mock_stream_manager): + argv = ['execution', 'tail', 'idfoo4'] + + MOCK_EVENTS = [ + # Workflow started running + MOCK_LIVEACTION_4_RUNNING, + + # Child task 1 started running (sub workflow) + MOCK_LIVEACTION_4_CHILD_1_RUNNING, + + # Child task 1 started running + MOCK_LIVEACTION_4_CHILD_1_1_RUNNING, + + # Output produced by the child task + MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_1, + MOCK_LIVEACTION_4_CHILD_1_1_OUTPUT_2, + + # Another execution has started, this output should not be included + MOCK_LIVEACTION_3_RUNNING, + + # Child task 1 started running + MOCK_LIVEACTION_3_CHILD_1_RUNNING, + + # Output produced by the child task + MOCK_LIVEACTION_3_CHILD_1_OUTPUT_1, + MOCK_LIVEACTION_3_CHILD_1_OUTPUT_2, + + # Child task 1 finished + MOCK_LIVEACTION_3_CHILD_1_SUCCEEDED, + + # Parent workflow task finished + MOCK_LIVEACTION_3_SUCCEDED, + # End another execution + + # Child task 1 has finished + MOCK_LIVEACTION_4_CHILD_1_1_SUCCEEDED, + + # Child task 1 finished (sub workflow) + MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, + + # Child task 2 started running + MOCK_LIVEACTION_4_CHILD_2_RUNNING, + + # Output produced by child task + MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, + + # Child task 2 finished + MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT, + + # Parent workflow task finished + MOCK_LIVEACTION_4_SUCCEDED + ] + + mock_cls = mock.Mock() + mock_cls.listen = mock.Mock() + mock_listen_generator = mock.Mock() + mock_listen_generator.return_value = MOCK_EVENTS + mock_cls.listen.side_effect = mock_listen_generator + mock_stream_manager.return_value = mock_cls + + self.assertEqual(self.shell.run(argv), 0) + self.assertEqual(mock_listen_generator.call_count, 1) + + stdout = self.stdout.getvalue() + stderr = self.stderr.getvalue() + + expected_result = """ +Execution idfoo4 has started. + +Child execution (task=task_1) idorquestachild1 has started. + +Child execution (task=task_1) idorquestachild1_1 has started. + +line orquesta 4 +line orquesta 5 + +Child execution (task=task_1) idorquestachild1_1 has finished (status=succeeded). + +Child execution (task=task_1) idorquestachild1 has finished (status=succeeded). +Child execution (task=task_2) idorquestachild2 has started. + +line orquesta 100 + +Child execution (task=task_2) idorquestachild2 has finished (status=timeout). + +Execution idfoo4 has completed (status=succeeded). +""".lstrip() + + self.assertEqual(stdout, expected_result) + self.assertEqual(stderr, '') + + @mock.patch.object( + httpclient.HTTPClient, 'get', + mock.MagicMock(return_value=base.FakeResponse(json.dumps(MOCK_LIVEACTION_4_CHILD_2_RUNNING), + 200, 'OK'))) + @mock.patch('st2client.client.StreamManager', autospec=True) + def test_tail_child_execution_directly(self, mock_stream_manager): + argv = ['execution', 'tail', 'idfoo4'] + + MOCK_EVENTS = [ + # Child task 2 started running + MOCK_LIVEACTION_4_CHILD_2_RUNNING, + + # Output produced by child task + MOCK_LIVEACTION_4_CHILD_2_OUTPUT_1, + + # Other executions should not interfere + # Child task 1 started running + MOCK_LIVEACTION_3_CHILD_1_RUNNING, + + # Child task 1 finished (sub workflow) + MOCK_LIVEACTION_4_CHILD_1_SUCCEEDED, + + # Child task 2 finished + MOCK_LIVEACTION_4_CHILD_2_TIMED_OUT + ] + + mock_cls = mock.Mock() + mock_cls.listen = mock.Mock() + mock_listen_generator = mock.Mock() + mock_listen_generator.return_value = MOCK_EVENTS + mock_cls.listen.side_effect = mock_listen_generator + mock_stream_manager.return_value = mock_cls + + self.assertEqual(self.shell.run(argv), 0) + self.assertEqual(mock_listen_generator.call_count, 1) + + stdout = self.stdout.getvalue() + stderr = self.stderr.getvalue() + + expected_result = """ +Child execution (task=task_2) idorquestachild2 has started. + +line orquesta 100 + +Child execution (task=task_2) idorquestachild2 has finished (status=timeout). +""".lstrip() + + self.assertEqual(stdout, expected_result) + self.assertEqual(stderr, '') From a70d5c92750798e6a6db5bc573ffcf2ec874ff34 Mon Sep 17 00:00:00 2001 From: Cloud User Date: Tue, 11 Aug 2020 17:57:22 +0000 Subject: [PATCH 19/26] Fix flake8 error --- st2common/tests/unit/test_runners_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/st2common/tests/unit/test_runners_base.py b/st2common/tests/unit/test_runners_base.py index 73249b5dff..cbe1dbcd67 100644 --- a/st2common/tests/unit/test_runners_base.py +++ b/st2common/tests/unit/test_runners_base.py @@ -37,7 +37,7 @@ def test_get_runner_failure_not_found(self): # Leave test commented so can uncomment when get a query runner, but # could not find way to get stevedore to find runners from fixtures - #def test_get_query_module_success(self): + # def test_get_query_module_success(self): # query_module = get_query_module('mistral-v2') # # self.assertEqual(query_module.__name__, 'mistral_v2.query') @@ -50,7 +50,7 @@ def test_get_query_module_failure_not_found(self): # Leave test commented so can uncomment when get a query runner, but # could not find way to get stevedore to find runners from fixtures - #def test_get_callback_module_success(self): + # def test_get_callback_module_success(self): # callback_module = get_callback_module('mistral-v2') # # self.assertEqual(callback_module.__name__, 'mistral_v2.callback') From 5524784385b2606fa028edb3a73b9a7138ccb63d Mon Sep 17 00:00:00 2001 From: amanda Date: Thu, 13 Aug 2020 17:17:52 +0100 Subject: [PATCH 20/26] Minor update to UT --- st2common/tests/unit/test_query_base.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/st2common/tests/unit/test_query_base.py b/st2common/tests/unit/test_query_base.py index 951d6013b9..a1edf0610a 100644 --- a/st2common/tests/unit/test_query_base.py +++ b/st2common/tests/unit/test_query_base.py @@ -41,9 +41,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orqesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -53,9 +53,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_2 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orquesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb3' } @@ -65,9 +65,9 @@ def test_fire_queries_doesnt_loop(self): mock_query_state_3 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orquesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb4' } @@ -109,9 +109,9 @@ def test_query_rescheduled(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orquesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -157,9 +157,9 @@ def test_query_completed(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orquesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } @@ -201,9 +201,9 @@ def test_state_db_entry_deleted(self): mock_query_state_1 = QueryContext( uuid.uuid4().hex, uuid.uuid4().hex, - 'orquesta_runner', + 'dummy_runner', { - 'orquesta': { + 'dummy': { 'workflow_name': 'st2ci.st2_pkg_e2e_test', 'execution_id': '6d624534-42ca-425c-aa3a-ccc676386fb2' } From 55b3ebc924757f71730d0b6eebbb51e753d3cbf8 Mon Sep 17 00:00:00 2001 From: amanda11 Date: Fri, 14 Aug 2020 17:18:56 +0000 Subject: [PATCH 21/26] Add mock query callback runner --- Makefile | 15 +- .../runners/mock_query_callback/MANIFEST.in | 11 ++ .../mock_query_callback/callback/__init__.py | 0 .../runners/mock_query_callback/dist_utils.py | 169 ++++++++++++++++++ .../mock_query_callback/in-requirements.txt | 0 .../mock_query_callback/__init__.py | 16 ++ .../mock_query_callback/callback.py | 30 ++++ .../mock_query_callback.py | 44 +++++ .../mock_query_callback/query.py | 32 ++++ .../mock_query_callback/runner.yaml | 7 + .../mock_query_callback/query/__init__.py | 0 .../mock_query_callback/requirements.txt | 8 + .../runners/mock_query_callback/runner.yaml | 1 + .../runners/mock_query_callback/setup.py | 45 +++++ st2common/tests/unit/test_runners_base.py | 24 ++- 15 files changed, 387 insertions(+), 15 deletions(-) create mode 100644 st2common/tests/runners/mock_query_callback/MANIFEST.in create mode 100644 st2common/tests/runners/mock_query_callback/callback/__init__.py create mode 100644 st2common/tests/runners/mock_query_callback/dist_utils.py create mode 100644 st2common/tests/runners/mock_query_callback/in-requirements.txt create mode 100644 st2common/tests/runners/mock_query_callback/mock_query_callback/__init__.py create mode 100644 st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py create mode 100644 st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py create mode 100644 st2common/tests/runners/mock_query_callback/mock_query_callback/query.py create mode 100644 st2common/tests/runners/mock_query_callback/mock_query_callback/runner.yaml create mode 100644 st2common/tests/runners/mock_query_callback/query/__init__.py create mode 100644 st2common/tests/runners/mock_query_callback/requirements.txt create mode 120000 st2common/tests/runners/mock_query_callback/runner.yaml create mode 100644 st2common/tests/runners/mock_query_callback/setup.py diff --git a/Makefile b/Makefile index e6113e8e60..b77fcfebec 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ BINARIES := bin # All components are prefixed by st2 and not .egg-info. COMPONENTS := $(shell ls -a | grep ^st2 | grep -v .egg-info) COMPONENTS_RUNNERS := $(wildcard contrib/runners/*) +MOCK_RUNNERS := $(wildcard st2common/tests/runners/*) COMPONENTS_WITHOUT_ST2TESTS := $(shell ls -a | grep ^st2 | grep -v .egg-info | grep -v st2tests | grep -v st2exporter) COMPONENTS_WITH_RUNNERS := $(COMPONENTS) $(COMPONENTS_RUNNERS) @@ -157,6 +158,18 @@ install-runners: (. $(VIRTUALENV_DIR)/bin/activate; cd $$component; python setup.py develop --no-deps); \ done +.PHONY: install-mock-runners +install-mock-runners: + @echo "" + @echo "================== INSTALL MOCK RUNNERS ====================" + @echo "" + @for component in $(MOCK_RUNNERS); do \ + echo "==========================================================="; \ + echo "Installing mock runner:" $$component; \ + echo "==========================================================="; \ + (. $(VIRTUALENV_DIR)/bin/activate; cd $$component; python setup.py develop --no-deps); \ + done + .PHONY: check-requirements .check-requirements: @echo @@ -508,7 +521,7 @@ distclean: clean @echo "===========================================================" .PHONY: requirements -requirements: virtualenv .requirements .sdist-requirements install-runners +requirements: virtualenv .requirements .sdist-requirements install-runners install-mock-runners @echo @echo "==================== requirements ====================" @echo diff --git a/st2common/tests/runners/mock_query_callback/MANIFEST.in b/st2common/tests/runners/mock_query_callback/MANIFEST.in new file mode 100644 index 0000000000..25ce80c091 --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/MANIFEST.in @@ -0,0 +1,11 @@ +# https://docs.python.org/2/distutils/sourcedist.html#commands +# Include all files under the source tree by default. +# Another behaviour can be used in the future though. +include __init__.py +include runner.yaml +include dist_utils.py +include requirements.txt +include README.rst +include CHANGELOG.rst +include LICENSE +global-exclude *.pyc diff --git a/st2common/tests/runners/mock_query_callback/callback/__init__.py b/st2common/tests/runners/mock_query_callback/callback/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/st2common/tests/runners/mock_query_callback/dist_utils.py b/st2common/tests/runners/mock_query_callback/dist_utils.py new file mode 100644 index 0000000000..1d637ca664 --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/dist_utils.py @@ -0,0 +1,169 @@ +# -*- coding: utf-8 -*- +# NOTE: This file is auto-generated - DO NOT EDIT MANUALLY +# Instead modify scripts/dist_utils.py and run 'make .sdist-requirements' to +# update dist_utils.py files for all components + +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os +import re +import sys + +from distutils.version import StrictVersion + +# NOTE: This script can't rely on any 3rd party dependency so we need to use this code here +# +# TODO: Why can't this script rely on 3rd party dependencies? Is it because it has to import +# from pip? +# +# TODO: Dear future developer, if you are back here fixing a bug with how we parse +# requirements files, please look into using the packaging package on PyPI: +# https://packaging.pypa.io/en/latest/requirements/ +# and specifying that in the `setup_requires` argument to `setuptools.setup()` +# for subpackages. +# At the very least we can vendorize some of their code instead of reimplementing +# each piece of their code every time our parsing breaks. +PY3 = sys.version_info[0] == 3 + +if PY3: + text_type = str +else: + text_type = unicode # NOQA + +GET_PIP = 'curl https://bootstrap.pypa.io/get-pip.py | python' + +__all__ = [ + 'check_pip_is_installed', + 'check_pip_version', + 'fetch_requirements', + 'apply_vagrant_workaround', + 'get_version_string', + 'parse_version_string' +] + + +def check_pip_is_installed(): + """ + Ensure that pip is installed. + """ + try: + import pip # NOQA + except ImportError as e: + print('Failed to import pip: %s' % (text_type(e))) + print('') + print('Download pip:\n%s' % (GET_PIP)) + sys.exit(1) + + return True + + +def check_pip_version(min_version='6.0.0'): + """ + Ensure that a minimum supported version of pip is installed. + """ + check_pip_is_installed() + + import pip + + if StrictVersion(pip.__version__) < StrictVersion(min_version): + print("Upgrade pip, your version '{0}' " + "is outdated. Minimum required version is '{1}':\n{2}".format(pip.__version__, + min_version, + GET_PIP)) + sys.exit(1) + + return True + + +def fetch_requirements(requirements_file_path): + """ + Return a list of requirements and links by parsing the provided requirements file. + """ + links = [] + reqs = [] + + def _get_link(line): + vcs_prefixes = ['git+', 'svn+', 'hg+', 'bzr+'] + + for vcs_prefix in vcs_prefixes: + if line.startswith(vcs_prefix) or line.startswith('-e %s' % (vcs_prefix)): + req_name = re.findall('.*#egg=(.+)([&|@]).*$', line) + + if not req_name: + req_name = re.findall('.*#egg=(.+?)$', line) + else: + req_name = req_name[0] + + if not req_name: + raise ValueError('Line "%s" is missing "#egg="' % (line)) + + link = line.replace('-e ', '').strip() + return link, req_name[0] + + return None, None + + with open(requirements_file_path, 'r') as fp: + for line in fp.readlines(): + line = line.strip() + + if line.startswith('#') or not line: + continue + + link, req_name = _get_link(line=line) + + if link: + links.append(link) + else: + req_name = line + + if ';' in req_name: + req_name = req_name.split(';')[0].strip() + + reqs.append(req_name) + + return (reqs, links) + + +def apply_vagrant_workaround(): + """ + Function which detects if the script is being executed inside vagrant and if it is, it deletes + "os.link" attribute. + Note: Without this workaround, setup.py sdist will fail when running inside a shared directory + (nfs / virtualbox shared folders). + """ + if os.environ.get('USER', None) == 'vagrant': + del os.link + + +def get_version_string(init_file): + """ + Read __version__ string for an init file. + """ + + with open(init_file, 'r') as fp: + content = fp.read() + version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", + content, re.M) + if version_match: + return version_match.group(1) + + raise RuntimeError('Unable to find version string in %s.' % (init_file)) + + +# alias for get_version_string +parse_version_string = get_version_string diff --git a/st2common/tests/runners/mock_query_callback/in-requirements.txt b/st2common/tests/runners/mock_query_callback/in-requirements.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/__init__.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/__init__.py new file mode 100644 index 0000000000..e682f5e7b6 --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +__version__ = '3.3dev' diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py new file mode 100644 index 0000000000..9cb4c5fbea --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py @@ -0,0 +1,30 @@ +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +from st2common import log as logging +from st2common.callback import base as callback + + +def get_instance(): + return MockCallbackHandler + + +class MockCallbackHandler(callback.AsyncActionExecutionCallbackHandler): + + @classmethod + def callback(cls, liveaction): + pass diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py new file mode 100644 index 0000000000..ebf27a5c5a --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import + +from st2common.constants.action import LIVEACTION_STATUS_SUCCEEDED +from st2common.runners.base import ActionRunner +from st2common.runners.base import get_metadata as get_runner_metadata + + +__all__ = [ + 'MockQueryCallbackRunner', + + 'get_runner', + 'get_metadata' +] + +class MockQueryCallbackRunner(ActionRunner): + """ + Runner which does absolutely nothing. No-op action. + """ + + def __init__(self, runner_id): + super(MockQueryCallbackRunner, self).__init__(runner_id=runner_id) + + def pre_run(self): + super(MockQueryCallbackRunner, self).pre_run() + + def run(self, action_parameters): + result = { + 'failed': False, + 'succeeded': True, + 'return_code': 0, + } + + status = LIVEACTION_STATUS_SUCCEEDED + return (status, result, None) + + +def get_runner(): + return MockQueryCallbackRunner(str(uuid.uuid4())) + + +def get_metadata(): + return get_runner_metadata('noop_runner')[0] + + diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py new file mode 100644 index 0000000000..6a01657c9e --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py @@ -0,0 +1,32 @@ +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +from st2common.query.base import Querier +from st2common.constants import action as action_constants + + +def get_instance(): + return MockQueryCallbackQuerier() + + +class MockQueryCallbackQuerier(Querier): + + def __init__(self, *args, **kwargs): + super(MockQueryCallbackQuerier, self).__init__(*args, **kwargs) + + def query(self, execution_id, query_context, last_query_time=None): + return (action_constants.LIVEACTION_STATUS_SUCCEEDED, {'called_with': {execution_id: query_context}}) diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/runner.yaml b/st2common/tests/runners/mock_query_callback/mock_query_callback/runner.yaml new file mode 100644 index 0000000000..318f0f555b --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/runner.yaml @@ -0,0 +1,7 @@ +- aliases: [] + description: A mock runner for query and callback + enabled: true + name: mock_query_callback + query_module: mock_query_callback + runner_module: mock_query_callback + diff --git a/st2common/tests/runners/mock_query_callback/query/__init__.py b/st2common/tests/runners/mock_query_callback/query/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/st2common/tests/runners/mock_query_callback/requirements.txt b/st2common/tests/runners/mock_query_callback/requirements.txt new file mode 100644 index 0000000000..f4a1c5a5ee --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/requirements.txt @@ -0,0 +1,8 @@ +# Don't edit this file. It's generated automatically! +# If you want to update global dependencies, modify fixed-requirements.txt +# and then run 'make requirements' to update requirements.txt for all +# components. +# If you want to update depdencies for a single component, modify the +# in-requirements.txt for that component and then run 'make requirements' to +# update the component requirements.txt + diff --git a/st2common/tests/runners/mock_query_callback/runner.yaml b/st2common/tests/runners/mock_query_callback/runner.yaml new file mode 120000 index 0000000000..994fdf0c6b --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/runner.yaml @@ -0,0 +1 @@ +mock_query_callback/runner.yaml \ No newline at end of file diff --git a/st2common/tests/runners/mock_query_callback/setup.py b/st2common/tests/runners/mock_query_callback/setup.py new file mode 100644 index 0000000000..3c68f3f808 --- /dev/null +++ b/st2common/tests/runners/mock_query_callback/setup.py @@ -0,0 +1,45 @@ +from __future__ import absolute_import +import os.path + +from setuptools import setup +from setuptools import find_packages + +from dist_utils import fetch_requirements +from dist_utils import apply_vagrant_workaround + +from mock_query_callback import __version__ + +BASE_DIR = os.path.dirname(os.path.abspath(__file__)) +REQUIREMENTS_FILE = os.path.join(BASE_DIR, 'requirements.txt') + +install_reqs, dep_links = fetch_requirements(REQUIREMENTS_FILE) + +apply_vagrant_workaround() +setup( + name='stackstorm-runner-mock_query_callback', + version=__version__, + description=('Mock runner for query callback'), + author='StackStorm', + author_email='info@stackstorm.com', + license='Apache License (2.0)', + url='https://stackstorm.com/', + install_requires=install_reqs, + dependency_links=dep_links, + test_suite='tests', + zip_safe=False, + include_package_data=True, + packages=find_packages(exclude=['setuptools', 'tests']), + package_data={'mock_query_callback': ['runner.yaml']}, + scripts=[], + entry_points={ + 'st2common.runners.runner': [ + 'mock_query_callback = mock_query_callback.mock_query_callback', + ], + 'st2common.runners.query': [ + 'mock_query_callback = mock_query_callback.query', + ], + 'st2common.runners.callback': [ + 'mock_query_callback = mock_query_callback.callback', + ], + } +) diff --git a/st2common/tests/unit/test_runners_base.py b/st2common/tests/unit/test_runners_base.py index eef6e3c33d..54d13ee18d 100644 --- a/st2common/tests/unit/test_runners_base.py +++ b/st2common/tests/unit/test_runners_base.py @@ -36,26 +36,22 @@ def test_get_runner_failure_not_found(self): self.assertRaisesRegexp(ActionRunnerCreateError, expected_msg, get_runner, 'invalid-name-not-found') - # Leave test commented so can uncomment when get a query runner, but - # could not find way to get stevedore to find runners from fixtures - # def test_get_query_module_success(self): - # query_module = get_query_module('mistral-v2') - # - # self.assertEqual(query_module.__name__, 'mistral_v2.query') - # self.assertTrue(query_module.get_instance()) + def test_get_query_module_success(self): + query_module = get_query_module('mock_query_callback') + + self.assertEqual(query_module.__name__, 'mock_query_callback.query') + self.assertTrue(query_module.get_instance()) def test_get_query_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' self.assertRaisesRegexp(NoMatches, expected_msg, get_query_module, 'invalid-name-not-found') - # Leave test commented so can uncomment when get a query runner, but - # could not find way to get stevedore to find runners from fixtures - # def test_get_callback_module_success(self): - # callback_module = get_callback_module('mistral-v2') - # - # self.assertEqual(callback_module.__name__, 'mistral_v2.callback') - # self.assertTrue(callback_module.get_instance()) + def test_get_callback_module_success(self): + callback_module = get_callback_module('mock_query_callback') + + self.assertEqual(callback_module.__name__, 'mock_query_callback.callback') + self.assertTrue(callback_module.get_instance()) def test_get_callback_module_failure_not_found(self): expected_msg = 'No .*? driver found.*' From 87b3c35c6a44beb5ba2cbce650bae1f0dda1e702 Mon Sep 17 00:00:00 2001 From: amanda11 Date: Mon, 17 Aug 2020 11:26:53 +0000 Subject: [PATCH 22/26] Amend so python 3 pick up mock runner and fix flake8 and UT error --- .../tests/unit/controllers/v1/test_packs.py | 7 ++++--- .../mock_query_callback/callback.py | 1 - .../mock_query_callback.py | 20 +++++++++++++++++-- .../mock_query_callback/query.py | 3 ++- .../runners/mock_query_callback/setup.py | 16 +++++++++++++++ tox.ini | 2 +- 6 files changed, 41 insertions(+), 8 deletions(-) diff --git a/st2api/tests/unit/controllers/v1/test_packs.py b/st2api/tests/unit/controllers/v1/test_packs.py index 0f519eed45..2fc64b1332 100644 --- a/st2api/tests/unit/controllers/v1/test_packs.py +++ b/st2api/tests/unit/controllers/v1/test_packs.py @@ -540,14 +540,15 @@ def test_packs_register_endpoint(self, mock_get_packs): {'packs': ['dummy_pack_1'], 'types': ['action']}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) + # 14 real plus 1 mock runner + self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) # Verify that plural name form also works resp = self.app.post_json('/v1/packs/register', {'packs': ['dummy_pack_1'], 'types': ['actions']}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) + self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) # Register single resource from a single pack specified multiple times - verify that # resources from the same pack are only registered once @@ -557,7 +558,7 @@ def test_packs_register_endpoint(self, mock_get_packs): 'fail_on_failure': False}) self.assertEqual(resp.status_int, 200) - self.assertEqual(resp.json, {'actions': 1, 'runners': 14}) + self.assertEqual(resp.json, {'actions': 1, 'runners': 15}) # Register resources from a single (non-existent pack) resp = self.app.post_json('/v1/packs/register', {'packs': ['doesntexist']}, diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py index 9cb4c5fbea..9f41758bab 100644 --- a/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/callback.py @@ -15,7 +15,6 @@ from __future__ import absolute_import -from st2common import log as logging from st2common.callback import base as callback diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py index ebf27a5c5a..7c78fcc134 100644 --- a/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/mock_query_callback.py @@ -1,9 +1,26 @@ +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from __future__ import absolute_import from st2common.constants.action import LIVEACTION_STATUS_SUCCEEDED from st2common.runners.base import ActionRunner from st2common.runners.base import get_metadata as get_runner_metadata +import uuid + __all__ = [ 'MockQueryCallbackRunner', @@ -12,6 +29,7 @@ 'get_metadata' ] + class MockQueryCallbackRunner(ActionRunner): """ Runner which does absolutely nothing. No-op action. @@ -40,5 +58,3 @@ def get_runner(): def get_metadata(): return get_runner_metadata('noop_runner')[0] - - diff --git a/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py b/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py index 6a01657c9e..065dd5d0e6 100644 --- a/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py +++ b/st2common/tests/runners/mock_query_callback/mock_query_callback/query.py @@ -29,4 +29,5 @@ def __init__(self, *args, **kwargs): super(MockQueryCallbackQuerier, self).__init__(*args, **kwargs) def query(self, execution_id, query_context, last_query_time=None): - return (action_constants.LIVEACTION_STATUS_SUCCEEDED, {'called_with': {execution_id: query_context}}) + return (action_constants.LIVEACTION_STATUS_SUCCEEDED, + {'called_with': {execution_id: query_context}}) diff --git a/st2common/tests/runners/mock_query_callback/setup.py b/st2common/tests/runners/mock_query_callback/setup.py index 3c68f3f808..af00f5b9cc 100644 --- a/st2common/tests/runners/mock_query_callback/setup.py +++ b/st2common/tests/runners/mock_query_callback/setup.py @@ -1,3 +1,19 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 The StackStorm Authors. +# Copyright 2019 Extreme Networks, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + from __future__ import absolute_import import os.path diff --git a/tox.ini b/tox.ini index 48593e0cf7..a12f742f4f 100644 --- a/tox.ini +++ b/tox.ini @@ -21,7 +21,7 @@ deps = -r{toxinidir}/requirements.txt # Python 3 tasks [testenv:py36-unit] basepython = python3.6 -setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner +setenv = PYTHONPATH = {toxinidir}/external:{toxinidir}/st2common:{toxinidir}/st2api:{toxinidir}/st2actions:{toxinidir}/st2exporter:{toxinidir}/st2reactor:{toxinidir}/st2tests:{toxinidir}/contrib/runners/action_chain_runner:{toxinidir}/contrib/runners/local_runner:{toxinidir}/contrib/runners/python_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/noop_runner:{toxinidir}/contrib/runners/announcement_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/remote_runner:{toxinidir}/contrib/runners/orquesta_runner:{toxinidir}/contrib/runners/inquirer_runner:{toxinidir}/contrib/runners/http_runner:{toxinidir}/contrib/runners/winrm_runner:{toxinidir}/st2common/tests/runners/mock_query_callback VIRTUALENV_DIR = {envdir} passenv = NOSE_WITH_TIMER TRAVIS install_command = pip install -U --force-reinstall {opts} {packages} From 707d4958499c96f33fc9830660866dd69611475a Mon Sep 17 00:00:00 2001 From: amanda11 Date: Mon, 17 Aug 2020 12:10:10 +0000 Subject: [PATCH 23/26] Add echo of pythonpath for investigation --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index a12f742f4f..6ec49b9ae3 100644 --- a/tox.ini +++ b/tox.ini @@ -30,6 +30,7 @@ deps = virtualenv -e{toxinidir}/st2client -e{toxinidir}/st2common commands = + echo $PYTHONPATH nosetests --rednose --immediate -sv st2actions/tests/unit/ nosetests --rednose --immediate -sv st2auth/tests/unit/ nosetests --rednose --immediate -sv st2api/tests/unit/controllers/v1/ From 8c3db451039cca770e2272d92a749eda1b76baa1 Mon Sep 17 00:00:00 2001 From: amanda11 Date: Mon, 17 Aug 2020 12:16:39 +0000 Subject: [PATCH 24/26] Add mock runner to python3.6 --- scripts/travis/install-requirements.sh | 7 +++++++ tox.ini | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/travis/install-requirements.sh b/scripts/travis/install-requirements.sh index 776a998a19..3de1e53853 100755 --- a/scripts/travis/install-requirements.sh +++ b/scripts/travis/install-requirements.sh @@ -29,6 +29,13 @@ if [[ " ${TASK}" = *' ci-py3-'* ]]; then cd $RUNNER python setup.py develop --no-deps done + # Install mock runners + for RUNNER in `ls -d $CURRENT_DIR/st2common/test/runners/*` + do + echo "Installing mock runner: $RUNNER..." + cd $RUNNER + python setup.py develop --no-deps + done # NOTE: We create the environment and install the dependencies first. This # means that the subsequent tox build / test command has a stable run time diff --git a/tox.ini b/tox.ini index 6ec49b9ae3..a12f742f4f 100644 --- a/tox.ini +++ b/tox.ini @@ -30,7 +30,6 @@ deps = virtualenv -e{toxinidir}/st2client -e{toxinidir}/st2common commands = - echo $PYTHONPATH nosetests --rednose --immediate -sv st2actions/tests/unit/ nosetests --rednose --immediate -sv st2auth/tests/unit/ nosetests --rednose --immediate -sv st2api/tests/unit/controllers/v1/ From d37418e4555031edffed128d570fa1a79dff8880 Mon Sep 17 00:00:00 2001 From: amanda11 Date: Mon, 17 Aug 2020 12:35:06 +0000 Subject: [PATCH 25/26] Updated travis install requirements --- scripts/travis/install-requirements.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/travis/install-requirements.sh b/scripts/travis/install-requirements.sh index 3de1e53853..1b8f62f9e1 100755 --- a/scripts/travis/install-requirements.sh +++ b/scripts/travis/install-requirements.sh @@ -30,7 +30,7 @@ if [[ " ${TASK}" = *' ci-py3-'* ]]; then python setup.py develop --no-deps done # Install mock runners - for RUNNER in `ls -d $CURRENT_DIR/st2common/test/runners/*` + for RUNNER in `ls -d $CURRENT_DIR/st2common/tests/runners/*` do echo "Installing mock runner: $RUNNER..." cd $RUNNER From cb501c699ca0d57c3de95881bb03b03d020f0244 Mon Sep 17 00:00:00 2001 From: Amanda McGuinness Date: Mon, 17 Aug 2020 21:07:19 +0100 Subject: [PATCH 26/26] Update CHANGELOG.rst Co-authored-by: Eugen C. --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7f071f53cf..5a0fa93357 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -78,7 +78,7 @@ Changed Removed ~~~~~~~ -* Removed ``Mistral`` +* Removed ``Mistral`` workflow engine (deprecation) #5011 Contributed by Amanda McGuinness (@amanda11 Ammeon Solutions) * Removed ``CentOS 6``/``RHEL 6`` support #4984