コード例 #1
0
 def test_convert_task_transitions_empty(self):
     converter = WorkflowConverter()
     task_spec = OrderedMap([])
     expr_converter = JinjaExpressionConverter()
     result = converter.convert_task_transitions("task_name", task_spec,
                                                 expr_converter, set())
     self.assertEqual(result, OrderedMap([]))
コード例 #2
0
 def test_convert_tasks_yaql(self):
     converter = WorkflowConverter()
     expr_converter = YaqlExpressionConverter()
     mistral_tasks = OrderedMap([('jinja_task',
                                  OrderedMap([
                                      ('action', 'mypack.actionname'),
                                      ('input',
                                       OrderedMap([
                                           ('cmd', '<% $.test %>'),
                                       ])),
                                      ('on-success', ['next_task']),
                                  ]))])
     result = converter.convert_tasks(mistral_tasks, expr_converter, set())
     self.assertEqual(
         result,
         OrderedMap([('jinja_task',
                      OrderedMap([
                          ('action', 'mypack.actionname'),
                          ('input',
                           OrderedMap([
                               ('cmd', '<% ctx().test %>'),
                           ])),
                          ('next', [
                              OrderedMap([('when', '<% succeeded() %>'),
                                          ('do', [
                                              'next_task',
                                          ])]),
                          ]),
                      ]))]))
コード例 #3
0
 def test_convert_with_items_expr_nonmatching_regex_str(self):
     wi_str = 'b in [3, 4, 5]'
     converter = WorkflowConverter()
     actual = converter.convert_with_items_expr(wi_str,
                                                YaqlExpressionConverter)
     expected = 'b in <% [3, 4, 5] %>'
     self.assertEqual(expected, actual)
コード例 #4
0
 def test_extract_context_variables(self):
     converter = WorkflowConverter()
     output_block = OrderedMap([
         ('key1', '{{ ctx().value1_str }}'),
         ('list_<%% ctx().list_key2 %>', [
             'a',
             '<%% ctx().value2_list %>',
             {
                 'inner_key_1': 'inner_value_1',
                 'inner_key_2': '<%% ctx().inner_value_2 %>',
                 'inner_<%% ctx().inner_key_3 %>': 'inner_value_3',
                 'inner_{{ ctx().inner_key_4 }}': '<%% ctx().list_key2 %>',
             },
         ]),
         ('key3_int', 1),
         ('key4_bool_false', False),
         ('key5_bool_true', True),
         ('key6_null', None),
         ('key7_float', 1.0),
     ])
     expected_output = set([
         'inner_key_3',
         'inner_key_4',
         'inner_value_2',
         'list_key2',
         'value1_str',
         'value2_list',
     ])
     actual_output = converter.extract_context_variables(output_block)
     self.assertEqual(actual_output, expected_output)
コード例 #5
0
    def test_convert_action_mistral_builtin_actions(self):
        converter = WorkflowConverter()

        self.assertEqual(converter.convert_action('std.fail'), 'fail')
        self.assertEqual(converter.convert_action('std.http'), 'core.http')
        self.assertEqual(converter.convert_action('std.mistral_http'),
                         'core.http')
        self.assertEqual(converter.convert_action('std.noop'), 'core.noop')
コード例 #6
0
 def test_convert_with_items_expr_list_unrecognized_expression(self):
     wi_list = [
         'a in <% [0, 1, 2] %>',
         'BLARGETH',  # bad syntax
         'c in <% $.all_the_things %>',
     ]
     converter = WorkflowConverter()
     with self.assertRaises(NotImplementedError):
         converter.convert_with_items_expr(wi_list, YaqlExpressionConverter)
コード例 #7
0
 def test_invalid_retry_continue_on_expression(self):
     retry = {
         'count': 30,
         'delay': 5,
         'continue-on': 'one fish, two fish, red fish, blue fish',
     }
     converter = WorkflowConverter()
     with self.assertRaises(NotImplementedError):
         converter.convert_retry(retry, 'retry_task_continue_on')
コード例 #8
0
 def test_invalid_retry_break_on_expression(self):
     retry = {
         'count': 30,
         'delay': 5,
         'break-on': 'and the cat in the hat knows a lot about that',
     }
     converter = WorkflowConverter()
     with self.assertRaises(NotImplementedError):
         converter.convert_retry(retry, 'retry_task_break_on')
コード例 #9
0
 def test_retry_continue_and_break_on_different_expression_types(self):
     retry = {
         'count': 30,
         'delay': 5,
         'continue-on': '<% $.foo = "continue" %>',
         'break-on': '{{ _.foo = "break" }}',
     }
     converter = WorkflowConverter()
     with self.assertRaises(NotImplementedError):
         converter.convert_retry(retry, 'different_expression_types')
コード例 #10
0
 def test_convert_with_items_expr_list_one_element(self):
     # Check that with-items expression lists with a single element don't
     # get put into a zip() expression
     wi_list = [
         'a in <% [0, 1, 2] %>',
     ]
     converter = WorkflowConverter()
     actual = converter.convert_with_items_expr(wi_list,
                                                YaqlExpressionConverter)
     expected = "a in <% [0, 1, 2] %>"
     self.assertEqual(expected, actual)
コード例 #11
0
 def test_convert_with_items_expr_list(self):
     wi_list = [
         'a in <% [0, 1, 2] %>',
         'b in [3, 4, 5]',
         'c in <% $.all_the_things %>',
     ]
     converter = WorkflowConverter()
     actual = converter.convert_with_items_expr(wi_list,
                                                YaqlExpressionConverter)
     expected = "a, b, c in <% zip([0, 1, 2], [3, 4, 5], ctx().all_the_things) %>"
     self.assertEqual(expected, actual)
コード例 #12
0
 def test_convert_with_items(self):
     wi = {
         'with-items': 'b in <% [3, 4, 5] %>',
     }
     converter = WorkflowConverter()
     actual = converter.convert_with_items(wi, YaqlExpressionConverter)
     # This should NOT have a concurrency key
     expected = {
         'items': 'b in <% [3, 4, 5] %>',
     }
     self.assertEqual(expected, actual)
コード例 #13
0
 def test_simple_retry(self):
     retry = {
         'count': 30,
         'delay': 5,
     }
     converter = WorkflowConverter()
     actual = converter.convert_retry(retry, 'retry_task')
     expected = OrderedMap([
         ('count', 30),
         ('delay', 5),
     ])
     self.assertEqual(expected, actual)
コード例 #14
0
 def test_dict_to_list(self):
     converter = WorkflowConverter()
     d = OrderedMap([('key1', 'value1'), ('key2', 'value2'),
                     ('key3', 'value3')])
     result = converter.dict_to_list(d)
     self.assertEqual(result, [{
         'key1': 'value1'
     }, {
         'key2': 'value2'
     }, {
         'key3': 'value3'
     }])
コード例 #15
0
 def test_convert_workflow_unsupported_attributes(self):
     mistral_wf = OrderedMap([
         ('version', '1.0'),
         ('output-on-error',
          OrderedMap([
              ('stdout', "{{ _.stdout }}"),
              ('stderr', "<% $.stderr %>"),
          ])),
     ])
     converter = WorkflowConverter()
     with self.assertRaises(NotImplementedError):
         converter.convert(mistral_wf)
コード例 #16
0
 def test_convert_with_items_concurrency_jinja(self):
     wi = {
         'with-items': 'b in <% [3, 4, 5] %>',
         'concurrency': '{{ _.count }}',
     }
     converter = WorkflowConverter()
     actual = converter.convert_with_items(wi, YaqlExpressionConverter)
     # This must have a concurrency key
     expected = {
         'items': 'b in <% [3, 4, 5] %>',
         'concurrency': '{{ ctx().count }}',
     }
     self.assertEqual(expected, actual)
コード例 #17
0
 def test_retry_break_on(self):
     retry = {
         'count': 30,
         'delay': 5,
         'break-on': '<% $.foo = "break" %>',
     }
     converter = WorkflowConverter()
     actual = converter.convert_retry(retry, 'retry_task_break_on')
     expected = OrderedMap([
         ('count', 30),
         ('delay', 5),
         ('when', '<% failed() and not (ctx().foo = "break") %>'),
     ])
     self.assertEqual(expected, actual)
コード例 #18
0
 def test_retry_continue_on(self):
     retry = {
         'count': 30,
         'delay': 5,
         'continue-on': '<% $.foo = "continue" %>',
     }
     converter = WorkflowConverter()
     actual = converter.convert_retry(retry, 'retry_task_continue_on')
     expected = OrderedMap([
         ('count', 30),
         ('delay', 5),
         ('when', '<% succeeded() and (ctx().foo = "continue") %>'),
     ])
     self.assertEqual(expected, actual)
コード例 #19
0
 def test_convert_task_transitions(self):
     converter = WorkflowConverter()
     task_spec = OrderedMap([
         ('publish', OrderedMap([
             ('good_data', '{{ _.good }}'),
         ])),
         ('publish-on-error', OrderedMap([
             ('bad_data', '{{ _.bad }}'),
         ])),
         ('on-success', [
             OrderedMap([('do_thing_a', '{{ _.x }}')]),
             OrderedMap([('do_thing_b', '{{ _.x }}')])
         ]),
         ('on-error', [
             OrderedMap([('do_thing_error', '{{ _.e }}')]),
         ]),
         ('on-complete', [
             OrderedMap([('do_thing_sometimes', '{{ _.d }}')]),
             'do_thing_always'
         ]),
     ])
     expr_converter = JinjaExpressionConverter()
     result = converter.convert_task_transitions(task_spec, expr_converter,
                                                 set())
     self.assertEquals(
         result,
         OrderedMap([
             ('next', [
                 OrderedMap([('when', '{{ succeeded() and (ctx().x) }}'),
                             ('publish', [{
                                 'good_data': '{{ ctx().good }}'
                             }]), ('do', [
                                 'do_thing_a',
                                 'do_thing_b',
                             ])]),
                 OrderedMap([('when', '{{ failed() and (ctx().e) }}'),
                             ('publish', [{
                                 'bad_data': '{{ ctx().bad }}'
                             }]), ('do', [
                                 'do_thing_error',
                             ])]),
                 OrderedMap([('do', [
                     'do_thing_always',
                 ])]),
                 OrderedMap([('when', '{{ ctx().d }}'),
                             ('do', [
                                 'do_thing_sometimes',
                             ])]),
             ]),
         ]))
コード例 #20
0
    def test_convert_task_transition_simple_no_publish(self):
        converter = WorkflowConverter()
        transitions = ['a', 'b', 'c']
        publish = None
        orquesta_expr = 'succeeded()'
        expr_converter = JinjaExpressionConverter()

        result = converter.convert_task_transition_simple(
            transitions, publish, orquesta_expr, expr_converter)

        expected = OrderedMap([
            ('when', '{{ succeeded() }}'),
            ('do', ['a', 'b', 'c']),
        ])
        self.assertEqual(result, expected)
コード例 #21
0
 def test_convert_tasks_join(self):
     converter = WorkflowConverter()
     expr_converter = YaqlExpressionConverter()
     mistral_tasks = OrderedMap([('jinja_task',
                                  OrderedMap([
                                      ('action', 'mypack.actionname'),
                                      ('join', 'all'),
                                  ]))])
     result = converter.convert_tasks(mistral_tasks, expr_converter, set())
     self.assertEqual(
         result,
         OrderedMap([('jinja_task',
                      OrderedMap([
                          ('action', 'mypack.actionname'),
                          ('join', 'all'),
                      ]))]))
コード例 #22
0
    def test_convert_task_transitions_common_publish_keys_same_values(self):
        converter = WorkflowConverter()
        task_spec = OrderedMap([
            ('publish',
             OrderedMap([
                 ('good_data', '{{ _.good }}'),
                 ('common_data_1', '{{ _.common_1 }}'),
                 ('common_data_2', '{{ _.common_2 }}'),
             ])),
            ('publish-on-error',
             OrderedMap([
                 ('bad_data', '{{ _.bad }}'),
                 ('common_data_1', '{{ _.common_1 }}'),
                 ('common_data_2', '{{ _.common_2 }}'),
             ])),
            ('on-complete', ['do_thing_always']),
        ])
        expr_converter = JinjaExpressionConverter()

        result = converter.convert_task_transitions("task_name", task_spec,
                                                    expr_converter, set())
        self.assertDictEqual(
            result,
            OrderedMap([
                ('next', [
                    OrderedMap([
                        ('publish', [
                            {
                                'good_data': '{{ ctx().good }}'
                            },
                            {
                                'common_data_1': '{{ ctx().common_1 }}'
                            },
                            {
                                'common_data_2': '{{ ctx().common_2 }}'
                            },
                            {
                                'bad_data': '{{ ctx().bad }}'
                            },
                        ]),
                        ('do', [
                            'do_thing_always',
                        ]),
                    ]),
                ]),
            ]))
コード例 #23
0
    def test_convert_task_transition_simple_no_transitions(self):
        converter = WorkflowConverter()
        transitions = None
        publish = OrderedMap([('key_plain', 'data'),
                              ('key_expr', '{{ _.test }}')])
        orquesta_expr = 'succeeded()'
        expr_converter = JinjaExpressionConverter()

        result = converter.convert_task_transition_simple(
            transitions, publish, orquesta_expr, expr_converter)

        expected = OrderedMap([
            ('when', '{{ succeeded() }}'),
            ('publish', [{
                'key_plain': 'data'
            }, {
                'key_expr': '{{ ctx().test }}'
            }]),
        ])
        self.assertEqual(result, expected)
コード例 #24
0
    def test_convert_task_transition_expr(self):
        converter = WorkflowConverter()
        expression_list = OrderedMap([('<% $.test %>', ['task1', 'task3']),
                                      ('{{ _.other }}', ['task2'])])
        orquesta_expr = 'succeeded()'

        result = converter.convert_task_transition_expr(
            expression_list, {}, orquesta_expr)

        expected = [
            OrderedMap([
                ('when', '<% succeeded() and (ctx().test) %>'),
                ('do', ['task1', 'task3']),
            ]),
            OrderedMap([
                ('when', '{{ succeeded() and (ctx().other) }}'),
                ('do', ['task2']),
            ]),
        ]
        self.assertEquals(result, expected)
コード例 #25
0
    def test_convert_task_transition_expr_no_orquesta_expr(self):
        converter = WorkflowConverter()
        expression_list = OrderedMap([('<% $.test %>', ['task1', 'task3']),
                                      ('{{ _.other }}', ['task2'])])
        orquesta_expr = None

        result = converter.convert_task_transition_expr(
            'task_name', expression_list, {}, orquesta_expr)

        expected = [
            OrderedMap([
                ('when', '<% ctx().test %>'),
                ('do', ['task1', 'task3']),
            ]),
            OrderedMap([
                ('when', '{{ ctx().other }}'),
                ('do', ['task2']),
            ]),
        ]
        self.assertEqual(result, expected)
コード例 #26
0
    def test_convert_task_transition_simple_no_orquesta_expr(self):
        converter = WorkflowConverter()
        transitions = ['a', 'b', 'c']
        publish = OrderedMap([('key_plain', 'data'),
                              ('key_expr', '{{ _.test }}')])
        orquesta_expr = None
        expr_converter = JinjaExpressionConverter()

        result = converter.convert_task_transition_simple(
            transitions, publish, orquesta_expr, expr_converter)

        expected = OrderedMap([
            ('publish', [{
                'key_plain': 'data'
            }, {
                'key_expr': '{{ ctx().test }}'
            }]),
            ('do', ['a', 'b', 'c']),
        ])
        self.assertEquals(result, expected)
コード例 #27
0
 def test_default_task_transition_map(self):
     converter = WorkflowConverter()
     result = converter.default_task_transition_map()
     self.assertEqual(
         result,
         OrderedMap([
             ('on-success',
              OrderedMap([
                  ('publish', OrderedMap()),
                  ('orquesta_expr', 'succeeded()'),
              ])),
             ('on-error',
              OrderedMap([
                  ('publish', OrderedMap()),
                  ('orquesta_expr', 'failed()'),
              ])),
             ('on-complete',
              OrderedMap([
                  ('publish', OrderedMap()),
                  ('orquesta_expr', None),
              ])),
         ]))
コード例 #28
0
 def test_group_task_transitions(self):
     converter = WorkflowConverter()
     transitions_list = [
         "simple transition string",
         {
             "key": "expr"
         },
         "another simple transition string",
         {
             "key2": "expression"
         },
         {
             "key3": "expr"
         },
     ]
     simple, expr = converter.group_task_transitions(transitions_list)
     self.assertEqual(
         simple,
         ["simple transition string", "another simple transition string"])
     expected = OrderedMap([("expr", ["key", "key3"]),
                            ("expression", ["key2"])])
     self.assertEqual(expr, expected)
コード例 #29
0
    def convert_file(self, filename, expr_type=None):
        # parse the Mistral workflow from file
        mistral_wf_data, mistral_wf_data_ruamel = yaml_utils.read_yaml(
            filename)

        # validate the Mistral workflow before we start
        mistral_wf_spec = mistral_workflow.instantiate(mistral_wf_data)
        self.validate_workflow_spec(mistral_wf_spec)

        # convert Mistral -> Orquesta
        mistral_wf = mistral_wf_data_ruamel[mistral_wf_spec.name]
        workflow_converter = WorkflowConverter()
        orquesta_wf_data_ruamel = workflow_converter.convert(
            mistral_wf, expr_type, force=self.args.force)
        orquesta_wf_data_str = yaml_utils.obj_to_yaml(orquesta_wf_data_ruamel)
        orquesta_wf_data = yaml_utils.yaml_to_obj(orquesta_wf_data_str)

        # validate we've generated a proper Orquesta workflow
        orquesta_wf_spec = orquesta_workflow.instantiate(orquesta_wf_data)
        if not self.args.force:
            self.validate_workflow_spec(orquesta_wf_spec)

        # write out the new Orquesta workflow to a YAML string
        return yaml_utils.obj_to_yaml(orquesta_wf_data_ruamel)
コード例 #30
0
    def test_convert_task_transitions_common_publish_keys_different_values(
            self):
        converter = WorkflowConverter()
        task_spec = OrderedMap([
            ('publish',
             OrderedMap([
                 ('good_data', '{{ _.good }}'),
                 ('common_key_1', '{{ _.common_data }}'),
                 ('common_key_2', '{{ _.different_data_1_1 }}'),
                 ('common_key_3', '{{ _.different_data_1_2 }}'),
             ])),
            ('publish-on-error',
             OrderedMap([
                 ('bad_data', '{{ _.bad }}'),
                 ('common_key_1', '{{ _.common_data }}'),
                 ('common_key_2', '{{ _.different_data_2_1 }}'),
                 ('common_key_3', '{{ _.different_data_2_2 }}'),
             ])),
            ('on-complete', [
                OrderedMap([('do_thing_sometimes', '{{ _.d }}')]),
                'do_thing_always'
            ]),
        ])
        expr_converter = JinjaExpressionConverter()

        with self.assertRaises(NotImplementedError) as ctx_m:
            converter.convert_task_transitions("tsk_name", task_spec,
                                               expr_converter, set())

        rgx = re.compile(
            r"Task 'tsk_name' contains one or more keys "
            r"\((?:common_key_2, common_key_3|common_key_3, common_key_2)\) "
            r"in both publish and publish-on-error dictionaries that have different "
            r"values\. Please either remove the common keys, or ensure that the "
            r"values of any common keys are the same\.")
        self.assertRegex(str(ctx_m.exception), rgx)