c31a9533fa
This change relocates the mistral resources from the contrib area into the main resource tree. It was originally added to contrib/ because of the project's incubation status, and more specifically because the client is not in the global-requirements.txt file. However, when this was discussed at the summit in Vancouver, the decision was to move the resources to main tree but skip registration if the client is not installed. This will save users from the trouble of installing it as a plugin. Change-Id: I6eeef5fa2b080df610e52620d2b935450d8d49e3
125 lines
4.6 KiB
Python
125 lines
4.6 KiB
Python
#
|
|
# 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.
|
|
|
|
import mock
|
|
from oslo_utils import importutils
|
|
import testtools
|
|
|
|
from heat.common import exception
|
|
from heat.common import template_format
|
|
from heat.engine import resources
|
|
from heat.engine.resources.openstack.mistral import cron_trigger
|
|
from heat.engine import scheduler
|
|
from heat.engine import stack as stack_parser
|
|
from heat.engine import template
|
|
from heat.tests import common
|
|
from heat.tests import utils
|
|
|
|
mistral_client = importutils.try_import('mistralclient.api.base')
|
|
|
|
stack_template = '''
|
|
heat_template_version: 2013-05-23
|
|
|
|
resources:
|
|
cron_trigger:
|
|
type: OS::Mistral::CronTrigger
|
|
properties:
|
|
name: my_cron_trigger
|
|
pattern: "* * 0 * *"
|
|
workflow: {'name': 'get_first_glance_image', 'input': {} }
|
|
count: 3
|
|
first_time: "2015-04-08 06:20"
|
|
'''
|
|
|
|
|
|
class FakeCronTrigger(object):
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
self.next_execution_time = '2015-03-01 00:00:00'
|
|
self.remaining_executions = 3
|
|
|
|
|
|
class MistralCronTriggerTest(common.HeatTestCase):
|
|
|
|
def setUp(self):
|
|
super(MistralCronTriggerTest, self).setUp()
|
|
resources.initialise()
|
|
utils.setup_dummy_db()
|
|
self.ctx = utils.dummy_context()
|
|
|
|
t = template_format.parse(stack_template)
|
|
self.stack = utils.parse_stack(t)
|
|
resource_defns = self.stack.t.resource_definitions(self.stack)
|
|
self.rsrc_defn = resource_defns['cron_trigger']
|
|
|
|
self.client = mock.Mock()
|
|
self.patchobject(cron_trigger.CronTrigger, 'client',
|
|
return_value=self.client)
|
|
|
|
def _create_resource(self, name, snippet, stack):
|
|
ct = cron_trigger.CronTrigger(name, snippet, stack)
|
|
self.client.cron_triggers.create.return_value = FakeCronTrigger(
|
|
'my_cron_trigger')
|
|
self.client.cron_triggers.get.return_value = FakeCronTrigger(
|
|
'my_cron_trigger')
|
|
scheduler.TaskRunner(ct.create)()
|
|
args = self.client.cron_triggers.create.call_args[1]
|
|
self.assertEqual('* * 0 * *', args['pattern'])
|
|
self.assertEqual('get_first_glance_image', args['workflow_name'])
|
|
self.assertEqual({}, args['workflow_input'])
|
|
self.assertEqual('2015-04-08 06:20', args['first_time'])
|
|
self.assertEqual(3, args['count'])
|
|
self.assertEqual('my_cron_trigger', ct.resource_id)
|
|
return ct
|
|
|
|
def test_create(self):
|
|
ct = self._create_resource('trigger', self.rsrc_defn, self.stack)
|
|
expected_state = (ct.CREATE, ct.COMPLETE)
|
|
self.assertEqual(expected_state, ct.state)
|
|
|
|
def test_resource_mapping(self):
|
|
mapping = cron_trigger.resource_mapping()
|
|
self.assertEqual(1, len(mapping))
|
|
self.assertEqual(cron_trigger.CronTrigger,
|
|
mapping['OS::Mistral::CronTrigger'])
|
|
|
|
def test_attributes(self):
|
|
ct = self._create_resource('trigger', self.rsrc_defn, self.stack)
|
|
self.assertEqual('2015-03-01 00:00:00',
|
|
ct.FnGetAtt('next_execution_time'))
|
|
self.assertEqual(3, ct.FnGetAtt('remaining_executions'))
|
|
|
|
def test_delete(self):
|
|
ct = self._create_resource('trigger', self.rsrc_defn, self.stack)
|
|
scheduler.TaskRunner(ct.delete)()
|
|
self.assertEqual((ct.DELETE, ct.COMPLETE), ct.state)
|
|
self.client.cron_triggers.delete.assert_called_once_with(
|
|
ct.resource_id)
|
|
|
|
def test_delete_not_found(self):
|
|
ct = self._create_resource('trigger', self.rsrc_defn, self.stack)
|
|
self.client.cron_triggers.delete.side_effect = (
|
|
self.client.mistral_base.APIException(error_code=404))
|
|
scheduler.TaskRunner(ct.delete)()
|
|
self.assertEqual((ct.DELETE, ct.COMPLETE), ct.state)
|
|
self.client.cron_triggers.delete.assert_called_once_with(
|
|
ct.resource_id)
|
|
|
|
@testtools.skipIf(mistral_client is not None,
|
|
'Tests mistral client not installed')
|
|
def test_no_client(self):
|
|
tmpl = template.Template((template_format.parse(stack_template)))
|
|
stack = stack_parser.Stack(utils.dummy_context(), 'foo', tmpl)
|
|
self.assertRaises(exception.ResourceTypeNotFound, stack.validate)
|