From d1997d616b765866f1b8b30ef6f3c87f845353f2 Mon Sep 17 00:00:00 2001 From: Maxim Kulkin Date: Wed, 16 Oct 2013 11:32:28 +0400 Subject: [PATCH] Added minimal support for running Lettuce-based inspections --- discover_test.py | 4 +- ostack_validator/inspections/__init__.py | 1 + .../inspections/lettuce/sample.feature | 8 +++ ostack_validator/inspections/lettuce/steps.py | 67 +++++++++++++++++++ .../inspections/lettuce_runner.py | 20 ++++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 ostack_validator/inspections/lettuce/sample.feature create mode 100644 ostack_validator/inspections/lettuce/steps.py create mode 100644 ostack_validator/inspections/lettuce_runner.py diff --git a/discover_test.py b/discover_test.py index 8a72e2b..822085f 100644 --- a/discover_test.py +++ b/discover_test.py @@ -4,7 +4,7 @@ from itertools import groupby from ostack_validator.common import Issue, MarkedIssue, Inspection from ostack_validator.model import OpenstackComponent from ostack_validator.discovery import OpenstackDiscovery -from ostack_validator.inspections import KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection +from ostack_validator.inspections import KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection, LettuceRunnerInspection def indent_prefix(indent=0): s = '' @@ -62,7 +62,7 @@ def main(): openstack = discovery.discover(['172.18.65.179'], 'root', private_key=private_key) - all_inspections = [KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection] + all_inspections = [KeystoneAuthtokenSettingsInspection, KeystoneEndpointsInspection, LettuceRunnerInspection] for inspection in all_inspections: x = inspection() x.inspect(openstack) diff --git a/ostack_validator/inspections/__init__.py b/ostack_validator/inspections/__init__.py index b9e71c5..3126d17 100644 --- a/ostack_validator/inspections/__init__.py +++ b/ostack_validator/inspections/__init__.py @@ -1,3 +1,4 @@ from ostack_validator.inspections.keystone_authtoken import KeystoneAuthtokenSettingsInspection from ostack_validator.inspections.keystone_endpoints import KeystoneEndpointsInspection +from ostack_validator.inspections.lettuce_runner import LettuceRunnerInspection diff --git a/ostack_validator/inspections/lettuce/sample.feature b/ostack_validator/inspections/lettuce/sample.feature new file mode 100644 index 0000000..3525747 --- /dev/null +++ b/ostack_validator/inspections/lettuce/sample.feature @@ -0,0 +1,8 @@ +Feature: Configuration consistency + + Scenario: Nova has proper Keystone host + Given I use OpenStack 2013.1 + And Nova has "auth_strategy" equal to "keystone" + And Keystone addresses are @X + Then Nova should have "keystone_authtoken.auth_host" in "$X" + diff --git a/ostack_validator/inspections/lettuce/steps.py b/ostack_validator/inspections/lettuce/steps.py new file mode 100644 index 0000000..acee845 --- /dev/null +++ b/ostack_validator/inspections/lettuce/steps.py @@ -0,0 +1,67 @@ +import string +from lettuce import * + +from ostack_validator.common import Issue, Version, find +from ostack_validator.model import * + +def get_variable(name): + if not hasattr(world, 'variables'): + return None + + return world.variables.get(name) + +def set_variable(name, value): + if not hasattr(world, 'variables'): + world.variables = {} + + world.variables[name] = value + +def subst(template): + if not hasattr(world, 'variables'): + return template + + tmpl = string.Template(template) + return tmpl.safe_substitute(world.variables) + +def stop(): + assert False, "stop" + +@step(r'I use OpenStack (\w+)') +def use_openstack_version(step, version): + version = Version(version) + for component in [c for c in world.openstack.components if isinstance(c, OpenstackComponent)]: + if not Version(component.version) >= version: stop() + +@step(r'Nova has "(.+)" equal to "(.*)"') +def nova_has_property(step, name, value): + name = subst(name) + value = subst(value) + + for nova in [c for c in world.openstack.components if c.name.startswith('nova')]: + if not nova.config[name] == value: stop() + +@step(r'Keystone addresses are @(\w+)') +def keystone_addresses(self, variable): + keystone = find(world.openstack.components, lambda c: c.name == 'keystone') + + if keystone.config['bind_host'] == '0.0.0.0': + addresses = filter(lambda ip: not ip.startswith('127.'), keystone.host.network_addresses) + else: + addresses = [keystone.config['bind_host']] + + set_variable(variable, addresses) + +@step(r'Nova should have "(.+)" in "(.*)"') +def nova_property_assertion(self, name, values): + name = subst(name) + values = subst(values) + + if not values: + return + + for nova in [c for c in world.openstack.components if c.name.startswith('nova')]: + nova_value = nova.config[name] + + if not (nova_value and nova_value in values): + nova.report_issue(Issue(Issue.ERROR, 'Nova should have "%s" in %s' % (name, values))) + diff --git a/ostack_validator/inspections/lettuce_runner.py b/ostack_validator/inspections/lettuce_runner.py new file mode 100644 index 0000000..cec92f1 --- /dev/null +++ b/ostack_validator/inspections/lettuce_runner.py @@ -0,0 +1,20 @@ +import os.path +import lettuce + +from ostack_validator.common import Inspection, Issue + +class LettuceRunnerInspection(Inspection): + def inspect(self, openstack): + runner = lettuce.Runner( + base_path=os.path.join(os.path.dirname(__file__), 'lettuce') + ) + + lettuce.world.openstack = openstack + result = runner.run() + del lettuce.world.openstack + + for feature_result in result.feature_results: + for scenario_result in [s for s in feature_result.scenario_results if not s.passed]: + for step in scenario_result.steps_undefined: + openstack.report_issue(Issue(Issue.ERROR, 'Undefined step "%s"' % step.sentence)) +