# vim: tabstop=4 shiftwidth=4 softtabstop=4 # Copyright 2012 OpenStack, LLC # 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 os import shlex import subprocess import sys from sqlalchemy import create_engine, MetaData from tempest.common import log as logging from tempest.common.ssh import Client from tempest.common.utils.data_utils import rand_name from tempest import exceptions from tempest.scenario import manager LOG = logging.getLogger(__name__) class WhiteboxTest(object): """ Base test case class mixin for "whitebox tests" Whitebox tests are tests that have the following characteristics: * Test common and advanced operations against a set of servers * Use a client that it is possible to send random or bad data with * SSH into either a host or a guest in order to validate server state * May execute SQL queries directly against internal databases to verify the state of data records """ pass class ComputeWhiteboxTest(manager.OfficialClientTest): """ Base smoke test case class for OpenStack Compute API (Nova) """ @classmethod def setUpClass(cls): super(ComputeWhiteboxTest, cls).setUpClass() if not cls.config.whitebox.whitebox_enabled: msg = "Whitebox testing disabled" raise cls.skipException(msg) # Add some convenience attributes that tests use... cls.nova_dir = cls.config.whitebox.source_dir cls.compute_bin_dir = cls.config.whitebox.bin_dir cls.compute_config_path = cls.config.whitebox.config_path cls.build_interval = cls.config.compute.build_interval cls.build_timeout = cls.config.compute.build_timeout cls.ssh_user = cls.config.compute.ssh_user cls.image_ref = cls.config.compute.image_ref cls.image_ref_alt = cls.config.compute.image_ref_alt cls.flavor_ref = cls.config.compute.flavor_ref cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt #NOTE(afazekas): Mimics the helper method used in the api tests @classmethod def create_server(cls, **kwargs): flavor_ref = cls.config.compute.flavor_ref image_ref = cls.config.compute.image_ref name = rand_name(cls.__name__ + "-instance") if 'name' in kwargs: name = kwargs.pop('name') flavor = kwargs.get('flavor', flavor_ref) image_id = kwargs.get('image_id', image_ref) server = cls.compute_client.servers.create( name, image_id, flavor, **kwargs) if 'wait_until' in kwargs: cls.status_timeout(cls.compute_client.servers, server.id, server['id'], kwargs['wait_until']) server = cls.compute_client.servers.get(server.id) cls.set_resource(name, server) return server @classmethod def get_db_handle_and_meta(cls, database='nova'): """Return a connection handle and metadata of an OpenStack database.""" engine_args = {"echo": False, "convert_unicode": True, "pool_recycle": 3600 } try: engine = create_engine(cls.config.whitebox.db_uri, **engine_args) connection = engine.connect() meta = MetaData() meta.reflect(bind=engine) except Exception as e: raise exceptions.SQLException(message=e) return connection, meta def nova_manage(self, category, action, params): """Executes nova-manage command for the given action.""" nova_manage_path = os.path.join(self.compute_bin_dir, 'nova-manage') cmd = ' '.join([nova_manage_path, category, action, params]) if self.deploy_mode == 'devstack-local': if not os.path.isdir(self.nova_dir): sys.exit("Cannot find Nova source directory: %s" % self.nova_dir) cmd = shlex.split(cmd) result = subprocess.Popen(cmd, stdout=subprocess.PIPE) #Todo(rohitk): Need to define host connection parameters in config else: client = self.get_ssh_connection(self.config.whitebox.api_host, self.config.whitebox.api_user, self.config.whitebox.api_passwd) result = client.exec_command(cmd) return result def get_ssh_connection(self, host, username, password): """Create an SSH connection object to a host.""" ssh_timeout = self.config.compute.ssh_timeout ssh_client = Client(host, username, password, ssh_timeout) if not ssh_client.test_connection_auth(): raise exceptions.SSHTimeout() else: return ssh_client