From fc4225fc99bfb55d3391eec0517607f45848258d Mon Sep 17 00:00:00 2001 From: "marina.koushnir@nokia.com" Date: Wed, 30 Mar 2016 11:12:39 +0000 Subject: [PATCH] fix runners & new topology tests Change-Id: Iad6349480024ba321bb2df6b6ffab901542c8ab8 --- vitrage_tempest_tests/tests/api/base.py | 84 +++++++++++ .../tests/api/topology/topology.py | 100 +++---------- .../tests/api/topology/topology_helper.py | 134 ++++++++++++++++++ .../tests/run_vitrage_env.py | 37 +++-- .../tests/stop_vitrage_env.py | 8 +- vitrage_tempest_tests/tests/utils.py | 16 +++ 6 files changed, 275 insertions(+), 104 deletions(-) create mode 100644 vitrage_tempest_tests/tests/api/topology/topology_helper.py diff --git a/vitrage_tempest_tests/tests/api/base.py b/vitrage_tempest_tests/tests/api/base.py index ca629c697..fc3f203f2 100644 --- a/vitrage_tempest_tests/tests/api/base.py +++ b/vitrage_tempest_tests/tests/api/base.py @@ -15,6 +15,8 @@ from oslo_log import log as logging from vitrage.tests.base import BaseTest from vitrage_tempest_tests.tests.base_mock import BaseMock +import vitrage_tempest_tests.tests.utils as utils + LOG = logging.getLogger(__name__) @@ -30,3 +32,85 @@ class BaseVitrageTest(BaseTest, BaseMock): entity_graph = processor.entity_graph mock_graph_output = entity_graph.output_graph() LOG.info("The mock graph is : " + mock_graph_output) + + @staticmethod + def get_flavor_id_from_list(): + text_out = utils.run_vitrage_command("nova flavor-list") + try: + flavor_id = utils.get_regex_result("\|\s+(\d+)\s+\|", + text_out.splitlines()[3]) + except Exception as e: + LOG.exception("Failed to get flavor id from the list %s ", e) + return None + + LOG.debug("The flavor id from the list is " + flavor_id) + return flavor_id + + @staticmethod + def get_image_id_from_list(): + text_out = utils.run_vitrage_command("glance image-list") + try: + image_id = utils.get_regex_result("\|\s+(.*)\s+\|", + text_out.splitlines()[3]) + image_id = image_id.split(" ")[0] + except Exception as e: + LOG.exception("Failed to get image id from the list %s ", e) + return None + + LOG.debug("The image id from the list is " + image_id) + return image_id + + @staticmethod + def get_instance_id_by_name(vm_name): + text_out = utils.run_vitrage_command("nova list") + for line in text_out.splitlines(): + if vm_name in line: + vm_id = utils.get_regex_result("\|\s+(.*)\s+\|", line) + vm_id = vm_id.split(" ")[0] + LOG.debug("The instance id from the nova list is " + vm_id) + return vm_id + return None + + @staticmethod + def get_volume_id_by_name(vol_name): + text_out = utils.run_vitrage_command("cinder list") + for line in text_out.splitlines(): + if vol_name in line: + vol_id = utils.get_regex_result("\|\s+(.*)\s+\|", line) + vol_id = vol_id.split(" ")[0] + LOG.debug("The volume id from the cinder list is " + vol_id) + return vol_id + return None + + @staticmethod + def create_vm_with_exist_image(vm_name, flavor_id, image_id): + utils.run_vitrage_command("nova boot " + vm_name + " --flavor " + + flavor_id + " --image " + image_id) + + text_out = utils.run_vitrage_command("nova list") + if vm_name in text_out: + LOG.debug("The expected vm exist in the nova list") + else: + LOG.error("The expected vm not exist in the nova list") + + @staticmethod + def create_volume_with_exist_size(vol_name): + utils.run_vitrage_command("cinder create --name " + vol_name + " 5") + + text_out = utils.run_vitrage_command("cinder list") + if vol_name in text_out: + LOG.debug("The expected volume exist in the cinder list") + else: + LOG.error("The expected volume not exist in the cinder list") + + def attach_volume(self, vm_name, vol_name): + vm_id = self.get_instance_id_by_name(vm_name) + vol_id = self.get_volume_id_by_name(vol_name) + + utils.run_vitrage_command("nova volume-attach " + vm_id + " " + vol_id) + + text_out = utils.run_vitrage_command("cinder list") + if vm_id in text_out: + LOG.debug("The expected volume attached to vm") + else: + LOG.error("The expected volume did not attached to vm") diff --git a/vitrage_tempest_tests/tests/api/topology/topology.py b/vitrage_tempest_tests/tests/api/topology/topology.py index fb5e1d3c9..5879bfd61 100644 --- a/vitrage_tempest_tests/tests/api/topology/topology.py +++ b/vitrage_tempest_tests/tests/api/topology/topology.py @@ -11,16 +11,10 @@ # 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 json -import subprocess -import vitrage_tempest_tests.tests.utils as utils - 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.api.topology.topology_helper \ + import TopologyHelper LOG = logging.getLogger(__name__) @@ -30,83 +24,35 @@ class BaseTopologyTest(BaseVitrageTest): def __init__(self, *args, **kwds): super(BaseTopologyTest, self).__init__(*args, **kwds) - self.created_graphs = [] self.name = 'tempest_graph' - self.depth = '' - self.query = '' - self.root = '' - self._get_env_params() - self.client = utils.get_client() + self.topology_client = TopologyHelper() - def test_get_tree(self): - """Wrapper that returns a test tree.""" - self._get_topology('tree') - - def test_get_graph(self): + def test_compare_graphs(self): """Wrapper that returns a test graph.""" - self._get_topology('graph') + api_graph = self.topology_client.get_api_topology('graph') + cli_graph = self.topology_client.show_cli_topology() - if self._validate_graph_correctness() is False: + if self.topology_client.compare_graphs(api_graph, cli_graph) is False: LOG.error('The graph ' + self.name + ' is not correct') else: LOG.info('The graph ' + self.name + ' is correct') - def _get_topology(self, graph_type): - """Get Graph objects returned by the v1 client """ - try: - g = TopologyController().get_graph(graph_type=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) - return None + def test_get_tree_with_vms(self): + """Wrapper that returns a test tree with created vm's""" + resources = self.topology_client.create_machines(4) + cli_graph = self.topology_client.show_cli_topology() - return g + if self.validate_graph_correctness(cli_graph, resources) is False: + LOG.error('The graph ' + self.name + ' is not correct') + else: + LOG.info('The graph ' + self.name + ' is correct') - def _validate_graph_correctness(self): - """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 + def test_get_graph_with_volume(self): + """Wrapper that returns a test graph.""" + resources = self.topology_client.create_volume() + cli_graph = self.topology_client.show_cli_topology() - 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 + if self.validate_graph_correctness(cli_graph, resources) is False: + LOG.error('The graph ' + self.name + ' is not correct') + else: + LOG.info('The graph ' + self.name + ' is correct') diff --git a/vitrage_tempest_tests/tests/api/topology/topology_helper.py b/vitrage_tempest_tests/tests/api/topology/topology_helper.py new file mode 100644 index 000000000..714ebc118 --- /dev/null +++ b/vitrage_tempest_tests/tests/api/topology/topology_helper.py @@ -0,0 +1,134 @@ +# 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. +import json +import vitrage_tempest_tests.tests.utils as utils + +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 + +LOG = logging.getLogger(__name__) + + +class TopologyHelper(BaseVitrageTest): + """Topology test class for Vitrage API tests.""" + + def __init__(self, *args, **kwds): + super(TopologyHelper, self).__init__(*args, **kwds) + self.depth = '' + self.query = '' + self.root = '' + self._get_env_params() + self.client = utils.get_client() + + def get_api_topology(self, graph_type): + """Get Graph objects returned by the v1 client """ + try: + api_graph = TopologyController().get_graph(graph_type=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) + return None + + return api_graph + + def _get_env_params(self): + conf = utils.get_conf() + self.user = conf.service_credentials.user + + def show_cli_topology(self): + """Get Graph objects returned by cli """ + LOG.debug("The command is : vitrage topology show") + return utils.run_vitrage_command( + "cd /home/stack/devstack; . openrc " + + self.user + " " + self.user + + "; vitrage topology show") + + def create_machines(self, machine_number): + flavor_id = self.get_flavor_id_from_list() + image_id = self.get_image_id_from_list() + + resources = [] + for r in range(start=0, stop=machine_number, step=1): + self.create_vm_with_exist_image("vm_for_test_" + str(r), + flavor_id, image_id) + resources.append("vm_for_test_" + str(r)) + + return resources + + def create_volume(self): + flavor_id = self.get_flavor_id_from_list() + image_id = self.get_image_id_from_list() + + resources = ["vm_for_vol", "vol_for_vm"] + self.create_vm_with_exist_image(resources[0], flavor_id, image_id) + self.create_volume_with_exist_size(resources[1]) + self.attach_volume(resources[0], resources[1]) + return resources + + @staticmethod + def compare_graphs(api_graph, cli_graph): + """Compare Graph object to graph form terminal """ + if not api_graph: + LOG.error("The topology graph taken from rest api is empty") + return False + if not cli_graph: + LOG.error("The topology graph taken from terminal is empty") + return False + + 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(api_graph)) + + cli_items = sorted(parsed_topology.items()) + api_items = sorted(api_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 + + @staticmethod + def validate_graph_correctness(cli_graph, resources): + """Compare Graph object to graph form terminal """ + if not cli_graph: + LOG.error("The topology graph taken from terminal is empty") + return False + if not resources: + LOG.error("The resources list is empty") + return False + + parsed_topology = json.loads(cli_graph) + LOG.debug("The topology graph taken from terminal is : " + + json.dumps(parsed_topology)) + cli_items = sorted(parsed_topology.items()) + + for resource_name in resources: + for item in cli_items[4][1]: + item.pop(VProps.UPDATE_TIMESTAMP, None) + if resource_name not in cli_items[4][1]: + LOG.error("The resources " + resource_name + + "doesn't exist in the topology graph") + return False + return True diff --git a/vitrage_tempest_tests/tests/run_vitrage_env.py b/vitrage_tempest_tests/tests/run_vitrage_env.py index 88ec3195a..7af6b6d9f 100644 --- a/vitrage_tempest_tests/tests/run_vitrage_env.py +++ b/vitrage_tempest_tests/tests/run_vitrage_env.py @@ -11,11 +11,9 @@ # 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 -# noinspection PyPackageRequirements import testtools import vitrage_tempest_tests.tests.utils as utils @@ -41,21 +39,21 @@ class RunVitrageEnv(testtools.TestCase): self._get_env_params() 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("chmod +x openrc") + utils.get_from_terminal_enabled_bash(". openrc " + self.user + " " + + self.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" + + # " --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" + + # " --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 + @@ -101,13 +99,12 @@ class RunVitrageEnv(testtools.TestCase): 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.user = conf.service_credentials.user + self.password = conf.service_credentials.password + self.url = conf.service_credentials.auth_url + "/v2.0" self.host = utils.get_regex_result( - "(\d+\.\d+\.\d+\.\d+)", self.identity_uri) - self.url = "http://" + self.host + ":5000/v2.0" + "(\d+\.\d+\.\d+\.\d+)", self.url) + self.identity_uri = conf.keystone_authtoken.identity_uri @staticmethod def _stop_vitrage_processes(): diff --git a/vitrage_tempest_tests/tests/stop_vitrage_env.py b/vitrage_tempest_tests/tests/stop_vitrage_env.py index 0c6be0911..65fdac780 100644 --- a/vitrage_tempest_tests/tests/stop_vitrage_env.py +++ b/vitrage_tempest_tests/tests/stop_vitrage_env.py @@ -35,10 +35,4 @@ class StopVitrageEnv(testtools.TestCase): @staticmethod def test_stop_vitrage_processes(): LOG.debug("Stop vitrage processes") - text_out = utils.get_from_terminal("pgrep vitrage-api") - if text_out != '': - utils.run_from_terminal("kill -9 " + text_out) - - text_out2 = utils.get_from_terminal("pgrep vitrage-graph") - if text_out2 != '': - utils.run_from_terminal("kill -9 " + text_out2) + utils.run_from_terminal("pkill vitrage") diff --git a/vitrage_tempest_tests/tests/utils.py b/vitrage_tempest_tests/tests/utils.py index b24e5ee29..a2ef67420 100644 --- a/vitrage_tempest_tests/tests/utils.py +++ b/vitrage_tempest_tests/tests/utils.py @@ -18,6 +18,7 @@ from vitrage import service import os import oslo_messaging import re +import subprocess import vitrage_tempest_tests.tests extra_log_level_defaults = [ @@ -52,6 +53,21 @@ def get_from_terminal(command): return text_out +def run_vitrage_command(command): + p = subprocess.Popen(command, + 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 run_from_terminal(command): proc = os.popen(command) text_out = proc.read()