24cdb64a1e
This commit removes H233 from ignored list and fixes corresponding code to pass the check. Change-Id: I5f842e74e5c05f421307e29c059d63b309f1d23d
290 lines
10 KiB
Python
290 lines
10 KiB
Python
# Copyright (c) 2014 OpenStack Foundation.
|
|
# All Rights Reserved.
|
|
#
|
|
# 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 inspect
|
|
import os.path
|
|
|
|
import unittest2 as unittest
|
|
import yaml
|
|
|
|
from murano.common import uuidutils
|
|
from murano.dsl import helpers
|
|
from murano.dsl import package_loader
|
|
import murano.policy.congress_rules as congress
|
|
|
|
TENANT_ID = 'de305d5475b4431badb2eb6b9e546013'
|
|
|
|
|
|
class MockPackageLoader(package_loader.MuranoPackageLoader):
|
|
def __init__(self, rules):
|
|
"""Create rules like this: ['child->parent', 'child->parent2']."""
|
|
|
|
self._classes = {}
|
|
rules_dict = {}
|
|
for rule in rules:
|
|
split = rule.split('->')
|
|
rules_dict.setdefault(split[0], []).append(split[1])
|
|
classes = (self.get_class(cls, rules_dict) for cls in rules_dict)
|
|
self._package = MockPackage(classes)
|
|
|
|
def get_class(self, name, rules_dict):
|
|
if name in self._classes:
|
|
return self._classes[name]
|
|
parents = [self.get_class(parent, rules_dict)
|
|
for parent in rules_dict.get(name, [])]
|
|
result = MockClass({'name': name, 'declared_parents': parents})
|
|
self._classes[name] = result
|
|
return result
|
|
|
|
def register_package(self, package):
|
|
pass
|
|
|
|
def load_class_package(self, class_name, version_spec):
|
|
return self._package
|
|
|
|
def load_package(self, package_name, version_spec):
|
|
return self._package
|
|
|
|
|
|
class MockPackage(object):
|
|
def __init__(self, classes):
|
|
self._classes = {}
|
|
for cls in classes:
|
|
self._classes[cls.name] = cls
|
|
|
|
@property
|
|
def classes(self):
|
|
return self._classes.keys()
|
|
|
|
def find_class(self, name, *args, **kwargs):
|
|
return self._classes.get(name)
|
|
|
|
|
|
class MockClass(object):
|
|
def __init__(self, entries):
|
|
self.__dict__.update(entries)
|
|
|
|
def ancestors(self):
|
|
return helpers.traverse(self, lambda t: t.declared_parents)
|
|
|
|
|
|
class TestCongressRules(unittest.TestCase):
|
|
|
|
def _load_file(self, file_name):
|
|
model_file = os.path.join(
|
|
os.path.dirname(inspect.getfile(self.__class__)), file_name)
|
|
|
|
with open(model_file) as stream:
|
|
return yaml.load(stream)
|
|
|
|
def _create_rules_str(self, model_file, package_loader=None):
|
|
model = self._load_file(model_file)
|
|
|
|
congress_rules = congress.CongressRulesManager()
|
|
rules = congress_rules.convert(model, package_loader,
|
|
tenant_id=TENANT_ID)
|
|
rules_str = ", \n".join(map(str, rules))
|
|
|
|
return rules_str
|
|
|
|
def test_transitive_closure(self):
|
|
closure = congress.CongressRulesManager.transitive_closure(
|
|
[(1, 2), (2, 3), (3, 4)])
|
|
self.assertTrue((1, 4) in closure)
|
|
self.assertTrue((2, 4) in closure)
|
|
|
|
def test_empty_model(self):
|
|
congress_rules = congress.CongressRulesManager()
|
|
rules = congress_rules.convert(None)
|
|
self.assertTrue(len(rules) == 0)
|
|
|
|
def test_convert_simple_app(self):
|
|
rules_str = self._create_and_check_rules_str('model')
|
|
|
|
self.assertFalse("instance." in rules_str)
|
|
|
|
def test_convert_model_two_instances(self):
|
|
rules_str = self._create_and_check_rules_str('model_two_instances')
|
|
|
|
self.assertFalse("\"instances\"" in rules_str)
|
|
|
|
def test_convert_model_with_relations(self):
|
|
rules_str = self._create_rules_str('model_with_relations.yaml')
|
|
|
|
self.assertFalse(
|
|
'murano:properties+("50fa68ff-cd9a-4845-b573-2c80879d158d", '
|
|
'"server", "8ce94f23-f16a-40a1-9d9d-a877266c315d")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:relationships+("50fa68ff-cd9a-4845-b573-2c80879d158d", '
|
|
'"8ce94f23-f16a-40a1-9d9d-a877266c315d", "server")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:relationships+("0aafd67e-72e9-4ae0-bb62-fe724f77df2a", '
|
|
'"ed8df2b0-ddd2-4009-b3c9-2e7a368f3cb8", "instance")' in rules_str)
|
|
|
|
def test_convert_model_transitive_relationships(self):
|
|
rules_str = self._create_rules_str('model_with_relations.yaml')
|
|
|
|
self.assertTrue(
|
|
'murano:connected+("50fa68ff-cd9a-4845-b573-2c80879d158d", '
|
|
'"8ce94f23-f16a-40a1-9d9d-a877266c315d")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:connected+("8ce94f23-f16a-40a1-9d9d-a877266c315d", '
|
|
'"fc6b8c41-166f-4fc9-a640-d82009e0a03d")' in rules_str)
|
|
|
|
def test_convert_model_services_relationship(self):
|
|
rules_str = self._create_rules_str('model_with_relations.yaml')
|
|
|
|
self.assertTrue(
|
|
'murano:relationships+("3409bdd0590e4c60b70fda5e6777ff96", '
|
|
'"8ce94f23-f16a-40a1-9d9d-a877266c315d", "services")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:relationships+("3409bdd0590e4c60b70fda5e6777ff96", '
|
|
'"50fa68ff-cd9a-4845-b573-2c80879d158d", "services")' in rules_str)
|
|
|
|
def test_convert_model_complex(self):
|
|
self._create_and_check_rules_str('model_complex')
|
|
|
|
def test_convert_renamed_app(self):
|
|
self._create_and_check_rules_str('model_renamed')
|
|
|
|
def test_parent_types(self):
|
|
|
|
# grand-parent
|
|
# / \
|
|
# parent1 parent2
|
|
# \ /
|
|
# io.murano.apps.linux.Git
|
|
|
|
package_loader = MockPackageLoader([
|
|
'io.murano.apps.linux.Git->parent1',
|
|
'io.murano.apps.linux.Git->parent2',
|
|
'parent1->grand-parent',
|
|
'parent2->grand-parent'
|
|
])
|
|
|
|
rules_str = self._create_rules_str('model.yaml', package_loader)
|
|
|
|
self.assertTrue(
|
|
'murano:parent_types+("0c810278-7282-4e4a-9d69-7b4c36b6ce6f",'
|
|
' "parent1")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:parent_types+("0c810278-7282-4e4a-9d69-7b4c36b6ce6f",'
|
|
' "parent2")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:parent_types+("0c810278-7282-4e4a-9d69-7b4c36b6ce6f",'
|
|
' "grand-parent")' in rules_str)
|
|
|
|
self.assertTrue(
|
|
'murano:parent_types+("0c810278-7282-4e4a-9d69-7b4c36b6ce6f",'
|
|
' "io.murano.apps.linux.Git")' in rules_str)
|
|
|
|
def test_to_dictionary(self):
|
|
"""If model contains object entry (not dict)
|
|
we try to convert to dict using 'to_dictionary' method.
|
|
"""
|
|
|
|
class Struct(object):
|
|
def __init__(self, d):
|
|
self.__dict__ = d
|
|
|
|
def to_dictionary(self):
|
|
return self.__dict__
|
|
|
|
def __getitem__(self, item):
|
|
return self.__dict__[item]
|
|
|
|
d = {'?': {'id': '1', 'type': 't1'},
|
|
'apps': [Struct({'?': {'id': '2', 'type': 't2'},
|
|
'instances': [Struct(
|
|
{'?': {'id': '3', 'type': 't3'}})]})]
|
|
}
|
|
|
|
model = Struct(d)
|
|
|
|
congress_rules = congress.CongressRulesManager()
|
|
tenant_id = uuidutils.generate_uuid()
|
|
rules = congress_rules.convert(model, tenant_id=tenant_id)
|
|
rules_str = ", \n".join(map(str, rules))
|
|
|
|
self.assertTrue('murano:objects+("1", "{0}", "t1")'.format(tenant_id)
|
|
in rules_str)
|
|
self.assertTrue('murano:objects+("2", "1", "t2")' in rules_str)
|
|
self.assertTrue('murano:objects+("3", "2", "t3")' in rules_str)
|
|
|
|
def test_environment_owner(self):
|
|
model = self._load_file("model.yaml")
|
|
congress_rules = congress.CongressRulesManager()
|
|
rules = congress_rules.convert(model, tenant_id='tenant1')
|
|
rules_str = ", \n".join(map(str, rules))
|
|
self.assertTrue('murano:objects+("c86104748a0c4907b4c5981e6d3bce9f", '
|
|
'"tenant1", "io.murano.Environment")' in rules_str)
|
|
|
|
def test_wordpress(self):
|
|
package_loader = MockPackageLoader([
|
|
'io.murano.Environment->io.murano.Object',
|
|
'io.murano.resources.NeutronNetwork->io.murano.resources.Network',
|
|
'io.murano.resources.Network->io.murano.Object',
|
|
'io.murano.databases.MySql->io.murano.databases.SqlDatabase',
|
|
'io.murano.databases.MySql->io.murano.Application',
|
|
'io.murano.databases.SqlDatabase->io.murano.Object',
|
|
'io.murano.resources.LinuxInstance->io.murano.resources.Instance',
|
|
'io.murano.resources.Instance->io.murano.Object',
|
|
'io.murano.Application->io.murano.Object',
|
|
'io.murano.apps.apache.ApacheHttpServer->io.murano.Application',
|
|
'io.murano.apps.ZabbixServer->io.murano.Application',
|
|
'io.murano.apps.ZabbixAgent->io.murano.Application',
|
|
'io.murano.apps.WordPress->io.murano.Application',
|
|
|
|
'io.murano.resources.LinuxMuranoInstance->'
|
|
'io.murano.resources.LinuxInstance'
|
|
])
|
|
|
|
self._create_and_check_rules_str('wordpress', package_loader)
|
|
|
|
def _create_and_check_rules_str(self, model_name, package_loader=None):
|
|
rules_str = self._create_rules_str(
|
|
'{0}.yaml'.format(model_name), package_loader)
|
|
self._check_expected_rules(rules_str,
|
|
'expected_rules_{0}.txt'.format(model_name))
|
|
return rules_str
|
|
|
|
def _check_expected_rules(self, rules_str, expected_rules_file_name):
|
|
expected_rules_file = os.path.join(
|
|
os.path.dirname(inspect.getfile(self.__class__)),
|
|
expected_rules_file_name)
|
|
|
|
s = ''
|
|
with open(expected_rules_file) as f:
|
|
for line in f:
|
|
line = line.rstrip('\n')
|
|
if line not in rules_str:
|
|
s += 'Expected rule not found:\n\t' + line + '\n'
|
|
|
|
if len(s) > 0:
|
|
self.fail(s)
|
|
|
|
def test_state_rule(self):
|
|
rules_str = self._create_rules_str('model.yaml')
|
|
|
|
self.assertTrue(
|
|
'murano:states+("c86104748a0c4907b4c5981e6d3bce9f", "pending")'
|
|
in rules_str)
|