Add functional tests for runtime
Change-Id: Ie1c77a86f7682a50d8b85b4ca19be6f1f38c431b
This commit is contained in:
parent
ac9d477112
commit
be7a929743
@ -2,6 +2,7 @@
|
||||
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
|
||||
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
|
||||
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ . $LISTOPT $IDOPTION
|
||||
OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \
|
||||
${PYTHON:-python} -m subunit.run discover -t ./ ./qinling/tests $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
||||
|
@ -19,6 +19,13 @@ function install_qinlingclient {
|
||||
}
|
||||
|
||||
|
||||
function install_k8s {
|
||||
pushd $QINLING_DIR
|
||||
source tools/gate/setup_gate.sh
|
||||
popd
|
||||
}
|
||||
|
||||
|
||||
function create_qinling_accounts {
|
||||
create_service_user "qinling" "admin"
|
||||
|
||||
@ -60,6 +67,7 @@ function configure_qinling {
|
||||
iniset $QINLING_CONF_FILE DEFAULT debug $QINLING_DEBUG
|
||||
iniset $QINLING_CONF_FILE DEFAULT server all
|
||||
iniset $QINLING_CONF_FILE storage file_system_dir $QINLING_FUNCTION_STORAGE_DIR
|
||||
iniset $QINLING_CONF_FILE kubernetes qinling_service_address $DEFAULT_HOST_IP
|
||||
|
||||
# Setup keystone_authtoken section
|
||||
configure_auth_token_middleware $QINLING_CONF_FILE qinling $QINLING_AUTH_CACHE_DIR
|
||||
@ -116,6 +124,10 @@ if is_service_enabled qinling; then
|
||||
if is_service_enabled key; then
|
||||
create_qinling_accounts
|
||||
fi
|
||||
|
||||
echo_summary "Installing kubernetes cluster"
|
||||
install_k8s
|
||||
|
||||
configure_qinling
|
||||
|
||||
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
|
||||
|
@ -13,5 +13,34 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
if __name__ == '__main__':
|
||||
pass
|
||||
from oslo_config import cfg
|
||||
|
||||
service_option = cfg.BoolOpt(
|
||||
'qinling',
|
||||
default=True,
|
||||
help="Whether or not Qinling is expected to be"
|
||||
"available"
|
||||
)
|
||||
|
||||
|
||||
qingling_group = cfg.OptGroup(name="qingling", title="Qinling Service Options")
|
||||
|
||||
QinlingGroup = [
|
||||
cfg.StrOpt("region",
|
||||
default="",
|
||||
help="The region name to use. If empty, the value "
|
||||
"of identity.region is used instead. If no such region "
|
||||
"is found in the service catalog, the first found one is "
|
||||
"used."),
|
||||
cfg.StrOpt("catalog_type",
|
||||
default="function",
|
||||
help="Catalog type of the Qinling service."),
|
||||
cfg.StrOpt('endpoint_type',
|
||||
default='publicURL',
|
||||
choices=['public', 'admin', 'internal',
|
||||
'publicURL', 'adminURL', 'internalURL'],
|
||||
help="The endpoint type to use for the qinling service."),
|
||||
cfg.StrOpt('kube_host',
|
||||
default='127.0.0.1:8001',
|
||||
help="The Kubernetes service address."),
|
||||
]
|
||||
|
@ -16,8 +16,11 @@
|
||||
|
||||
import os
|
||||
|
||||
from tempest import config
|
||||
from tempest.test_discover import plugins
|
||||
|
||||
from qinling_tempest_plugin import config as qinling_config
|
||||
|
||||
|
||||
class QinlingTempestPlugin(plugins.TempestPlugin):
|
||||
def load_tests(self):
|
||||
@ -29,7 +32,26 @@ class QinlingTempestPlugin(plugins.TempestPlugin):
|
||||
return full_test_dir, base_path
|
||||
|
||||
def register_opts(self, conf):
|
||||
pass
|
||||
conf.register_opt(
|
||||
qinling_config.service_option, group='service_available'
|
||||
)
|
||||
|
||||
conf.register_group(qinling_config.qingling_group)
|
||||
conf.register_opts(qinling_config.QinlingGroup, group='qinling')
|
||||
|
||||
def get_opt_lists(self):
|
||||
pass
|
||||
return [
|
||||
('service_available', [qinling_config.service_option]),
|
||||
(qinling_config.qingling_group.name, qinling_config.QinlingGroup)
|
||||
]
|
||||
|
||||
def get_service_clients(self):
|
||||
qinling_config = config.service_client_config('qinling')
|
||||
params = {
|
||||
'name': 'qinling',
|
||||
'service_version': 'qinling',
|
||||
'module_path': 'qinling_tempest_plugin.services.qinling_client',
|
||||
'client_names': ['QinlingClient'],
|
||||
}
|
||||
params.update(qinling_config)
|
||||
return [params]
|
||||
|
@ -14,15 +14,4 @@
|
||||
|
||||
# This script is executed inside pre_test_hook function in devstack gate.
|
||||
|
||||
set -ex
|
||||
|
||||
export localconf=$BASE/new/devstack/local.conf
|
||||
export QINLING_CONF=/etc/qinling/qinling.conf
|
||||
|
||||
# Install k8s cluster
|
||||
pushd $BASE/new/qinling/
|
||||
bash tools/gate/setup_gate.sh
|
||||
popd
|
||||
|
||||
echo -e "[[post-config|$QINLING_CONF]]\n[kubernetes]\n" >> $localconf
|
||||
echo -e "qinling_service_address=${DEFAULT_HOST_IP}\n" >> $localconf
|
||||
echo "Pass"
|
||||
|
44
qinling_tempest_plugin/services/base.py
Normal file
44
qinling_tempest_plugin/services/base.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright 2017 Catalyst IT Ltd
|
||||
#
|
||||
# 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
|
||||
|
||||
from tempest.lib.common import rest_client
|
||||
|
||||
|
||||
class QinlingClientBase(rest_client.RestClient):
|
||||
def __init__(self, auth_provider, **kwargs):
|
||||
super(QinlingClientBase, self).__init__(auth_provider, **kwargs)
|
||||
|
||||
self.runtimes = []
|
||||
|
||||
def get_list_objs(self, url_path):
|
||||
resp, body = self.get(url_path)
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def delete_obj(self, obj, id):
|
||||
return self.delete('{obj}/{id}'.format(obj=obj, id=id))
|
||||
|
||||
def get_obj(self, obj, id):
|
||||
resp, body = self.get('{obj}/{id}'.format(obj=obj, id=id))
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def post_json(self, url_path, obj, extra_headers={}):
|
||||
headers = {"Content-Type": "application/json"}
|
||||
headers = dict(headers, **extra_headers)
|
||||
resp, body = self.post(url_path, json.dumps(obj), headers=headers)
|
||||
|
||||
return resp, json.loads(body)
|
32
qinling_tempest_plugin/services/qinling_client.py
Normal file
32
qinling_tempest_plugin/services/qinling_client.py
Normal file
@ -0,0 +1,32 @@
|
||||
# Copyright 2017 Catalyst IT Ltd
|
||||
#
|
||||
# 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
|
||||
|
||||
from qinling_tempest_plugin.services import base as client_base
|
||||
|
||||
|
||||
class QinlingClient(client_base.QinlingClientBase):
|
||||
"""Tempest REST client for Qinling."""
|
||||
|
||||
def create_runtime(self, image, name=None):
|
||||
body = {"image": image}
|
||||
|
||||
if name:
|
||||
body.update({'name': name})
|
||||
|
||||
resp, body = self.post('runtimes', json.dumps(body))
|
||||
self.runtimes.append(json.loads(body)['id'])
|
||||
|
||||
return resp, json.loads(body)
|
55
qinling_tempest_plugin/tests/api/test_runtimes.py
Normal file
55
qinling_tempest_plugin/tests/api/test_runtimes.py
Normal file
@ -0,0 +1,55 @@
|
||||
# Copyright 2017 Catalyst IT Ltd
|
||||
#
|
||||
# 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.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
from qinling_tempest_plugin.tests import base
|
||||
|
||||
|
||||
class RuntimesTest(base.BaseQinlingTest):
|
||||
name_prefix = 'RuntimesTest'
|
||||
|
||||
@decorators.idempotent_id('fdc2f07f-dd1d-4981-86d3-5bc7908d9a9b')
|
||||
def test_create_delete_runtime(self):
|
||||
name = data_utils.rand_name('runtime', prefix=self.name_prefix)
|
||||
|
||||
req_body = {
|
||||
'name': name,
|
||||
'image': 'openstackqinling/python-runtime'
|
||||
}
|
||||
resp, body = self.qinling_client.post_json('runtimes', req_body)
|
||||
runtime_id = body['id']
|
||||
|
||||
self.assertEqual(201, resp.status)
|
||||
self.assertEqual(name, body['name'])
|
||||
|
||||
resp, body = self.qinling_client.get_list_objs('runtimes')
|
||||
|
||||
self.assertEqual(200, resp.status)
|
||||
self.assertIn(
|
||||
runtime_id,
|
||||
[runtime['id'] for runtime in body['runtimes']]
|
||||
)
|
||||
|
||||
deploy = self.k8s_v1extention.read_namespaced_deployment(
|
||||
runtime_id,
|
||||
namespace=self.namespace
|
||||
)
|
||||
|
||||
self.assertEqual(runtime_id, deploy.metadata.name)
|
||||
|
||||
resp, _ = self.qinling_client.delete_obj('runtimes', runtime_id)
|
||||
|
||||
self.assertEqual(204, resp.status)
|
52
qinling_tempest_plugin/tests/base.py
Normal file
52
qinling_tempest_plugin/tests/base.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright 2017 Catalyst IT Ltd
|
||||
#
|
||||
# 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 kubernetes import client as k8s_client
|
||||
from tempest import config
|
||||
from tempest import test
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class BaseQinlingTest(test.BaseTestCase):
|
||||
credentials = ('primary',)
|
||||
force_tenant_isolation = False
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(BaseQinlingTest, cls).skip_checks()
|
||||
|
||||
if not CONF.service_available.qinling:
|
||||
raise cls.skipException("Qinling service is not available.")
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(BaseQinlingTest, cls).setup_clients()
|
||||
|
||||
# os here is tempest.lib.services.clients.ServiceClients object
|
||||
os = getattr(cls, 'os_%s' % cls.credentials[0])
|
||||
cls.qinling_client = os.qinling.QinlingClient()
|
||||
|
||||
if CONF.identity.auth_version == 'v3':
|
||||
project_id = os.auth_provider.auth_data[1]['project']['id']
|
||||
else:
|
||||
project_id = os.auth_provider.auth_data[1]['token']['tenant']['id']
|
||||
cls.tenant_id = project_id
|
||||
cls.user_id = os.auth_provider.auth_data[1]['user']['id']
|
||||
|
||||
# Initilize k8s client
|
||||
k8s_client.Configuration().host = CONF.qinling.kube_host
|
||||
cls.k8s_v1 = k8s_client.CoreV1Api()
|
||||
cls.k8s_v1extention = k8s_client.ExtensionsV1beta1Api()
|
||||
cls.namespace = 'qinling'
|
@ -8,9 +8,11 @@ python-subunit>=0.0.18 # Apache-2.0/BSD
|
||||
sphinx>=1.6.2 # BSD
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
os-testr>=0.8.0 # Apache-2.0
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
testscenarios>=0.4 # Apache-2.0/BSD
|
||||
testtools>=1.4.0 # MIT
|
||||
tempest>=16.1.0 # Apache-2.0
|
||||
|
||||
# releasenotes
|
||||
reno!=2.3.1,>=1.8.0 # Apache-2.0
|
||||
|
Loading…
Reference in New Issue
Block a user