Adding base for integration tests

- Added sample tests for list/create/get clusters

Change-Id: If3b6af5c58579ec0e94d16570a626d3a05dddce9
This commit is contained in:
Steve Leon 2015-04-27 15:08:45 -07:00
parent 8a56568e97
commit b1646e5112
16 changed files with 329 additions and 1 deletions

View File

@ -4,6 +4,6 @@ test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \
OS_DEBUG=${OS_DEBUG:-1} \
OS_TEST_TIMEOUT=60 \
${PYTHON:-python} -m subunit.run discover . $LISTOPT $IDOPTION
${PYTHON:-python} -m subunit.run discover ./cue/tests $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

@ -17,3 +17,4 @@ sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
sphinxcontrib-pecanwsme>=0.8
oslosphinx>=2.2.0 # Apache-2.0
zake>=0.1.6
tempest-lib>=0.4.0

0
tests/__init__.py Normal file
View File

View File

@ -0,0 +1,4 @@
[DEFAULT]
test_command=python -m subunit.run discover ./api $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

View File

View File

View File

View File

@ -0,0 +1,83 @@
# Copyright 2014 OpenStack Foundation
# 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 json
import logging
import urllib
from tempest_lib.common import rest_client
from tests.integration.common.client import BaseMessageQueueClient
LOG = logging.getLogger(__name__)
class MessageQueueClustersClient(BaseMessageQueueClient):
"""This class is used for creating a Cue Cluster client.
It contains all the CRUD requests for Cue Clusters.
"""
def list_clusters(self, params=None):
"""List all clusters
:param params: Optional parameters for listing cluster
"""
url = 'clusters'
if params:
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
self.expected_success(200, resp.status)
return rest_client.ResponseBodyData(resp, body)
def get_cluster_details(self, cluster_id):
"""Get a cluster
:param cluster_id: The ID of the cluster to get
"""
resp, body = self.get("clusters/%s" % str(cluster_id))
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, self._parse_resp(body))
def create_cluster(self, name, flavor, network_id):
"""Create a new cluster with one node
:param name: The name of the cluster
:param flavor: The flavor of the cluster
:param network_id: The network_id to associate the cluster
"""
post_body = {
'name': name,
'size': 1,
"flavor": flavor,
'volume_size': 100,
"network_id": network_id,
}
post_body = post_body
post_body = json.dumps(post_body)
resp, body = self.post('clusters', post_body)
return rest_client.ResponseBody(resp, self._parse_resp(body))
def delete_cluster(self, cluster_id):
"""Delete a cluster
:param cluster_id: The ID of the cluster to delete
"""
resp, body = self.delete("clusters/%s" % str(cluster_id))
self.expected_success(202, resp.status)
return rest_client.ResponseBody(resp, body)

View File

@ -0,0 +1,63 @@
# Copyright 2014 OpenStack Foundation
# 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.
"""
Tests for the API /cluster/ controller methods.
"""
import logging
import tempest_lib.base
from tempest_lib.common.utils import data_utils
from tests.integration.api.v1.clients import clusters_client
from tests.integration.common import config
CONF = config.get_config()
LOG = logging.getLogger(__name__)
class ClusterTest(tempest_lib.base.BaseTestCase):
"""Cluster integration tests for Cue."""
@classmethod
def setUpClass(cls):
super(ClusterTest, cls).setUpClass()
cls.client = clusters_client.MessageQueueClustersClient()
def setUp(self):
super(ClusterTest, self).setUp()
self.cluster = self._create_cluster()
def tearDown(self):
super(ClusterTest, self).tearDown()
self.client.delete_cluster(self.cluster['id'])
def _create_cluster(self):
name = data_utils.rand_name(ClusterTest.__name__ + "-cluster")
network_id = [self.client.private_network['id']]
flavor = CONF.message_queue.flavor
return self.client.create_cluster(name, flavor, network_id)
def test_list_clusters(self):
clusters = self.client.list_clusters()
self.assertIn('id', clusters.data)
self.assertIn('status', clusters.data)
def test_get_cluster(self):
cluster_resp = self.client.get_cluster_details(self.cluster['id'])
self.assertEqual(self.cluster['id'], cluster_resp['id'])
self.assertEqual(self.cluster['name'], cluster_resp['name'])

View File

View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# 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 tempest.services.compute.json import tenant_networks_client
from tempest_lib import auth
from tempest_lib.common import rest_client
from tests.integration.common import config
CONF = config.get_config()
class BaseMessageQueueClient(rest_client.RestClient):
"""This class is used for building Cue api clients.
It extends the Openstack RestClient class, which provides a base layer for
wrapping outgoing http requests in keystone auth as well as providing
response code checking and error handling. It obtains the keystone
credentials from the configuration.
"""
def __init__(self):
auth_provider = self._get_keystone_auth_provider()
super(BaseMessageQueueClient, self).__init__(
auth_provider=auth_provider,
service='message_queue',
region='RegionOne',
)
self.private_network = self._get_network('private')
def _get_network(self, label):
network_client = tenant_networks_client.TenantNetworksClientJSON(
self._get_keystone_auth_provider(),
'compute',
'RegionOne')
networks = network_client.list_tenant_networks()
return [network for network in networks
if network['label'] == label][0]
def _get_keystone_auth_provider(self):
creds = auth.KeystoneV2Credentials(
username=CONF.identity.username,
password=CONF.identity.password,
tenant_name=CONF.identity.tenant_name,
)
auth_provider = auth.KeystoneV2AuthProvider(creds,
CONF.identity.uri)
auth_provider.fill_credentials()
return auth_provider

View File

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# 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
from oslo_config import cfg
TEST_CONF = None
def setup_config(config_file=''):
global TEST_CONF
TEST_CONF = cfg.ConfigOpts()
identity_group = cfg.OptGroup(name='identity')
identity_options = [
cfg.StrOpt('uri', default='http://localhost:5000/v2.0'),
cfg.StrOpt('username', default='demo'),
cfg.StrOpt('password', default='secret'),
cfg.StrOpt('tenant_name', default='demo'),
]
TEST_CONF.register_group(identity_group)
TEST_CONF.register_opts(identity_options, group=identity_group)
message_queue_group = cfg.OptGroup(name='message_queue')
message_queue_options = [
cfg.StrOpt('flavor', default='8795'),
]
TEST_CONF.register_group(message_queue_group)
TEST_CONF.register_opts(message_queue_options, group=message_queue_group)
# Figure out which config to load
config_to_load = []
local_config = 'cue-integration.conf'
if os.path.isfile(config_file):
config_to_load.append(config_file)
elif os.path.isfile(local_config):
config_to_load.append(local_config)
else:
config_to_load.append('/etc/cue/cue-integration.conf')
# Actually parse config
TEST_CONF(
(), # Required to load a anonymous config
default_config_files=config_to_load
)
def get_config():
if not TEST_CONF:
setup_config()
return TEST_CONF

View File

@ -0,0 +1,11 @@
[DEFAULT]
[identity]
# Replace these with values that represent your identity configuration
uri=http://localhost:5000/v2.0
username=demo
tenant_name=demo
password=password
[message_queue]
flavor=8795

39
tests/integration/run_tests.sh Executable file
View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
# Copyright 2015 Hewlett-Packard Development Company, L.P.
#
# 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.
# How many seconds to wait for the API to be responding before giving up
API_RESPONDING_TIMEOUT=20
if ! timeout ${API_RESPONDING_TIMEOUT} sh -c "while ! curl -s http://127.0.0.1:8795/ 2>/dev/null | grep -q 'v1' ; do sleep 1; done"; then
echo "The Cue API failed to respond within ${API_RESPONDING_TIMEOUT} seconds"
exit 1
fi
echo "Successfully contacted the Cue API"
# Where Cue and Tempest code lives
CUE_DIR=${CUE_DIR:-/opt/stack/cue}
TEMPEST_DIR=${TEMPEST_DIR:-/opt/stack/tempest}
# Install tempest
pip freeze | grep tempest 2>&1 1>/dev/null || pip install -e $TEMPEST_DIR
# run the tests in parallel
test -d .testrepository || testr init
testr run --parallel --subunit | subunit-trace --no-failure-debug -f
retval=$?
testr slowest
exit $retval