blob: 3b1b10719f04bf2f946a9866665ddefac2b854d9 [file] [log] [blame]
Jay Pipes051075a2012-04-28 17:39:37 -04001# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
3# Copyright 2012 OpenStack, LLC
4# All Rights Reserved.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17
Jay Pipes051075a2012-04-28 17:39:37 -040018import os
Jay Pipes051075a2012-04-28 17:39:37 -040019import shlex
20import subprocess
Matthew Treinisha83a16e2012-12-07 13:44:02 -050021import sys
Jay Pipes051075a2012-04-28 17:39:37 -040022
Jay Pipes051075a2012-04-28 17:39:37 -040023from sqlalchemy import create_engine, MetaData
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040024
Jay Pipes051075a2012-04-28 17:39:37 -040025from tempest.common.ssh import Client
Matthew Treinisha83a16e2012-12-07 13:44:02 -050026from tempest.common.utils.data_utils import rand_name
Jay Pipes051075a2012-04-28 17:39:37 -040027from tempest import exceptions
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040028from tempest.openstack.common import log as logging
Attila Fazekasd6d86292013-07-02 16:15:01 +020029from tempest.scenario import manager
Jay Pipes051075a2012-04-28 17:39:37 -040030
31LOG = logging.getLogger(__name__)
32
33
34class WhiteboxTest(object):
35
36 """
37 Base test case class mixin for "whitebox tests"
38
39 Whitebox tests are tests that have the following characteristics:
40
41 * Test common and advanced operations against a set of servers
42 * Use a client that it is possible to send random or bad data with
43 * SSH into either a host or a guest in order to validate server state
44 * May execute SQL queries directly against internal databases to verify
45 the state of data records
46 """
47 pass
48
49
Attila Fazekasd6d86292013-07-02 16:15:01 +020050class ComputeWhiteboxTest(manager.OfficialClientTest):
Jay Pipes051075a2012-04-28 17:39:37 -040051
52 """
53 Base smoke test case class for OpenStack Compute API (Nova)
54 """
55
56 @classmethod
57 def setUpClass(cls):
Sean Dague2203a1f2013-05-14 11:50:46 -040058 super(ComputeWhiteboxTest, cls).setUpClass()
59 if not cls.config.whitebox.whitebox_enabled:
Jay Pipes051075a2012-04-28 17:39:37 -040060 msg = "Whitebox testing disabled"
ivan-zhu1feeb382013-01-24 10:14:39 +080061 raise cls.skipException(msg)
Jay Pipes051075a2012-04-28 17:39:37 -040062
Jay Pipes051075a2012-04-28 17:39:37 -040063 # Add some convenience attributes that tests use...
Attila Fazekas3ca1fb32013-01-21 23:10:53 +010064 cls.nova_dir = cls.config.whitebox.source_dir
65 cls.compute_bin_dir = cls.config.whitebox.bin_dir
66 cls.compute_config_path = cls.config.whitebox.config_path
Jay Pipes051075a2012-04-28 17:39:37 -040067 cls.build_interval = cls.config.compute.build_interval
68 cls.build_timeout = cls.config.compute.build_timeout
69 cls.ssh_user = cls.config.compute.ssh_user
70 cls.image_ref = cls.config.compute.image_ref
71 cls.image_ref_alt = cls.config.compute.image_ref_alt
72 cls.flavor_ref = cls.config.compute.flavor_ref
73 cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
Jay Pipes051075a2012-04-28 17:39:37 -040074
Attila Fazekasc3a095b2013-08-17 09:15:44 +020075 # NOTE(afazekas): Mimics the helper method used in the api tests
Jay Pipes051075a2012-04-28 17:39:37 -040076 @classmethod
Attila Fazekasd6d86292013-07-02 16:15:01 +020077 def create_server(cls, **kwargs):
78 flavor_ref = cls.config.compute.flavor_ref
79 image_ref = cls.config.compute.image_ref
80 name = rand_name(cls.__name__ + "-instance")
81 if 'name' in kwargs:
82 name = kwargs.pop('name')
83 flavor = kwargs.get('flavor', flavor_ref)
84 image_id = kwargs.get('image_id', image_ref)
Jay Pipes051075a2012-04-28 17:39:37 -040085
Attila Fazekasd6d86292013-07-02 16:15:01 +020086 server = cls.compute_client.servers.create(
87 name, image_id, flavor, **kwargs)
Jay Pipes051075a2012-04-28 17:39:37 -040088
Attila Fazekasd6d86292013-07-02 16:15:01 +020089 if 'wait_until' in kwargs:
90 cls.status_timeout(cls.compute_client.servers, server.id,
91 server['id'], kwargs['wait_until'])
92
93 server = cls.compute_client.servers.get(server.id)
94 cls.set_resource(name, server)
Jay Pipes051075a2012-04-28 17:39:37 -040095 return server
96
97 @classmethod
98 def get_db_handle_and_meta(cls, database='nova'):
Sean Daguef237ccb2013-01-04 15:19:14 -050099 """Return a connection handle and metadata of an OpenStack database."""
Jay Pipes051075a2012-04-28 17:39:37 -0400100 engine_args = {"echo": False,
101 "convert_unicode": True,
102 "pool_recycle": 3600
103 }
104
105 try:
Attila Fazekas3ca1fb32013-01-21 23:10:53 +0100106 engine = create_engine(cls.config.whitebox.db_uri, **engine_args)
Jay Pipes051075a2012-04-28 17:39:37 -0400107 connection = engine.connect()
108 meta = MetaData()
109 meta.reflect(bind=engine)
110
Dirk Mueller1db5db22013-06-23 20:21:32 +0200111 except Exception as e:
Jay Pipes051075a2012-04-28 17:39:37 -0400112 raise exceptions.SQLException(message=e)
113
114 return connection, meta
115
116 def nova_manage(self, category, action, params):
Sean Daguef237ccb2013-01-04 15:19:14 -0500117 """Executes nova-manage command for the given action."""
Jay Pipes051075a2012-04-28 17:39:37 -0400118
119 nova_manage_path = os.path.join(self.compute_bin_dir, 'nova-manage')
120 cmd = ' '.join([nova_manage_path, category, action, params])
121
122 if self.deploy_mode == 'devstack-local':
123 if not os.path.isdir(self.nova_dir):
124 sys.exit("Cannot find Nova source directory: %s" %
125 self.nova_dir)
126
127 cmd = shlex.split(cmd)
128 result = subprocess.Popen(cmd, stdout=subprocess.PIPE)
129
Attila Fazekasc3a095b2013-08-17 09:15:44 +0200130 # TODO(rohitk): Need to define host connection parameters in config
Jay Pipes051075a2012-04-28 17:39:37 -0400131 else:
132 client = self.get_ssh_connection(self.config.whitebox.api_host,
Zhongyue Luo79d8d362012-09-25 13:49:27 +0800133 self.config.whitebox.api_user,
134 self.config.whitebox.api_passwd)
Jay Pipes051075a2012-04-28 17:39:37 -0400135 result = client.exec_command(cmd)
136
137 return result
138
139 def get_ssh_connection(self, host, username, password):
Sean Daguef237ccb2013-01-04 15:19:14 -0500140 """Create an SSH connection object to a host."""
Jay Pipes051075a2012-04-28 17:39:37 -0400141 ssh_timeout = self.config.compute.ssh_timeout
142 ssh_client = Client(host, username, password, ssh_timeout)
143 if not ssh_client.test_connection_auth():
144 raise exceptions.SSHTimeout()
145 else:
146 return ssh_client