Trigger remaining-executions and first-exec-date

Adds the support of two optionals parameters for the cron-trigger resource:
  -first-execution-time : --first-time <"YYYY-MM-DD HH:MM">
  -remaining_occurrences : --count <integer>

The positional parameter "pattern" is now: --pattern <"* * * * *">

Implements: blueprint mistral-cron-triggers-start-and-repeat
Depends-On: I55bc28e98f89ffdfdce9cb3daa3848a17d85fd20
Change-Id: I2059db83e217ff415fb3f43dca27904b8f9acdce
This commit is contained in:
Pierre-Arthur MATHIEU
2015-03-12 16:50:11 +00:00
parent 6066a75dbe
commit 103e5ecb9a
6 changed files with 111 additions and 36 deletions

View File

@@ -24,17 +24,19 @@ class CronTrigger(base.Resource):
class CronTriggerManager(base.ResourceManager):
resource_class = CronTrigger
def create(self, name, pattern, workflow_name, workflow_input=None):
def create(self, name, workflow_name, workflow_input=None, pattern=None,
first_time=None, count=None):
self._ensure_not_empty(
name=name,
pattern=pattern,
workflow_name=workflow_name
)
data = {
'name': name,
'pattern': pattern,
'workflow_name': workflow_name,
'pattern': pattern,
'first_execution_time': first_time,
'remaining_executions': count
}
if workflow_input:

View File

@@ -33,11 +33,12 @@ def format_list(trigger=None):
def format(trigger=None, lister=False):
columns = (
'Name',
'Pattern',
'Workflow',
'Pattern',
# TODO(rakhmerov): Uncomment when passwords are handled properly.
# TODO(rakhmerov): Add 'Workflow input' column.
'Next execution time',
'Remaining executions',
'Created at',
'Updated at'
)
@@ -49,11 +50,12 @@ def format(trigger=None, lister=False):
data = (
trigger.name,
trigger.pattern,
trigger.workflow_name,
trigger.pattern,
# TODO(rakhmerov): Uncomment when passwords are handled properly.
# TODo(rakhmerov): Add 'wf_input' here.
trigger.next_execution_time,
trigger.remaining_executions,
trigger.created_at,
)
@@ -100,7 +102,6 @@ class Create(show.ShowOne):
parser = super(Create, self).get_parser(prog_name)
parser.add_argument('name', help='Cron trigger name')
parser.add_argument('pattern', help='Cron trigger pattern')
parser.add_argument('workflow_name', help='Workflow name')
parser.add_argument(
@@ -109,6 +110,25 @@ class Create(show.ShowOne):
help='Workflow input'
)
parser.add_argument(
'--pattern',
type=str,
help='Cron trigger pattern',
metavar='<* * * * *>'
)
parser.add_argument(
'--first-time',
type=str,
help="Date and time of the first execution",
metavar='<YYYY-MM-DD HH:MM>'
)
parser.add_argument(
'--count',
type=int,
help="Number of wanted executions",
metavar='<integer>'
)
return parser
def take_action(self, parsed_args):
@@ -124,9 +144,11 @@ class Create(show.ShowOne):
trigger = mgr.create(
parsed_args.name,
parsed_args.pattern,
parsed_args.workflow_name,
wf_input
wf_input,
parsed_args.pattern,
parsed_args.first_time,
parsed_args.count
)
return format(trigger)

View File

@@ -115,12 +115,20 @@ class MistralClientTestBase(base.MistralCLIAuth, base.MistralCLIAltAuth):
return acts
def cron_trigger_create(self, name, pattern,
wf_name, wf_input, admin=True):
def cron_trigger_create(self, name, wf_name, wf_input, pattern=None,
count=None, first_time=None, admin=True):
optional_params = ""
if pattern:
optional_params += ' --pattern "{}"'.format(pattern)
if count:
optional_params += ' --count {}'.format(count)
if first_time:
optional_params += ' --first-time "{}"'.format(first_time)
trigger = self.mistral_cli(
admin,
'cron-trigger-create',
params='%s "%s" %s %s' % (name, pattern, wf_name, wf_input))
params='{} {} {} {}'.format(name, wf_name, wf_input,
optional_params))
self.addCleanup(self.mistral_cli,
admin,
'cron-trigger-delete',

View File

@@ -224,7 +224,7 @@ class CronTriggerIsolationCLITests(base_v2.MistralClientTestBase):
def test_cron_trigger_name_uniqueness(self):
wf = self.workflow_create(self.wf_def)
self.cron_trigger_create(
"trigger", "5 * * * *", wf[0]["Name"], "{}")
"trigger", wf[0]["Name"], "{}", "5 * * * *")
self.assertRaises(
exceptions.CommandFailed,
@@ -236,23 +236,20 @@ class CronTriggerIsolationCLITests(base_v2.MistralClientTestBase):
)
wf = self.workflow_create(self.wf_def, admin=False)
self.cron_trigger_create(
"trigger", "5 * * * *", wf[0]["Name"], "{}", admin=False)
self.cron_trigger_create("trigger", wf[0]["Name"], "{}", "5 * * * *",
None, None, admin=False)
self.assertRaises(
exceptions.CommandFailed,
self.cron_trigger_create,
"trigger",
"5 * * * *",
wf[0]["Name"],
"{}",
admin=False
"trigger", wf[0]["Name"], "{}", "5 * * * *",
None, None, admin=False
)
def test_cron_trigger_isolation(self):
wf = self.workflow_create(self.wf_def)
self.cron_trigger_create(
"trigger", "5 * * * *", wf[0]["Name"], "{}")
"trigger", wf[0]["Name"], "{}", "5 * * * *")
alt_trs = self.mistral_alt_user("cron-trigger-list")

View File

@@ -67,8 +67,8 @@ class SimpleMistralCLITests(base.MistralCLIAuth):
self.mistral('cron-trigger-list'))
self.assertTableStruct(
triggers,
['Name', 'Pattern', 'Workflow', 'Next execution time',
'Created at', 'Updated at']
['Name', 'Workflow', 'Pattern', 'Next execution time',
'Remaining executions', 'Created at', 'Updated at']
)
def test_actions_list(self):
@@ -369,16 +369,21 @@ class CronTriggerCLITests(base_v2.MistralClientTestBase):
def test_cron_trigger_create_delete(self):
trigger = self.mistral_admin(
'cron-trigger-create',
params='trigger "5 * * * *" %s {}' % self.wf_name)
params=('trigger %s {} --pattern "5 * * * *" --count 5'
' --first-time "4242-12-25 13:37"' % self.wf_name))
self.assertTableStruct(trigger, ['Field', 'Value'])
tr_name = self.get_value_of_field(trigger, 'Name')
wf_name = self.get_value_of_field(trigger, 'Workflow')
created_at = self.get_value_of_field(trigger, 'Created at')
remain = self.get_value_of_field(trigger, 'Remaining executions')
next_time = self.get_value_of_field(trigger, 'Next execution time')
self.assertEqual('trigger', tr_name)
self.assertEqual(self.wf_name, wf_name)
self.assertIsNotNone(created_at)
self.assertEqual("4242-12-25 13:37:00", next_time)
self.assertEqual("5", remain)
trgs = self.mistral_admin('cron-trigger-list')
self.assertIn(tr_name, [tr['Name'] for tr in trgs])
@@ -391,9 +396,9 @@ class CronTriggerCLITests(base_v2.MistralClientTestBase):
def test_two_cron_triggers_for_one_wf(self):
self.cron_trigger_create(
'trigger1', "5 * * * *", self.wf_name, '{}')
'trigger1', self.wf_name, '{}', "5 * * * *")
self.cron_trigger_create(
'trigger2', "15 * * * *", self.wf_name, '{}')
'trigger2', self.wf_name, '{}', "15 * * * *")
trgs = self.mistral_admin('cron-trigger-list')
self.assertIn("trigger1", [tr['Name'] for tr in trgs])
@@ -401,7 +406,7 @@ class CronTriggerCLITests(base_v2.MistralClientTestBase):
def test_cron_trigger_get(self):
trigger = self.cron_trigger_create(
'trigger', "5 * * * *", self.wf_name, '{}')
'trigger', self.wf_name, '{}', "5 * * * *")
self.assertTableStruct(trigger, ['Field', 'Value'])
tr_name = self.get_value_of_field(trigger, 'Name')
@@ -857,27 +862,28 @@ class NegativeCLITests(base_v2.MistralClientTestBase):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr "" %s {}' % wf[0]['Name'])
params='tr %s {}' % wf[0]['Name'])
def test_tr_create_invalid_pattern(self):
wf = self.workflow_create(self.wf_def)
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr "q" %s {}' % wf[0]['Name'])
params='tr %s {} --pattern "q"' % wf[0]['Name'])
def test_tr_create_invalid_pattern_value_out_of_range(self):
wf = self.workflow_create(self.wf_def)
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr "88 * * * *" %s {}' % wf[0]['Name'])
params='tr %s {}'
' --pattern "80 * * * *"' % wf[0]['Name'])
def test_tr_create_nonexistent_wf(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr "* * * * *" wb.wf1 {}')
params='tr wb.wf1 {} --pattern "* * * * *"')
def test_tr_delete_nonexistant_tr(self):
self.assertRaises(exceptions.CommandFailed,
@@ -891,6 +897,41 @@ class NegativeCLITests(base_v2.MistralClientTestBase):
'cron-trigger-get',
params='tr')
def test_tr_create_invalid_count(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr wb.wf1 {}'
' --pattern "* * * * *" --count q')
def test_tr_create_negative_count(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr wb.wf1 {}'
' --pattern "* * * * *" --count -1')
def test_tr_create_invalid_first_date(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr wb.wf1 {}'
' --pattern "* * * * *"'
' --first-date "q"')
def test_tr_create_count_only(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr wb.wf1 {} --count 42')
def test_tr_create_date_and_count_without_pattern(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral_admin,
'cron-trigger-create',
params='tr wb.wf1 {} --count 42'
' --first-time "4242-12-25 13:37"')
def test_action_get_nonexistent(self):
self.assertRaises(exceptions.CommandFailed,
self.mistral,

View File

@@ -23,10 +23,11 @@ from mistralclient.tests.unit import base
TRIGGER_DICT = {
'name': 'my_trigger',
'pattern': '* * * * *',
'workflow_name': 'flow1',
'workflow_input': {},
'next_execution_time': '1',
'pattern': '* * * * *',
'next_execution_time': '4242-12-20 13:37',
'remaining_executions': 5,
'created_at': '1',
'updated_at': '1'
}
@@ -44,11 +45,13 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
result = self.call(
cron_triggers_cmd.Create,
app_args=['my_trigger', '* * * * *', 'flow1']
app_args=['my_trigger', 'flow1', '--pattern', '* * * * *',
'--count', '5', '--first-time', '4242-12-20 13:37']
)
self.assertEqual(
('my_trigger', '* * * * *', 'flow1', '1', '1', '1'),
('my_trigger', 'flow1', '* * * * *', '4242-12-20 13:37', 5, '1',
'1'),
result[1]
)
@@ -59,7 +62,8 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
result = self.call(cron_triggers_cmd.List)
self.assertEqual(
[('my_trigger', '* * * * *', 'flow1', '1', '1', '1')],
[('my_trigger', 'flow1', '* * * * *', '4242-12-20 13:37', 5, '1',
'1')],
result[1]
)
@@ -70,7 +74,8 @@ class TestCLIWorkbooksV2(base.BaseCommandTest):
result = self.call(cron_triggers_cmd.Get, app_args=['name'])
self.assertEqual(
('my_trigger', '* * * * *', 'flow1', '1', '1', '1'),
('my_trigger', 'flow1', '* * * * *', '4242-12-20 13:37', 5, '1',
'1'),
result[1]
)