338 lines
12 KiB
Python
338 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Copyright 2016 Mirantis, Inc.
|
|
#
|
|
# 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.
|
|
|
|
from nailgun import consts
|
|
from nailgun.lcm.context import TransactionContext
|
|
from nailgun.lcm import task_serializer
|
|
from nailgun.settings import settings
|
|
|
|
from nailgun.test.base import BaseUnitTest
|
|
|
|
|
|
class TestTaskSerializerContext(BaseUnitTest):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.transaction = TransactionContext(
|
|
{
|
|
'common': {
|
|
'cluster': {'id': 1},
|
|
'release': {'version': 'liberty-9.0'},
|
|
'openstack_version': 'liberty-9.0',
|
|
'public_ssl': {'hostname': 'localhost'},
|
|
},
|
|
'nodes': {
|
|
'1': {
|
|
'attribute': '1'
|
|
}
|
|
}
|
|
}
|
|
)
|
|
cls.context = task_serializer.Context(cls.transaction)
|
|
|
|
def test_transform_legacy_condition(self):
|
|
cases = [
|
|
(
|
|
'settings:additional_components.ceilometer.value == 1 or ',
|
|
'settings:ceilometer.enabled == 1 or ',
|
|
),
|
|
(
|
|
'settings:common.vms_create.value == 1 or '
|
|
'settings:common.vms_create.value == 2',
|
|
'settings:vms_create == 1 or settings:vms_create == 2',
|
|
),
|
|
(
|
|
'settings:my.id.value == 2 or settings:my.id.value == 1',
|
|
'settings:my.id == 2 or settings:my.id == 1',
|
|
),
|
|
(
|
|
'settings:common.value.id == 2 or '
|
|
'settings:common.value.id == 1',
|
|
'settings:value.id == 2 or settings:value.id == 1',
|
|
),
|
|
(
|
|
'cluster:id == 2 or cluster:id == 1',
|
|
'cluster:id == 2 or cluster:id == 1'
|
|
),
|
|
(
|
|
'cluster:common.id.value == 2 or cluster:common.id.value == 1',
|
|
'cluster:common.id.value == 2 or cluster:common.id.value == 1',
|
|
),
|
|
]
|
|
for value, expected in cases:
|
|
self.assertEqual(
|
|
expected,
|
|
self.context.transform_legacy_condition(value)
|
|
)
|
|
|
|
def test_get_new_data(self):
|
|
self.assertEqual(
|
|
self.transaction.get_new_data('1'),
|
|
self.context.get_new_data('1')
|
|
)
|
|
|
|
def test_get_legacy_interpreter(self):
|
|
interpreter = self.context.get_legacy_interpreter('1')
|
|
self.assertTrue(interpreter('cluster:id == 1'))
|
|
self.assertTrue(interpreter("settings:common.attribute.value == '1'"))
|
|
|
|
def test_get_formatter_context(self):
|
|
self.assertEqual(
|
|
{
|
|
'CLUSTER_ID': 1,
|
|
'OPENSTACK_VERSION': 'liberty-9.0',
|
|
'MASTER_IP': settings.MASTER_IP,
|
|
'CN_HOSTNAME': 'localhost',
|
|
'SETTINGS': settings,
|
|
},
|
|
self.context.get_formatter_context('1')
|
|
)
|
|
|
|
|
|
class TestTaskSerializer(BaseUnitTest):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.transaction_context = TransactionContext({
|
|
'common': {
|
|
'cluster': {'id': 1},
|
|
'release': {'version': 'liberty-9.0'},
|
|
'openstack_version': 'liberty-9.0',
|
|
'public_ssl': {'hostname': 'localhost'},
|
|
},
|
|
'nodes': {
|
|
'1': {
|
|
'cluster': {'id': 1},
|
|
'attributes': {
|
|
'a_str': 'text1',
|
|
'a_int': 1
|
|
}
|
|
},
|
|
'2': {
|
|
'cluster': {'id': 2},
|
|
'attributes': {
|
|
'a_str': 'text2',
|
|
'a_int': 2
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
cls.context = task_serializer.Context(cls.transaction_context)
|
|
|
|
|
|
class TestDefaultTaskSerializer(TestTaskSerializer):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestDefaultTaskSerializer, cls).setUpClass()
|
|
cls.serializer_class = task_serializer.DefaultTaskSerializer
|
|
|
|
def check_condition(self, condition, expected):
|
|
task_template = {
|
|
'id': 'test',
|
|
'type': 'puppet',
|
|
'parameters': {},
|
|
'condition': condition
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
for node_id, result in expected:
|
|
self.assertEqual(result, serializer.should_execute(
|
|
task_template, node_id
|
|
))
|
|
|
|
def test_should_execute_legacy_condition_for_settings(self):
|
|
self.check_condition(
|
|
"settings:common.attributes.a_str.value == 'text1'",
|
|
[('1', True), ('2', False)]
|
|
)
|
|
|
|
def test_should_execute_legacy_condition_for_cluster(self):
|
|
self.check_condition(
|
|
"cluster:id == 1",
|
|
[('1', True), ('2', False)]
|
|
)
|
|
|
|
def should_execute_returns_condition_if_it_is_bool(self):
|
|
self.check_condition(False, [('1', False), ('2', False)])
|
|
self.check_condition(True, [('1', True), ('2', True)])
|
|
|
|
def should_execute_returns_true_if_no_condition(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'type': 'puppet',
|
|
'parameters': {},
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
self.assertTrue(serializer.should_execute('1'))
|
|
self.assertTrue(serializer.should_execute('2'))
|
|
|
|
def test_serialize_with_format(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'roles': ['controller'],
|
|
'condition': '1',
|
|
'type': 'upload_file',
|
|
'parameters': {
|
|
'data': {
|
|
'yaql_exp': '$.cluster',
|
|
},
|
|
'path': '/etc/{CLUSTER_ID}/astute.yaml'
|
|
},
|
|
'requires': ['deploy_start'],
|
|
'required_for': ['deploy_end'],
|
|
'cross_depends': [],
|
|
'cross_depended_by': [],
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
serialized = serializer.serialize('1')
|
|
task_template['parameters']['data'] = \
|
|
self.context.get_new_data('1')['cluster']
|
|
task_template['parameters']['path'] = '/etc/1/astute.yaml'
|
|
task_template['parameters']['cwd'] = '/'
|
|
task_template['fail_on_error'] = True
|
|
del task_template['condition']
|
|
del task_template['roles']
|
|
self.assertEqual(task_template, serialized)
|
|
|
|
def test_serialize_does_not_fail_if_format_fail(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'type': 'upload_file',
|
|
'parameters': {
|
|
'cmd': "cat /etc/astute.yaml | awk '{ print $1 }'",
|
|
'cwd': '/tmp/'
|
|
},
|
|
'fail_on_error': False,
|
|
'required_for': None,
|
|
'requires': None,
|
|
'cross_depends': [],
|
|
'cross_depended_by': []
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
serialized = serializer.serialize('1')
|
|
self.assertEqual(task_template, serialized)
|
|
|
|
def test_serialize_skipped_task(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'type': 'upload_file',
|
|
'condition': '0',
|
|
'parameters': {
|
|
'cmd': "cat /etc/astute.yaml | awk '{ print $1 }'",
|
|
'cwd': '/tmp/'
|
|
},
|
|
'fail_on_error': True,
|
|
'requires': ['deploy_start'],
|
|
'required_for': ['deploy_end'],
|
|
'cross_depends': [{'roles': '*', 'name': 'task1'}],
|
|
'cross_depended_by': [{'roles': '*', 'name': 'task1'}],
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
serialized = serializer.serialize('1')
|
|
self.assertEqual(
|
|
{
|
|
'id': 'test',
|
|
'type': consts.ORCHESTRATOR_TASK_TYPES.skipped,
|
|
'fail_on_error': False,
|
|
'requires': ['deploy_start'],
|
|
'required_for': ['deploy_end'],
|
|
'cross_depends': [{'roles': '*', 'name': 'task1'}],
|
|
'cross_depended_by': [{'roles': '*', 'name': 'task1'}],
|
|
},
|
|
serialized
|
|
)
|
|
|
|
def test_serialize_context_components(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'roles': ['controller'],
|
|
'type': 'upload_file',
|
|
'parameters': {
|
|
'data': {
|
|
'yaql_exp': '$node',
|
|
},
|
|
'data2': {
|
|
'yaql_exp': '$common',
|
|
},
|
|
'path': '/etc/{CLUSTER_ID}/astute.yaml'
|
|
},
|
|
'requires': ['deploy_start'],
|
|
'required_for': ['deploy_end'],
|
|
'cross_depends': [],
|
|
'cross_depended_by': [],
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
serialized = serializer.serialize('1')
|
|
self.assertEqual(serialized['parameters']['data'],
|
|
self.transaction_context.get_new_node_data('1'))
|
|
self.assertEqual(serialized['parameters']['data2'],
|
|
self.transaction_context.get_new_common_data())
|
|
|
|
|
|
class TestNoopTaskSerialzer(TestTaskSerializer):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestNoopTaskSerialzer, cls).setUpClass()
|
|
cls.serializer_class = task_serializer.NoopTaskSerializer
|
|
|
|
def test_serialize(self):
|
|
task_template = {
|
|
'id': 'test',
|
|
'type': 'skipped',
|
|
'parameters': {},
|
|
'fail_on_error': True,
|
|
'requires': {'yaql_exp': '["deploy_start"]'},
|
|
'required_for': ['deploy_end'],
|
|
}
|
|
serializer = self.serializer_class(self.context, task_template)
|
|
serialized = serializer.serialize('1')
|
|
self.assertEqual(
|
|
{
|
|
'id': 'test', 'type': 'skipped', 'fail_on_error': False,
|
|
'requires': ['deploy_start'], 'required_for': ['deploy_end']
|
|
},
|
|
serialized
|
|
)
|
|
|
|
|
|
class TestTasksSerializersFactory(BaseUnitTest):
|
|
factory_class = task_serializer.TasksSerializersFactory
|
|
|
|
def test_create_serializer_for_generic(self):
|
|
common_task_types = set(consts.ORCHESTRATOR_TASK_TYPES)
|
|
common_task_types.discard(consts.ORCHESTRATOR_TASK_TYPES.role)
|
|
common_task_types.discard(consts.ORCHESTRATOR_TASK_TYPES.skipped)
|
|
common_task_types.discard(consts.ORCHESTRATOR_TASK_TYPES.stage)
|
|
common_task_types.discard(consts.ORCHESTRATOR_TASK_TYPES.group)
|
|
|
|
factory = self.factory_class(TransactionContext({}))
|
|
for task_type in common_task_types:
|
|
task = {'id': 'test', 'type': task_type}
|
|
self.assertIsInstance(
|
|
factory.create_serializer(task),
|
|
task_serializer.DefaultTaskSerializer
|
|
)
|
|
|
|
def test_create_noop_serializer(self):
|
|
noop_task_types = [
|
|
consts.ORCHESTRATOR_TASK_TYPES.skipped,
|
|
consts.ORCHESTRATOR_TASK_TYPES.stage
|
|
]
|
|
factory = self.factory_class(TransactionContext({}))
|
|
for task_type in noop_task_types:
|
|
task = {'id': 'test', 'type': task_type}
|
|
self.assertIsInstance(
|
|
factory.create_serializer(task),
|
|
task_serializer.NoopTaskSerializer
|
|
)
|