Add scenario test manager
This commit adds a scenario test manager and an example scenario test using it for cross-connectivity between pods and vms. Change-Id: I890f5b35847a7b874659c52b172a5af7da26a147
This commit is contained in:
parent
8883d324ba
commit
0a820212fe
|
@ -2,6 +2,9 @@
|
|||
Tempest Integration of Kuryr
|
||||
============================
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This project defines a tempest plugin containing tests used to verify the
|
||||
functionality of a kuryr installation. The plugin will automatically load
|
||||
these tests into tempest.
|
||||
|
|
|
@ -1 +1,9 @@
|
|||
.. include:: ../../README.rst
|
||||
|
||||
Scenario Tests
|
||||
==============
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
scenario_tests/scenario
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../../../kuryr_tempest_plugin/tests/scenario/README.rst
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
What are these tests?
|
||||
---------------------
|
||||
|
||||
As stated in the tempest developer guide, scenario tests are meant to be used to
|
||||
test the interaction between several OpenStack services to perform a real-life
|
||||
use case.
|
||||
|
||||
In the case of the Kuryr Tempest Plugin it also involves interaction with
|
||||
Kubernetes pods, so its manager class includes handlers to its python bindings.
|
||||
|
||||
A developer using this manager would be able to perform, among others, CRUD
|
||||
operations with pods, alongside Kuryr-K8s added funcionality.
|
|
@ -0,0 +1,122 @@
|
|||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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 time
|
||||
|
||||
from kubernetes import client as k8s_client
|
||||
from kubernetes import config as k8s_config
|
||||
|
||||
from tempest.scenario import manager
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest import config
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class BaseKuryrScenarioTest(manager.NetworkScenarioTest):
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(BaseKuryrScenarioTest, cls).skip_checks()
|
||||
if not CONF.service_available.kuryr:
|
||||
raise cls.skipException('Kuryr support is required')
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
super(BaseKuryrScenarioTest, cls).setup_clients()
|
||||
cls.k8s_client = k8s_client
|
||||
|
||||
@classmethod
|
||||
def resource_setup(cls):
|
||||
super(BaseKuryrScenarioTest, cls).resource_setup()
|
||||
cls.pod_fips = []
|
||||
# TODO (dmellado): Config k8s client in a cleaner way
|
||||
k8s_config.load_kube_config()
|
||||
|
||||
@classmethod
|
||||
def resource_cleanup(cls):
|
||||
super(BaseKuryrScenarioTest, cls).resource_cleanup()
|
||||
for fip in cls.pod_fips:
|
||||
cls.os_admin.floating_ips_client.delete_floatingip(
|
||||
fip['floatingip']['id'])
|
||||
|
||||
def create_pod(self, name=None, image='celebdor/kuryr-demo',
|
||||
namespace="default"):
|
||||
name = data_utils.rand_name(prefix='kuryr-pod')
|
||||
pod = self.k8s_client.V1Pod()
|
||||
pod.metadata = self.k8s_client.V1ObjectMeta(name=name)
|
||||
|
||||
container = self.k8s_client.V1Container()
|
||||
container.image = image
|
||||
container.args = ["sleep", "3600"]
|
||||
container.name = name
|
||||
|
||||
spec = self.k8s_client.V1PodSpec()
|
||||
spec.containers = [container]
|
||||
|
||||
pod.spec = spec
|
||||
self.k8s_client.CoreV1Api().create_namespaced_pod(namespace=namespace,
|
||||
body=pod)
|
||||
status = ""
|
||||
while status != "Running":
|
||||
# TODO (dmellado) add timeout config to tempest plugin
|
||||
time.sleep(1)
|
||||
status = self.get_pod_status(name, namespace)
|
||||
|
||||
return name, pod
|
||||
|
||||
def delete_pod(self, pod_name, body=None, namespace="default"):
|
||||
if body is None:
|
||||
body = {}
|
||||
self.k8s_client.CoreV1Api().delete_namespaced_pod(
|
||||
name=pod_name,
|
||||
body=body,
|
||||
namespace=namespace)
|
||||
|
||||
def get_pod_ip(self, pod_name, namespace="default"):
|
||||
pod_list = self.k8s_client.CoreV1Api().list_namespaced_pod(
|
||||
namespace=namespace)
|
||||
for pod in pod_list.items:
|
||||
if pod.metadata.name == pod_name:
|
||||
return pod.status.pod_ip
|
||||
|
||||
def get_pod_status(self, pod_name, namespace="default"):
|
||||
pod_list = self.k8s_client.CoreV1Api().list_namespaced_pod(
|
||||
namespace=namespace)
|
||||
for pod in pod_list.items:
|
||||
if pod.metadata.name == pod_name:
|
||||
return pod.status.phase
|
||||
|
||||
def get_pod_port(self, pod_name, namespace="default"):
|
||||
# TODO(gcheresh) get pod port using container id, as kuryr this would
|
||||
# depend on port_debug kuryr feature
|
||||
port_list = self.os_admin.ports_client.list_ports()
|
||||
for port in port_list['ports']:
|
||||
if pod_name == port['name']:
|
||||
return port
|
||||
|
||||
def assign_fip_to_pod(self, pod_name, namespace="default"):
|
||||
ext_net_id = CONF.network.public_network_id
|
||||
pod_fip = self.os_admin.floating_ips_client.create_floatingip(
|
||||
floating_network_id=ext_net_id,
|
||||
tenant_id=self.get_project_id(),
|
||||
port_id=self.get_pod_port(pod_name)['id'])
|
||||
self.pod_fips.append(pod_fip)
|
||||
return pod_fip
|
||||
|
||||
def get_project_id(self, project_name='k8s'):
|
||||
projects_list = self.os_admin.projects_client.list_projects()
|
||||
for project in projects_list['projects']:
|
||||
if project_name == project['name']:
|
||||
return project['id']
|
|
@ -0,0 +1,66 @@
|
|||
# Copyright 2017 Red Hat, Inc.
|
||||
#
|
||||
# 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 testtools
|
||||
|
||||
from oslo_log import log as logging
|
||||
from tempest import config
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions
|
||||
from tempest.lib.common.utils import data_utils
|
||||
|
||||
from kuryr_tempest_plugin.tests.scenario import base
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class TestCrossPingScenario(base.BaseKuryrScenarioTest):
|
||||
|
||||
@classmethod
|
||||
def skip_checks(cls):
|
||||
super(TestCrossPingScenario, cls).skip_checks()
|
||||
if not CONF.network_feature_enabled.floating_ips:
|
||||
raise cls.skipException("Floating ips are not available")
|
||||
|
||||
@decorators.idempotent_id('bddf5441-1244-449d-a125-b5fddfb1a1a8')
|
||||
def test_vm_pod_ping(self):
|
||||
keypair = self.create_keypair()
|
||||
security_groups = [
|
||||
{'name': self._create_security_group()['name']}
|
||||
]
|
||||
server = self.create_server(name=data_utils.rand_name(prefix='kuryr'),
|
||||
key_name=keypair['name'],
|
||||
security_groups=security_groups)
|
||||
fip = self.create_floating_ip(server)
|
||||
|
||||
pod_name, pod = self.create_pod()
|
||||
self.addCleanup(self.delete_pod, pod_name, pod)
|
||||
pod_fip = self.assign_fip_to_pod(pod_name)
|
||||
|
||||
ssh_client = self.get_remote_client(fip['floating_ip_address'],
|
||||
private_key=keypair['private_key'])
|
||||
cmd = ("ping -c1 -w1 %s &> /dev/null; echo $?" %
|
||||
pod_fip['floatingip']['floating_ip_address'])
|
||||
|
||||
try:
|
||||
result = ssh_client.exec_command(cmd)
|
||||
if result:
|
||||
msg = ('Failed while trying to ping. Could not ping '
|
||||
'from host "%s" to "%s".' % (
|
||||
fip['floating_ip_address'],
|
||||
pod_fip['floatingip']['floating_ip_address']))
|
||||
self.assertEqual('0', result.rstrip('\n'))
|
||||
except exceptions.SSHExecCommandFailed:
|
||||
LOG.error("Couldn't ping server")
|
Loading…
Reference in New Issue