Hot SoftwareConfig model part
Provide components model and related methods Implements blueprint hot-software-config Change-Id: I251d10f25943513ef346883263a4dd2e0f6fb7a6
This commit is contained in:
parent
012087be2c
commit
2fa20bf0c7
|
@ -0,0 +1,99 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
(TYPE, PROPERTIES, SCRIPTS, RELATIONSHIPS) = (
|
||||
'type', 'properties', 'scripts', 'relationships')
|
||||
|
||||
(SOFTWARE_CONFIG_TYPE, HOSTED_ON, DEPENDS_ON) = (
|
||||
'OS::Heat::SoftwareConfig', 'hosted_on', 'depends_on')
|
||||
|
||||
|
||||
class Component(dict):
|
||||
"""
|
||||
Model for hot component.
|
||||
"""
|
||||
|
||||
def __init__(self, schema={}):
|
||||
super(Component, self).__init__(schema)
|
||||
|
||||
@property
|
||||
def properties(self):
|
||||
return self.get(PROPERTIES, {})
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self.get(TYPE, SOFTWARE_CONFIG_TYPE)
|
||||
|
||||
@property
|
||||
def scripts(self):
|
||||
return self.get(SCRIPTS, {})
|
||||
|
||||
@property
|
||||
def relations(self):
|
||||
return self.get(RELATIONSHIPS, [])
|
||||
|
||||
def hosted_on(self):
|
||||
for rel in self.relations:
|
||||
if HOSTED_ON in rel:
|
||||
return rel[HOSTED_ON]
|
||||
return None
|
||||
|
||||
def depends(self):
|
||||
deps = []
|
||||
rels = self.relations
|
||||
for rel in rels:
|
||||
if DEPENDS_ON in rel:
|
||||
deps.append(rel[DEPENDS_ON])
|
||||
return deps
|
||||
|
||||
|
||||
class Components(dict):
|
||||
"""
|
||||
Model for hot components.
|
||||
"""
|
||||
|
||||
def __init__(self, schema):
|
||||
items = schema.iteritems()
|
||||
schema = dict(map(lambda x: (x[0], Component(x[1])), items))
|
||||
super(Components, self).__init__(schema)
|
||||
|
||||
def depends(self):
|
||||
deps = []
|
||||
for (k, v) in self.iteritems():
|
||||
for dep in v.depends():
|
||||
if dep not in deps:
|
||||
deps.append(dep)
|
||||
return deps
|
||||
|
||||
def filter(self, hosted):
|
||||
return map(lambda x: x[0],
|
||||
filter(lambda x: x[1].hosted_on() == hosted,
|
||||
self.iteritems()))
|
||||
|
||||
def validate(self):
|
||||
deps = self.depends()
|
||||
for dep in deps:
|
||||
if dep not in self.iterkeys():
|
||||
raise ValueError('component %s is not defined.' % dep)
|
||||
comp = self[dep]
|
||||
if dep in comp.depends():
|
||||
raise ValueError('component %s depends on itself.' % dep)
|
||||
for (name, comp) in self.iteritems():
|
||||
cdeps = comp.depends()
|
||||
for dep in cdeps:
|
||||
if cdeps.count(dep) > 1:
|
||||
msg = 'duplicated %s in %s depends on.' % (dep, name)
|
||||
raise ValueError(msg)
|
||||
return True
|
|
@ -0,0 +1,218 @@
|
|||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# 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 heat.engine.components import Component
|
||||
from heat.engine.components import Components
|
||||
from heat.tests.common import HeatTestCase
|
||||
|
||||
|
||||
class ComponentTest(HeatTestCase):
|
||||
|
||||
def test_init(self):
|
||||
comp = Component()
|
||||
self.assertEqual(comp.type, 'OS::Heat::SoftwareConfig')
|
||||
self.assertEqual(comp.properties, {})
|
||||
self.assertEqual(comp.scripts, {})
|
||||
self.assertEqual(comp.relations, [])
|
||||
self.assertEqual(comp.hosted_on(), None)
|
||||
self.assertEqual(comp.depends(), [])
|
||||
|
||||
def test_hosted_on(self):
|
||||
schema = {
|
||||
'relationships': [
|
||||
{'hosted_on': 'wordpress'}
|
||||
]
|
||||
}
|
||||
comp = Component(schema)
|
||||
self.assertEqual(comp.hosted_on(), 'wordpress')
|
||||
|
||||
def test_depends(self):
|
||||
schema = {
|
||||
'relationships': [
|
||||
{'depends_on': 'config_mysql'}
|
||||
]
|
||||
}
|
||||
comp = Component(schema)
|
||||
self.assertEqual(comp.depends(), ['config_mysql'])
|
||||
|
||||
comp['relationships'].append({'depends_on': 'config_wordpress'})
|
||||
self.assertEqual(comp.depends(),
|
||||
['config_mysql', 'config_wordpress'])
|
||||
|
||||
|
||||
class ComponentsTest(HeatTestCase):
|
||||
|
||||
def test_init(self):
|
||||
schema = {}
|
||||
comps = Components(schema)
|
||||
self.assertEqual(0, len(comps))
|
||||
|
||||
schema['config_mysql'] = {}
|
||||
comps = Components(schema)
|
||||
self.assertEquals(1, len(comps))
|
||||
comp = comps['config_mysql']
|
||||
self.assertIsInstance(comp, Component)
|
||||
|
||||
def test_depends(self):
|
||||
schema = {
|
||||
'install_mysql': {
|
||||
},
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'install_mysql'}
|
||||
]
|
||||
},
|
||||
'start_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'config_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
comps = Components(schema)
|
||||
self.assertEqual(3, len(comps))
|
||||
deps = comps.depends()
|
||||
self.assertEqual(2, len(deps))
|
||||
self.assertIn('install_mysql', deps)
|
||||
self.assertIn('config_mysql', deps)
|
||||
|
||||
def test_multi_depends(self):
|
||||
schema = {
|
||||
'install_mysql': {
|
||||
},
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'install_mysql'}
|
||||
]
|
||||
},
|
||||
'start_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'config_mysql'}
|
||||
]
|
||||
},
|
||||
'install_wordpress': {},
|
||||
'config_wordpress': {
|
||||
'relationships': [
|
||||
{'depends_on': 'install_wordpress'}
|
||||
]
|
||||
},
|
||||
'start_wordpress': {
|
||||
'relationships': [
|
||||
{'depends_on': 'config_wordpress'},
|
||||
{'depends_on': 'start_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
comps = Components(schema)
|
||||
deps = comps.depends()
|
||||
self.assertEqual(5, len(deps))
|
||||
self.assertNotIn('start_wordpress', deps)
|
||||
self.assertIn('install_wordpress', deps)
|
||||
self.assertIn('config_wordpress', deps)
|
||||
self.assertIn('start_mysql', deps)
|
||||
self.assertIn('config_mysql', deps)
|
||||
self.assertIn('install_mysql', deps)
|
||||
|
||||
def test_filter(self):
|
||||
schema = {
|
||||
'install_mysql': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'mysql'}
|
||||
]
|
||||
},
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'mysql'},
|
||||
{'depends_on': 'install_mysql'}
|
||||
]
|
||||
},
|
||||
'start_mysql': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'mysql'},
|
||||
{'depends_on': 'config_mysql'}
|
||||
]
|
||||
},
|
||||
'install_wordpress': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'wordpress'}
|
||||
]
|
||||
},
|
||||
'config_wordpress': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'wordpress'},
|
||||
{'depends_on': 'install_wordpress'}
|
||||
]
|
||||
},
|
||||
'start_wordpress': {
|
||||
'relationships': [
|
||||
{'hosted_on': 'wordpress'},
|
||||
{'depends_on': 'config_wordpress'},
|
||||
{'depends_on': 'start_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
comps = Components(schema)
|
||||
names = comps.filter('mysql')
|
||||
self.assertEqual(3, len(names))
|
||||
self.assertIn('config_mysql', names)
|
||||
self.assertIn('install_mysql', names)
|
||||
self.assertIn('start_mysql', names)
|
||||
|
||||
names = comps.filter('wordpress')
|
||||
self.assertEqual(3, len(names))
|
||||
self.assertIn('config_wordpress', names)
|
||||
self.assertIn('install_wordpress', names)
|
||||
self.assertIn('start_wordpress', names)
|
||||
|
||||
def test_validate(self):
|
||||
schema = {'install_mysql': {}}
|
||||
comps = Components(schema)
|
||||
self.assertTrue(comps.validate())
|
||||
|
||||
schema = {
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'config_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
comps = Components(schema)
|
||||
err = self.assertRaises(ValueError, comps.validate)
|
||||
self.assertIn('component config_mysql depends on itself.', str(err))
|
||||
|
||||
schema = {
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'install_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
comps = Components(schema)
|
||||
err = self.assertRaises(ValueError, comps.validate)
|
||||
self.assertIn('component install_mysql is not defined.', str(err))
|
||||
|
||||
schema = {
|
||||
'install_mysql': {
|
||||
},
|
||||
'config_mysql': {
|
||||
'relationships': [
|
||||
{'depends_on': 'install_mysql'},
|
||||
{'depends_on': 'install_mysql'}
|
||||
]
|
||||
}
|
||||
}
|
||||
comps = Components(schema)
|
||||
err = self.assertRaises(ValueError, comps.validate)
|
||||
self.assertIn('duplicated install_mysql in config_mysql depends on.',
|
||||
str(err))
|
Loading…
Reference in New Issue