From 0e2b012d69edf519e61c9e521fa0c652493baf78 Mon Sep 17 00:00:00 2001 From: "marina.koushnir@nokia.com" Date: Tue, 16 Feb 2016 15:54:43 +0000 Subject: [PATCH] get_topology validation & run_vitrage_tempest.sh Change-Id: Ia54cbb4a86f563089f591b6a8ce374d133d48650 --- requirements.txt | 1 - run_vitrage.sh | 86 ---------- run_vitrage_tempest.sh | 31 ++++ vitrage_tempest_tests/tests/__init__.py | 16 +- vitrage_tempest_tests/tests/api/base.py | 11 ++ .../tests/api/topology/topology.py | 107 +++++++----- .../tests/run_vitrage_env.py | 155 ++++++++---------- .../tests/stop_vitrage_env.py | 29 ++-- vitrage_tempest_tests/tests/utils.py | 99 +++++++++++ 9 files changed, 299 insertions(+), 236 deletions(-) delete mode 100755 run_vitrage.sh create mode 100755 run_vitrage_tempest.sh create mode 100644 vitrage_tempest_tests/tests/utils.py diff --git a/requirements.txt b/requirements.txt index 31fa50052..457026058 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,7 +16,6 @@ oslo.service>=1.0.0 # Apache-2.0 oslo.i18n>=2.1.0 pecan>=0.8.0 PasteDeploy>=1.5.0 -testtools>=1.4.0 Werkzeug>=0.7 keystonemiddleware>=2.3.0 stevedore>=1.5.0 # Apache-2.0 diff --git a/run_vitrage.sh b/run_vitrage.sh deleted file mode 100755 index b2b138a05..000000000 --- a/run_vitrage.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash - -function usage { - echo "Usage: $0 [OPTION]..." - echo "Run Vitrage Tempest tests" - echo "" - echo " -h, --help Print this usage message" - echo " -d, --debug Run tests with testtools instead of testr. This allows you to use PDB" - echo " -t, --serial Run testr serially" - echo " -c, --coverage Generate coverage report" - echo " -- [TESTROPTIONS] After the first '--' you can pass arbitrary arguments to testr " -} - -testrargs="" -debug=0 -serial=0 -coverage=0 -wrapper="" - -if ! options=$(getopt -o VNnfuctphd -l help,debug,serial,coverage -- "$@") -then - # parse error - usage - exit 1 -fi - -eval set -- $options -first_uu=yes -while [ $# -gt 0 ]; do - case "$1" in - -h|--help) usage; exit;; - -d|--debug) debug=1;; - -c|--coverage) coverage=1;; - -t|--serial) serial=1;; - --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no ;; - *) testrargs="$testrargs $1";; - esac - shift -done - -cd `dirname "$0"` - -function testr_init { - if [ ! -d .testrepository ]; then - ${wrapper} testr init - fi -} - -function run_tests { - testr_init - - echo "run env" - nosetests -vx vitrage_tempest_tests/tests/run_vitrage_env.py - - echo "run tests" - ${wrapper} find . -type f -name "*.pyc" -delete - export OS_TEST_PATH=./vitrage_tempest_tests/tests - - if [ "$testrargs" = "" ]; then - testrargs="discover ../vitrage_tempest_tests/tests" - fi - - if [ $debug -eq 1 ]; then - ${wrapper} python -m testtools.run $testrargs - return $? - fi - - if [ $coverage -eq 1 ]; then - ${wrapper} python setup.py test --coverage - return $? - fi - - if [ $serial -eq 1 ]; then - ${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-trace -n -f - else - ${wrapper} testr run --parallel --subunit $testrargs | ${wrapper} subunit-trace -n -f - fi - - echo "stop env" - nosetests -vx vitrage_tempest_tests/tests/stop_vitrage_env.py -} - -run_tests -retval=$? - -exit $retval \ No newline at end of file diff --git a/run_vitrage_tempest.sh b/run_vitrage_tempest.sh new file mode 100755 index 000000000..d0c90bca7 --- /dev/null +++ b/run_vitrage_tempest.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +function usage { + echo "Usage: run_vitrage_tempest.sh [OPTIONS]" + echo "Run Vitrage Tempest tests" + echo "" + echo " -h, --help Print this usage message" +} + +#case "$1" in +# -h|--help) usage; exit;; +# *) echo "Unknown command"; usage; exit;; +#esac + +function run_tests { + + find . -type f -name "*.pyc" -delete + + echo "run env" + nosetests -vx vitrage_tempest_tests/tests/run_vitrage_env.py + sleep 10s + + echo "run tests" + nosetests -vx vitrage_tempest_tests/tests/api/topology/* + sleep 5s + + echo "stop env" + nosetests -vx vitrage_tempest_tests/tests/stop_vitrage_env.py +} + +run_tests \ No newline at end of file diff --git a/vitrage_tempest_tests/tests/__init__.py b/vitrage_tempest_tests/tests/__init__.py index dd32b852f..adc40bd6c 100644 --- a/vitrage_tempest_tests/tests/__init__.py +++ b/vitrage_tempest_tests/tests/__init__.py @@ -12,4 +12,18 @@ # License for the specific language governing permissions and limitations # under the License. -__author__ = 'stack' +from oslo_config import cfg + +OPTS = [ + cfg.StrOpt('admin_user', + default='admin', + help='admin_user'), + cfg.StrOpt('admin_password', + default='password', + help='admin_password'), + cfg.StrOpt('admin_tenant_name', + default='admin', + help='admin_tenant_name'), + cfg.StrOpt('identity_uri', + help='identity_uri'), +] diff --git a/vitrage_tempest_tests/tests/api/base.py b/vitrage_tempest_tests/tests/api/base.py index 14a90671c..b388bf3cd 100644 --- a/vitrage_tempest_tests/tests/api/base.py +++ b/vitrage_tempest_tests/tests/api/base.py @@ -11,7 +11,11 @@ # 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 oslo_log import log as logging from vitrage.tests.base import BaseTest +from vitrage_tempest_tests.tests.base_mock import BaseMock + +LOG = logging.getLogger(__name__) class BaseVitrageTest(BaseTest): @@ -19,3 +23,10 @@ class BaseVitrageTest(BaseTest): def __init__(self, *args, **kwds): super(BaseVitrageTest, self).__init__(*args, **kwds) + + def _create_graph_by_mock(self): + """Create MOCK Graph and copied to the string """ + processor = BaseMock.create_processor_with_graph(self) + entity_graph = processor.entity_graph + mock_graph_output = entity_graph.output_graph() + LOG.info("The mock graph is : " + mock_graph_output) diff --git a/vitrage_tempest_tests/tests/api/topology/topology.py b/vitrage_tempest_tests/tests/api/topology/topology.py index 02bfe0647..15d962392 100644 --- a/vitrage_tempest_tests/tests/api/topology/topology.py +++ b/vitrage_tempest_tests/tests/api/topology/topology.py @@ -12,15 +12,15 @@ # License for the specific language governing permissions and limitations # under the License. -import os +import json +import subprocess +import vitrage_tempest_tests.tests.utils as utils -import oslo_messaging - -from oslo_config import cfg from oslo_log import log as logging + from vitrage.api.controllers.v1.topology import TopologyController +from vitrage.common.constants import VertexProperties as VProps from vitrage_tempest_tests.tests.api.base import BaseVitrageTest -from vitrage_tempest_tests.tests.base_mock import BaseMock LOG = logging.getLogger(__name__) @@ -35,32 +35,31 @@ class BaseTopologyTest(BaseVitrageTest): self.depth = '' self.query = '' self.root = '' - - """ Get client """ - transport = oslo_messaging.get_transport(cfg.CONF) - cfg.CONF.set_override('rpc_backend', 'rabbit') - target = oslo_messaging.Target(topic='rpcapiv1') - self.client = oslo_messaging.RPCClient(transport, target) - - def test_get_graph(self): - """Wrapper that returns a test graph.""" - self.graph_type = 'graph' - self.graph = self._get_topology() - self._validate_graph_correctness() - LOG.debug('The graph ' + self.name + ' does not exist') + self._get_env_params() + self.client = utils.get_client() def test_get_tree(self): """Wrapper that returns a test tree.""" self.graph_type = 'tree' self.graph = self._get_topology() - self._validate_graph_correctness() - LOG.debug('The graph tree ' + self.name + ' exist') + + def test_get_graph(self): + """Wrapper that returns a test graph.""" + self.graph_type = 'graph' + self.graph = self._get_topology() + + if self._validate_graph_correctness() is False: + LOG.error('The graph ' + self.name + ' is not correct') + else: + LOG.info('The graph ' + self.name + ' is correct') def _get_topology(self): """Get Graph objects returned by the v1 client """ try: - g = TopologyController().get_graph(graph_type=self.graph_type) - + g = TopologyController().get_graph(graph_type=self.graph_type, + depth=self.depth, + query=self.query, + root=self.root) except Exception as e: LOG.exception("Failed to get topology (graph_type = " + self.graph_type + ") %s ", e) @@ -69,25 +68,47 @@ class BaseTopologyTest(BaseVitrageTest): return g def _validate_graph_correctness(self): - """Compare Graph object to graph form os terminal """ - - print("The topology graph taken by api is : %s", self.graph) - - def _create_graph_by_mock(self): - """Create MOCK Graph and copied to the string """ - processor = BaseMock.create_processor_with_graph(self) - entity_graph = processor.entity_graph - a = entity_graph.output_graph() - print (a) - - @staticmethod - def _show_topology(): - text_out = os.popen("vitrage topology show").read() - print (text_out) - - if "RESOURCE" not in text_out: - LOG.info('The topology graph does not exist') + """Compare Graph object to graph form terminal """ + cli_graph = self._show_topology() + if cli_graph == '': + LOG.error("The topology graph taken from terminal is empty") return False - else: - LOG.info('The topology graph exist') - return True + + parsed_topology = json.loads(cli_graph) + LOG.debug("The topology graph taken from terminal is : " + + json.dumps(parsed_topology)) + LOG.debug("The topology graph taken by api is : %s", + json.dumps(self.graph)) + + cli_items = sorted(parsed_topology.items()) + api_items = sorted(self.graph.items()) + + for item in cli_items[4][1]: + item.pop(VProps.UPDATE_TIMESTAMP, None) + + for item in api_items[4][1]: + item.pop(VProps.UPDATE_TIMESTAMP, None) + + return cli_items == api_items + + def _show_topology(self): + LOG.debug("The command is : vitrage topology show") + p = subprocess.Popen("cd /home/stack/devstack; . openrc " + + self.user + " " + self.tenant_user + + "; vitrage topology show", + shell=True, + executable="/bin/bash", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if stderr != '': + LOG.error("The command output error is : " + stderr) + if stdout != '': + LOG.debug("The command output is : \n" + stdout) + return stdout + return None + + def _get_env_params(self): + conf = utils.get_conf() + self.user = conf.keystone_authtoken.admin_user + self.tenant_user = conf.keystone_authtoken.admin_tenant_name diff --git a/vitrage_tempest_tests/tests/run_vitrage_env.py b/vitrage_tempest_tests/tests/run_vitrage_env.py index c5b6f178c..6152d28fa 100644 --- a/vitrage_tempest_tests/tests/run_vitrage_env.py +++ b/vitrage_tempest_tests/tests/run_vitrage_env.py @@ -11,13 +11,18 @@ # 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 oslo_config import cfg from oslo_log import log as logging -import os -import re +import vitrage_tempest_tests.tests.utils as utils + import testtools LOG = logging.getLogger(__name__) +CONF = cfg.CONF +logging.register_options(CONF) +logging.setup(CONF, "vitrage") +logging.set_defaults(default_log_levels=utils.extra_log_level_defaults) class RunVitrageEnv(testtools.TestCase): @@ -26,41 +31,46 @@ class RunVitrageEnv(testtools.TestCase): def __init__(self, *args, **kwds): super(RunVitrageEnv, self).__init__(*args, **kwds) self.filename = '/opt/stack/vitrage/etc/vitrage/vitrage.conf' - self.port = '8999' def test_run_env(self): - self._set_env_params() - print("The host ip address = " + self.host + " with port " + self.port) - - LOG.info('MARINA!!!') if self._show_vitrage_processes() is True: - print ("The vitrage processed existed and should be removed") - LOG.info('The vitrage processed existed and should be removed') + LOG.debug('The vitrage processed existed and should be removed') self._stop_vitrage_processes() - os.system("openstack service create rca" + - " --os-username " + self.user + - " --os-password " + self.password + - " --os-auth-url " + self.url + - " --os-project-name admin" + - " --name vitrage") - os.system("openstack endpoint create rca --os-username " + self.user + - " --os-password " + self.password + - " --os-auth-url " + self.url + - " --os-project-name admin" + - " --adminurl http://" + self.host + ":" + self.port + - " --internalurl http://" + self.host + ":" + self.port + - " --publicurl http://" + self.host + ":" + self.port + - " --region RegionOne") + self._get_env_params() - os.chdir('/tmp') - os.system("\rm nohup.out") - os.system("nohup vitrage-graph &") - os.system("nohup vitrage-api &") + utils.change_terminal_dir('/home/stack/devstack') + utils.run_from_terminal("chmod +x openrc") + utils.run_from_terminal("./openrc " + self.user + " " + + self.tenant_user) + utils.run_from_terminal("openstack service create rca" + + " --os-username " + self.user + + " --os-password " + self.password + + " --os-auth-url " + self.url + + " --os-project-name admin" + + " --name vitrage") + utils.run_from_terminal("openstack endpoint create rca" + + " --os-username " + self.user + + " --os-username " + self.user + + " --os-password " + self.password + + " --os-auth-url " + self.url + + " --os-project-name admin" + + " --adminurl http://" + self.host + + ":" + str(self.port) + + " --internalurl http://" + self.host + + ":" + str(self.port) + + " --publicurl http://" + self.host + + ":" + str(self.port) + + " --region RegionOne") + + utils.run_from_terminal("nohup vitrage-graph > /tmp/nohup-graph.out &") + utils.run_from_terminal("nohup vitrage-api > /tmp/nohup-api.out &") if self._show_vitrage_processes() is False: LOG.error("No vitrage processes founded") raise ValueError("No vitrage processes founded") + else: + LOG.info('The vitrage processes exists') if self._validate_vitrage_processes() is False: LOG.error("The vitrage processes are not correct") @@ -69,88 +79,53 @@ class RunVitrageEnv(testtools.TestCase): @staticmethod def _show_vitrage_processes(): - text_out = os.popen( - "ps -ef | grep vitrage-api | grep -v grep").read() - print (text_out) - - text_out2 = os.popen( - "ps -ef | grep vitrage-graph | grep -v grep").read() - print (text_out2) + text_out = utils.get_from_terminal( + "ps -ef | grep vitrage-api | grep -v grep") + text_out2 = utils.get_from_terminal( + "ps -ef | grep vitrage-graph | grep -v grep") if ("vitrage-api" in text_out) and ("vitrage-graph" in text_out2): - LOG.info('The vitrage processes exists') + LOG.debug('The vitrage processes exists') return True elif "vitrage-api" in text_out: - LOG.info('Only vitrage-api process exist') + LOG.debug('Only vitrage-api process exist') return True elif "vitrage-graph" in text_out2: - LOG.info('Only vitrage-graph process exist') + LOG.debug('Only vitrage-graph process exist') return True else: - LOG.info('The vitrage process does not run') + LOG.debug('The vitrage process does not run') return False - @staticmethod - def _get_field_from_file(pattern, lines_arr): - p = re.compile(pattern) - for line in lines_arr: - m = p.search(line) - if m: - print("The field value is " + m.group(1)) - return m.group(1) - return None - - def _set_env_params(self): - lines_arr = [] - with open(self.filename, 'r') as the_file: - for line in the_file: - if "#" not in line and line.strip() != '': - lines_arr.append(line) - - self.user = self._get_field_from_file( - "admin_user = (\w+)", lines_arr) - text_out = os.popen("echo $OS_USERNAME").read() - if text_out not in self.user: - os.system("export OS_USERNAME=" + self.user) - - self.tenent_user = self._get_field_from_file( - "admin_tenant_name = (\w+)", lines_arr) - text_out = os.popen("echo $OS_TENANT_NAME").read() - if text_out not in self.tenent_user: - os.system("export OS_TENANT_NAME=" + self.tenent_user) - - self.password = self._get_field_from_file( - "admin_password = (\w+)", lines_arr) - text_out = os.popen("echo $OS_PASSWORD").read() - if text_out not in self.password: - os.system("export OS_PASSWORD=" + self.password) - - self.host = self._get_field_from_file( - "(\d+\.\d+\.\d+\.\d+)", lines_arr) + def _get_env_params(self): + conf = utils.get_conf() + self.port = conf.api.port + self.user = conf.keystone_authtoken.admin_user + self.tenant_user = conf.keystone_authtoken.admin_tenant_name + self.password = conf.keystone_authtoken.admin_password + self.identity_uri = conf.keystone_authtoken.identity_uri + self.host = utils.get_regex_result( + "(\d+\.\d+\.\d+\.\d+)", self.identity_uri) self.url = "http://" + self.host + ":5000/v2.0" - text_out = os.popen("echo $OS_AUTH_URL").read() - if text_out not in self.url: - os.system("export OS_AUTH_URL=" + self.url) @staticmethod def _stop_vitrage_processes(): - text_out = os.popen("pgrep vitrage-api").read() - print (text_out) + text_out = utils.get_from_terminal("pgrep vitrage-api") if text_out != '': - LOG.info("The vitrage-api process exist") - os.system("kill -9 " + text_out) + LOG.debug("The vitrage-api process exist") + utils.run_from_terminal("kill -9 " + text_out) - text_out2 = os.popen("pgrep vitrage-graph").read() - print (text_out2) + text_out2 = utils.get_from_terminal("pgrep vitrage-graph") if text_out2 != '': - LOG.info("The vitrage-graph process exist") - os.system("kill -9 " + text_out2) + LOG.debug("The vitrage-graph process exist") + utils.run_from_terminal("kill -9 " + text_out2) @staticmethod def _validate_vitrage_processes(): - text_out2 = os.popen("grep 'ERROR vitrage' nohup.out").read() - if text_out2 != '': - LOG.info("The error is : " + text_out2) - print("The error is : " + text_out2) + errors_out = utils.get_from_terminal( + "grep ERROR /tmp/nohup-graph.out | " + + "grep ERROR /tmp/nohup-api.out | grep -v \'ERROR %\'") + if errors_out != '': + LOG.error("The errors are : " + errors_out) return False return True diff --git a/vitrage_tempest_tests/tests/stop_vitrage_env.py b/vitrage_tempest_tests/tests/stop_vitrage_env.py index 2391115f3..d1bece74a 100644 --- a/vitrage_tempest_tests/tests/stop_vitrage_env.py +++ b/vitrage_tempest_tests/tests/stop_vitrage_env.py @@ -11,34 +11,33 @@ # 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 oslo_config import cfg from oslo_log import log as logging -import os -import subprocess +import vitrage_tempest_tests.tests.utils as utils + import testtools LOG = logging.getLogger(__name__) +CONF = cfg.CONF +logging.register_options(CONF) +logging.setup(CONF, "vitrage") +logging.set_defaults(default_log_levels=utils.extra_log_level_defaults) class StopVitrageEnv(testtools.TestCase): - """RunVitrageEnv class. Run Vitrage env.""" + """StopVitrageEnv class. Stop Vitrage env.""" def __init__(self, *args, **kwds): super(StopVitrageEnv, self).__init__(*args, **kwds) - self.filename = '/etc/vitrage/vitrage.conf' @staticmethod def test_stop_vitrage_processes(): - f = subprocess.Popen("pgrep vitrage-api", - stdout=subprocess.PIPE, shell=True) - text_out, std_error = f.communicate() - print (text_out) + LOG.debug("Stop vitrage processes") + text_out = utils.get_from_terminal("pgrep vitrage-api") if text_out != '': - os.system("kill -9 " + text_out) + utils.run_from_terminal("kill -9 " + text_out) - f = subprocess.Popen("pgrep vitrage-graph", - stdout=subprocess.PIPE, shell=True) - text_out, std_error2 = f.communicate() - print (text_out) - if text_out != '': - os.system("kill -9 " + text_out) + text_out2 = utils.get_from_terminal("pgrep vitrage-graph") + if text_out2 != '': + utils.run_from_terminal("kill -9 " + text_out2) diff --git a/vitrage_tempest_tests/tests/utils.py b/vitrage_tempest_tests/tests/utils.py new file mode 100644 index 000000000..b24e5ee29 --- /dev/null +++ b/vitrage_tempest_tests/tests/utils.py @@ -0,0 +1,99 @@ +# Copyright 2016 Nokia +# +# 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 oslo_config import cfg +from oslo_log import log as logging +from vitrage import service + +import os +import oslo_messaging +import re +import vitrage_tempest_tests.tests + +extra_log_level_defaults = [ + 'vitrage_tempest_tests.tests.utils=INFO', + 'vitrage_tempest_tests.tests.run_vitrage_env=INFO', + 'vitrage_tempest_tests.tests.stop_vitrage_env=INFO', + 'vitrage_tempest_tests.tests.api.topology.topology=INFO', + 'vitrage.api.controllers.v1.topology=WARN', + 'oslo_messaging._drivers.amqpdriver=WARN' +] + +LOG = logging.getLogger(__name__) +CONF = cfg.CONF +logging.register_options(CONF) +logging.setup(CONF, "vitrage") +logging.set_defaults(default_log_levels=extra_log_level_defaults) + + +def opts(): + return [ + ('keystone_authtoken', vitrage_tempest_tests.tests.OPTS) + ] + + +def get_from_terminal(command): + proc = os.popen(command) + text_out = proc.read() + proc.close() + LOG.debug("The command is : " + command) + if text_out != '': + LOG.debug("The command output is : \n" + text_out) + return text_out + + +def run_from_terminal(command): + proc = os.popen(command) + text_out = proc.read() + proc.close() + LOG.debug("The command is : " + command) + if text_out != '': + LOG.debug("The command output is : \n" + text_out) + + +def change_terminal_dir(path): + os.chdir(path) + LOG.debug("The path is : " + path) + + +def get_conf(): + conf = service.prepare_service([]) + for group, options in opts(): + conf.register_opts(list(options), group=group) + return conf + + +def get_client(): + transport = oslo_messaging.get_transport(cfg.CONF) + cfg.CONF.set_override('rpc_backend', 'rabbit') + target = oslo_messaging.Target(topic='rpcapiv1') + return oslo_messaging.RPCClient(transport, target) + + +def get_regex_from_array(pattern, lines_arr): + p = re.compile(pattern) + for line in lines_arr: + m = p.search(line) + if m: + LOG.debug("The field value is " + m.group(1)) + return m.group(1) + return None + + +def get_regex_result(pattern, text): + p = re.compile(pattern) + m = p.search(text) + if m: + LOG.debug("The regex value is " + m.group(1)) + return m.group(1) + return None