Added 'safe-rerun' policy to task-defaults section
Change-Id: Ib6641bda008a813660af5584c9319fcaddcd416f Signed-off-by: Vitalii Solodilov <mcdkr@yandex.ru>
This commit is contained in:
parent
48e17b3422
commit
a29c7d9f7f
@ -160,6 +160,7 @@ Common workflow attributes
|
|||||||
- **timeout** - Configures timeout policy. *Optional*.
|
- **timeout** - Configures timeout policy. *Optional*.
|
||||||
- **retry** - Configures retry policy. *Optional*.
|
- **retry** - Configures retry policy. *Optional*.
|
||||||
- **concurrency** - Configures concurrency policy. *Optional*.
|
- **concurrency** - Configures concurrency policy. *Optional*.
|
||||||
|
- **safe-rerun** - Configures safe-rerun policy. *Optional*.
|
||||||
|
|
||||||
- **tasks** - Dictionary containing workflow tasks. See below for more
|
- **tasks** - Dictionary containing workflow tasks. See below for more
|
||||||
details. *Required*.
|
details. *Required*.
|
||||||
|
@ -336,6 +336,22 @@ class Task(object):
|
|||||||
|
|
||||||
self.created = True
|
self.created = True
|
||||||
|
|
||||||
|
def _get_safe_rerun(self):
|
||||||
|
safe_rerun = self.task_spec.get_safe_rerun()
|
||||||
|
|
||||||
|
if safe_rerun is not None:
|
||||||
|
return safe_rerun
|
||||||
|
|
||||||
|
task_defaults = self.wf_spec.get_task_defaults()
|
||||||
|
|
||||||
|
if task_defaults:
|
||||||
|
default_safe_rerun = task_defaults.get_safe_rerun()
|
||||||
|
|
||||||
|
if default_safe_rerun is not None:
|
||||||
|
return default_safe_rerun
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def _get_action_defaults(self):
|
def _get_action_defaults(self):
|
||||||
action_name = self.task_spec.get_action_name()
|
action_name = self.task_spec.get_action_name()
|
||||||
|
|
||||||
@ -474,7 +490,7 @@ class RegularTask(Task):
|
|||||||
action.schedule(
|
action.schedule(
|
||||||
input_dict,
|
input_dict,
|
||||||
target,
|
target,
|
||||||
safe_rerun=self.task_spec.get_safe_rerun(),
|
safe_rerun=self._get_safe_rerun(),
|
||||||
timeout=self._get_timeout()
|
timeout=self._get_timeout()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -655,7 +671,7 @@ class WithItemsTask(RegularTask):
|
|||||||
input_dict,
|
input_dict,
|
||||||
target,
|
target,
|
||||||
index=i,
|
index=i,
|
||||||
safe_rerun=self.task_spec.get_safe_rerun(),
|
safe_rerun=self._get_safe_rerun(),
|
||||||
timeout=self._get_timeout()
|
timeout=self._get_timeout()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ class TaskDefaultsSpec(base.BaseSpec):
|
|||||||
"on-complete": types.ANY,
|
"on-complete": types.ANY,
|
||||||
"on-success": types.ANY,
|
"on-success": types.ANY,
|
||||||
"on-error": types.ANY,
|
"on-error": types.ANY,
|
||||||
|
"safe-rerun": types.EXPRESSION_OR_BOOLEAN,
|
||||||
"requires": {
|
"requires": {
|
||||||
"oneOf": [types.NONEMPTY_STRING, types.UNIQUE_STRING_LIST]
|
"oneOf": [types.NONEMPTY_STRING, types.UNIQUE_STRING_LIST]
|
||||||
}
|
}
|
||||||
@ -70,10 +71,17 @@ class TaskDefaultsSpec(base.BaseSpec):
|
|||||||
self._on_success = self._spec_property('on-success', on_spec_cls)
|
self._on_success = self._spec_property('on-success', on_spec_cls)
|
||||||
self._on_error = self._spec_property('on-error', on_spec_cls)
|
self._on_error = self._spec_property('on-error', on_spec_cls)
|
||||||
|
|
||||||
|
self._safe_rerun = data.get('safe-rerun')
|
||||||
|
|
||||||
# TODO(rakhmerov): 'requires' should reside in a different spec for
|
# TODO(rakhmerov): 'requires' should reside in a different spec for
|
||||||
# reverse workflows.
|
# reverse workflows.
|
||||||
self._requires = data.get('requires', [])
|
self._requires = data.get('requires', [])
|
||||||
|
|
||||||
|
def validate_schema(self):
|
||||||
|
super(TaskDefaultsSpec, self).validate_schema()
|
||||||
|
|
||||||
|
self.validate_expr(self._data.get('safe-rerun', {}))
|
||||||
|
|
||||||
def validate_semantics(self):
|
def validate_semantics(self):
|
||||||
# Validate YAQL expressions.
|
# Validate YAQL expressions.
|
||||||
self._validate_transitions(self._on_complete)
|
self._validate_transitions(self._on_complete)
|
||||||
@ -101,6 +109,9 @@ class TaskDefaultsSpec(base.BaseSpec):
|
|||||||
def get_on_error(self):
|
def get_on_error(self):
|
||||||
return self._on_error
|
return self._on_error
|
||||||
|
|
||||||
|
def get_safe_rerun(self):
|
||||||
|
return self._safe_rerun
|
||||||
|
|
||||||
def get_requires(self):
|
def get_requires(self):
|
||||||
if isinstance(self._requires, six.string_types):
|
if isinstance(self._requires, six.string_types):
|
||||||
return [self._requires]
|
return [self._requires]
|
||||||
|
@ -128,7 +128,7 @@ class TaskSpec(base.BaseSpec):
|
|||||||
)
|
)
|
||||||
self._target = data.get('target')
|
self._target = data.get('target')
|
||||||
self._keep_result = data.get('keep-result', True)
|
self._keep_result = data.get('keep-result', True)
|
||||||
self._safe_rerun = data.get('safe-rerun', False)
|
self._safe_rerun = data.get('safe-rerun')
|
||||||
|
|
||||||
self._process_action_and_workflow()
|
self._process_action_and_workflow()
|
||||||
|
|
||||||
|
@ -176,3 +176,68 @@ class TestSafeRerun(base.EngineTestCase):
|
|||||||
self.assertIn(1, result)
|
self.assertIn(1, result)
|
||||||
self.assertIn(2, result)
|
self.assertIn(2, result)
|
||||||
self.assertIn(3, result)
|
self.assertIn(3, result)
|
||||||
|
|
||||||
|
@mock.patch.object(r_exe.RemoteExecutor, 'run_action', MOCK_RUN_AT_TARGET)
|
||||||
|
def test_safe_rerun_in_task_defaults(self):
|
||||||
|
wf_text = """---
|
||||||
|
version: '2.0'
|
||||||
|
|
||||||
|
wf:
|
||||||
|
task-defaults:
|
||||||
|
safe-rerun: true
|
||||||
|
tasks:
|
||||||
|
task1:
|
||||||
|
safe-rerun: false
|
||||||
|
on-error:
|
||||||
|
- task2
|
||||||
|
|
||||||
|
task2:
|
||||||
|
action: std.noop
|
||||||
|
"""
|
||||||
|
|
||||||
|
wf_service.create_workflows(wf_text)
|
||||||
|
|
||||||
|
wf_ex = self.engine.start_workflow('wf')
|
||||||
|
|
||||||
|
self.await_workflow_success(wf_ex.id)
|
||||||
|
|
||||||
|
with db_api.transaction():
|
||||||
|
wf_ex = db_api.get_workflow_execution(wf_ex.id)
|
||||||
|
|
||||||
|
tasks = wf_ex.task_executions
|
||||||
|
|
||||||
|
self.assertEqual(len(tasks), 2)
|
||||||
|
|
||||||
|
task1 = self._assert_single_item(tasks, name='task1')
|
||||||
|
task2 = self._assert_single_item(tasks, name='task2')
|
||||||
|
|
||||||
|
self.assertEqual(task1.state, states.ERROR)
|
||||||
|
self.assertEqual(task2.state, states.SUCCESS)
|
||||||
|
|
||||||
|
@mock.patch.object(r_exe.RemoteExecutor, 'run_action', MOCK_RUN_AT_TARGET)
|
||||||
|
def test_default_value_of_safe_rerun(self):
|
||||||
|
wf_text = """---
|
||||||
|
version: '2.0'
|
||||||
|
|
||||||
|
wf:
|
||||||
|
tasks:
|
||||||
|
task1:
|
||||||
|
action: std.noop
|
||||||
|
"""
|
||||||
|
|
||||||
|
wf_service.create_workflows(wf_text)
|
||||||
|
|
||||||
|
wf_ex = self.engine.start_workflow('wf')
|
||||||
|
|
||||||
|
self.await_workflow_error(wf_ex.id)
|
||||||
|
|
||||||
|
with db_api.transaction():
|
||||||
|
wf_ex = db_api.get_workflow_execution(wf_ex.id)
|
||||||
|
|
||||||
|
tasks = wf_ex.task_executions
|
||||||
|
|
||||||
|
self.assertEqual(len(tasks), 1)
|
||||||
|
|
||||||
|
task1 = self._assert_single_item(tasks, name='task1')
|
||||||
|
|
||||||
|
self.assertEqual(task1.state, states.ERROR)
|
||||||
|
@ -713,3 +713,24 @@ class TaskSpecValidation(v2_base.WorkflowSpecValidationTestCase):
|
|||||||
changes=overlay,
|
changes=overlay,
|
||||||
expect_error=expect_error
|
expect_error=expect_error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_safe_rerurn(self):
|
||||||
|
tests = [
|
||||||
|
({'safe-rerun': True}, False),
|
||||||
|
({'safe-rerun': False}, False),
|
||||||
|
({'safe-rerun': '<% false %>'}, False),
|
||||||
|
({'safe-rerun': '<% true %>'}, False),
|
||||||
|
({'safe-rerun': '<% * %>'}, True),
|
||||||
|
({'safe-rerun': None}, True)
|
||||||
|
]
|
||||||
|
|
||||||
|
for default, expect_error in tests:
|
||||||
|
overlay = {'test': {'task-defaults': {}}}
|
||||||
|
|
||||||
|
utils.merge_dicts(overlay['test']['task-defaults'], default)
|
||||||
|
|
||||||
|
self._parse_dsl_spec(
|
||||||
|
add_tasks=True,
|
||||||
|
changes=overlay,
|
||||||
|
expect_error=expect_error
|
||||||
|
)
|
||||||
|
@ -383,7 +383,13 @@ class WorkflowSpecValidation(base.WorkflowSpecValidationTestCase):
|
|||||||
({'concurrency': '{{ * }}'}, True),
|
({'concurrency': '{{ * }}'}, True),
|
||||||
({'concurrency': -10}, True),
|
({'concurrency': -10}, True),
|
||||||
({'concurrency': 10.0}, True),
|
({'concurrency': 10.0}, True),
|
||||||
({'concurrency': '10'}, True)
|
({'concurrency': '10'}, True),
|
||||||
|
({'safe-rerun': True}, False),
|
||||||
|
({'safe-rerun': False}, False),
|
||||||
|
({'safe-rerun': '<% false %>'}, False),
|
||||||
|
({'safe-rerun': '<% true %>'}, False),
|
||||||
|
({'safe-rerun': '<% * %>'}, True),
|
||||||
|
({'safe-rerun': None}, True)
|
||||||
]
|
]
|
||||||
|
|
||||||
for default, expect_error in tests:
|
for default, expect_error in tests:
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Added 'safe-rerun' policy to task-defaults section
|
Loading…
x
Reference in New Issue
Block a user