tempest/tempest/whitebox/manager.py

146 lines
5.2 KiB
Python

# 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