Merge "Add API integration tests for actions"
This commit is contained in:
commit
9ba091ae6e
@ -59,8 +59,7 @@ class WorkflowTestsV2(base.TestCase):
|
||||
resp, body = self.client.get_list_obj('workflows')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
names = [body['workflows'][i]['name']
|
||||
for i in range(len(body['workflows']))]
|
||||
names = [wf['name'] for wf in body['workflows']]
|
||||
self.assertIn('wf', names)
|
||||
|
||||
self.client.delete_obj('workflows', 'wf')
|
||||
@ -68,8 +67,7 @@ class WorkflowTestsV2(base.TestCase):
|
||||
|
||||
_, body = self.client.get_list_obj('workflows')
|
||||
|
||||
names = [body['workflows'][i]['name']
|
||||
for i in range(len(body['workflows']))]
|
||||
names = [wf['name'] for wf in body['workflows']]
|
||||
self.assertNotIn('wf', names)
|
||||
|
||||
@test.attr(type='smoke')
|
||||
@ -138,26 +136,25 @@ class CronTriggerTestsV2(base.TestCase):
|
||||
super(CronTriggerTestsV2, self).tearDown()
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_get_list_triggers(self):
|
||||
def test_get_list_cron_triggers(self):
|
||||
resp, body = self.client.get_list_obj('cron_triggers')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual([], body['cron_triggers'])
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_create_and_delete_triggers(self):
|
||||
def test_create_and_delete_cron_triggers(self):
|
||||
tr_name = 'trigger'
|
||||
resp, body = self.client.create_trigger(
|
||||
tr_name, '5 * * * *', self.wf_name)
|
||||
|
||||
resp, body = self.client.create_cron_trigger(
|
||||
tr_name, '5 * * * *', self.wf_name)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(tr_name, body['name'])
|
||||
|
||||
resp, body = self.client.get_list_obj('cron_triggers')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
trs_names = [body['cron_triggers'][i]['name']
|
||||
for i in range(len(body['cron_triggers']))]
|
||||
|
||||
trs_names = [tr['name'] for tr in body['cron_triggers']]
|
||||
self.assertIn(tr_name, trs_names)
|
||||
|
||||
self.client.delete_obj('cron_triggers', tr_name)
|
||||
@ -165,38 +162,35 @@ class CronTriggerTestsV2(base.TestCase):
|
||||
|
||||
_, body = self.client.get_list_obj('cron_triggers')
|
||||
|
||||
trs_names = [body['cron_triggers'][i]['name']
|
||||
for i in range(len(body['cron_triggers']))]
|
||||
trs_names = [tr['name'] for tr in body['cron_triggers']]
|
||||
self.assertNotIn(tr_name, trs_names)
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_create_two_triggers_for_one_wf(self):
|
||||
def test_create_two_cron_triggers_for_one_wf(self):
|
||||
tr_name_1 = 'trigger1'
|
||||
tr_name_2 = 'trigger2'
|
||||
resp, body = self.client.create_trigger(
|
||||
tr_name_1, '5 * * * *', self.wf_name)
|
||||
|
||||
resp, body = self.client.create_cron_trigger(
|
||||
tr_name_1, '5 * * * *', self.wf_name)
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(tr_name_1, body['name'])
|
||||
|
||||
resp, body = self.client.create_trigger(
|
||||
resp, body = self.client.create_cron_trigger(
|
||||
tr_name_2, '15 * * * *', self.wf_name)
|
||||
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(tr_name_2, body['name'])
|
||||
|
||||
resp, body = self.client.get_list_obj('cron_triggers')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
trs_names = [body['cron_triggers'][i]['name']
|
||||
for i in range(len(body['cron_triggers']))]
|
||||
|
||||
trs_names = [tr['name'] for tr in body['cron_triggers']]
|
||||
self.assertIn(tr_name_1, trs_names)
|
||||
self.assertIn(tr_name_2, trs_names)
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_get_trigger(self):
|
||||
def test_get_cron_trigger(self):
|
||||
tr_name = 'trigger'
|
||||
self.client.create_trigger(
|
||||
self.client.create_cron_trigger(
|
||||
tr_name, '5 * * * *', self.wf_name)
|
||||
|
||||
resp, body = self.client.get_object('cron_triggers', tr_name)
|
||||
@ -205,13 +199,13 @@ class CronTriggerTestsV2(base.TestCase):
|
||||
self.assertEqual(tr_name, body['name'])
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_create_trigger_nonexistent_wf(self):
|
||||
def test_create_cron_trigger_nonexistent_wf(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.client.create_trigger,
|
||||
self.client.create_cron_trigger,
|
||||
'trigger', '5 * * * *', 'nonexist')
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_get_nonexistent_trigger(self):
|
||||
def test_get_nonexistent_cron_trigger(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.client.get_object,
|
||||
'cron_triggers', 'trigger')
|
||||
@ -223,31 +217,180 @@ class CronTriggerTestsV2(base.TestCase):
|
||||
'cron_triggers', 'trigger')
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_create_two_triggers_with_same_name(self):
|
||||
def test_create_two_cron_triggers_with_same_name(self):
|
||||
tr_name = 'trigger'
|
||||
self.client.create_trigger(
|
||||
self.client.create_cron_trigger(
|
||||
tr_name, '5 * * * *', self.wf_name)
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.client.create_trigger,
|
||||
self.client.create_cron_trigger,
|
||||
tr_name, '5 * * * *', self.wf_name)
|
||||
|
||||
@test.skip_because(bug="1383146")
|
||||
@test.attr(type='negative')
|
||||
def test_create_two_triggers_with_same_pattern(self):
|
||||
def test_create_two_cron_triggers_with_same_pattern(self):
|
||||
self.client.create_trigger(
|
||||
'trigger1', '5 * * * *', self.wf_name)
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.client.create_trigger,
|
||||
self.client.create_cron_trigger,
|
||||
'trigger2', '5 * * * *', self.wf_name)
|
||||
|
||||
@test.attr(type='nagative')
|
||||
def test_invalid_pattern_not_enough_params(self):
|
||||
def test_invalid_cron_pattern_not_enough_params(self):
|
||||
self.assertRaises(exceptions.ServerFault,
|
||||
self.client.create_trigger,
|
||||
self.client.create_cron_trigger,
|
||||
'trigger', '5 *', self.wf_name)
|
||||
|
||||
@test.attr(type='nagative')
|
||||
def test_invalid_pattern_out_of_range(self):
|
||||
def test_invalid_cron_pattern_out_of_range(self):
|
||||
self.assertRaises(exceptions.ServerFault,
|
||||
self.client.create_trigger,
|
||||
self.client.create_cron_trigger,
|
||||
'trigger', '88 * * * *', self.wf_name)
|
||||
|
||||
|
||||
class ActionTestsV2(base.TestCase):
|
||||
|
||||
_version = 2
|
||||
|
||||
def get_field_value(self, body, act_name, field):
|
||||
return [body['actions'][i][field]
|
||||
for i in range(len(body['actions']))
|
||||
if body['actions'][i]['name'] == act_name][0]
|
||||
|
||||
def tearDown(self):
|
||||
for act in self.client.actions:
|
||||
self.client.delete_obj('actions', act)
|
||||
self.client.actions = []
|
||||
|
||||
super(ActionTestsV2, self).tearDown()
|
||||
|
||||
@test.attr(type='smoke')
|
||||
def test_get_list_actions(self):
|
||||
resp, body = self.client.get_list_obj('actions')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertNotEqual([], body['actions'])
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_create_and_delete_few_actions(self):
|
||||
text = base.get_resource('resources/action_v2.yaml')
|
||||
action1_name = 'greeting'
|
||||
action2_name = 'farewell'
|
||||
|
||||
resp, body = self.client.create_action(text)
|
||||
self.assertEqual(201, resp.status)
|
||||
|
||||
actions = [action['name'] for action in body['actions']]
|
||||
self.assertIn(action1_name, actions)
|
||||
self.assertIn(action2_name, actions)
|
||||
|
||||
resp, body = self.client.get_list_obj('actions')
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
actions = [action['name'] for action in body['actions']]
|
||||
self.assertIn(action1_name, actions)
|
||||
self.assertIn(action2_name, actions)
|
||||
|
||||
self.client.delete_obj('actions', action1_name)
|
||||
self.client.delete_obj('actions', action2_name)
|
||||
|
||||
_, body = self.client.get_list_obj('actions')
|
||||
|
||||
actions = [action['name'] for action in body['actions']]
|
||||
self.assertNotIn(action1_name, actions)
|
||||
self.assertNotIn(action2_name, actions)
|
||||
self.client.actions.remove(action1_name)
|
||||
self.client.actions.remove(action2_name)
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_get_action(self):
|
||||
text = base.get_resource('resources/action_v2.yaml')
|
||||
action1_name = 'greeting'
|
||||
self.client.create_action(text)
|
||||
|
||||
resp, body = self.client.get_object('actions', action1_name)
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertEqual(action1_name, body['name'])
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_update_action(self):
|
||||
text = base.get_resource('resources/action_v2.yaml')
|
||||
act1_name = 'greeting'
|
||||
act2_name = 'farewell'
|
||||
|
||||
resp, body = self.client.create_action(text)
|
||||
act1_created_at = self.get_field_value(
|
||||
body=body, act_name=act1_name, field='created_at')
|
||||
act2_created_at = self.get_field_value(
|
||||
body=body, act_name=act2_name, field='created_at')
|
||||
|
||||
self.assertNotIn('updated at', body['actions'])
|
||||
|
||||
resp, body = self.client.update_action(text)
|
||||
self.assertEqual(200, resp.status)
|
||||
|
||||
actions = [action['name'] for action in body['actions']]
|
||||
self.assertIn(act1_name, actions)
|
||||
self.assertIn(act2_name, actions)
|
||||
|
||||
updated1_created_at = self.get_field_value(
|
||||
body=body, act_name=act1_name, field='created_at')
|
||||
updated2_created_at = self.get_field_value(
|
||||
body=body, act_name=act2_name, field='created_at')
|
||||
|
||||
self.assertEqual(act1_created_at.split(".")[0], updated1_created_at)
|
||||
self.assertEqual(act2_created_at.split(".")[0], updated2_created_at)
|
||||
self.assertTrue(all(['updated_at' in item
|
||||
for item in body['actions']]))
|
||||
|
||||
@test.attr(type='sanity')
|
||||
def test_get_action_definition(self):
|
||||
text = base.get_resource('resources/action_v2.yaml')
|
||||
action1_name = 'greeting'
|
||||
action2_name = 'farewell'
|
||||
self.client.create_action(text)
|
||||
|
||||
resp, body = self.client.get_action_definition(action1_name)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertIsNotNone(body)
|
||||
|
||||
resp, body = self.client.get_action_definition(action2_name)
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertIsNotNone(body)
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_get_nonexistent_action(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.client.get_object,
|
||||
'actions', 'nonexist')
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_double_creation(self):
|
||||
text = base.get_resource('resources/action_v2.yaml')
|
||||
self.client.create_action(text)
|
||||
|
||||
self.assertRaises(exceptions.Conflict,
|
||||
self.client.create_action,
|
||||
text)
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_create_action_invalid_def(self):
|
||||
self.assertRaises(exceptions.ServerFault,
|
||||
self.client.create_action, "")
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_update_action_invalid_def(self):
|
||||
self.assertRaises(exceptions.ServerFault,
|
||||
self.client.update_action, "")
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_delete_nonexistent_action(self):
|
||||
self.assertRaises(exceptions.NotFound,
|
||||
self.client.delete_obj,
|
||||
'actions', 'nonexist')
|
||||
|
||||
@test.attr(type='negative')
|
||||
def test_delete_standard_action(self):
|
||||
self.assertRaises(exceptions.BadRequest,
|
||||
self.client.delete_obj,
|
||||
'actions', 'nova.servers_create')
|
||||
|
@ -73,6 +73,7 @@ class MistralClientBase(rest_client.RestClient):
|
||||
self.executions = []
|
||||
self.workflows = []
|
||||
self.triggers = []
|
||||
self.actions = []
|
||||
|
||||
def get_list_obj(self, name):
|
||||
resp, body = self.get(name)
|
||||
@ -287,7 +288,7 @@ class MistralClientV2(MistralClientBase):
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def create_trigger(self, name, pattern, wf_name, wf_input=None):
|
||||
def create_cron_trigger(self, name, pattern, wf_name, wf_input=None):
|
||||
post_body = {
|
||||
'name': name,
|
||||
'pattern': pattern,
|
||||
@ -302,6 +303,27 @@ class MistralClientV2(MistralClientBase):
|
||||
|
||||
return rest, json.loads(body)
|
||||
|
||||
def create_action(self, text):
|
||||
post_body = {"definition": "%s" % text}
|
||||
resp, body = self.post('actions',
|
||||
json.dumps(post_body))
|
||||
self.actions.extend(
|
||||
[action['name'] for action in json.loads(body)['actions']])
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def update_action(self, text):
|
||||
post_body = {"definition": "%s" % text}
|
||||
resp, body = self.put('actions',
|
||||
json.dumps(post_body))
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def get_action_definition(self, name):
|
||||
resp, body = self.get("actions/%s" % name)
|
||||
|
||||
return resp, json.loads(body)['definition']
|
||||
|
||||
|
||||
class AuthProv(auth.KeystoneV2AuthProvider):
|
||||
|
||||
|
21
mistral/tests/resources/action_v2.yaml
Normal file
21
mistral/tests/resources/action_v2.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
version: "2.0"
|
||||
|
||||
greeting:
|
||||
description: "This action says 'Hello'"
|
||||
tags: [hello]
|
||||
base: std.echo
|
||||
base-input:
|
||||
output: 'Hello, {$.name}'
|
||||
input:
|
||||
- name
|
||||
output:
|
||||
string: $.output
|
||||
|
||||
farewell:
|
||||
base: std.echo
|
||||
base-input:
|
||||
output: 'Bye!'
|
||||
output:
|
||||
info: $.output
|
||||
|
Loading…
Reference in New Issue
Block a user