From c52e5bea06c70e3e6656f9cde9d3c818b4151281 Mon Sep 17 00:00:00 2001 From: Hongbin Lu Date: Sun, 28 Feb 2016 18:21:08 -0500 Subject: [PATCH] Add tox test for k8s coreos bay * Add a CoreOS test class TestCoreosKubernetesAPIs * Add a CoreOS test environment in tox.ini * Create a base class BaseK8sTest and move OS-agnostic k8s testing code to that class. * Increase the disk size from 8G to 10G for m1.magnum and s1.magnum, since CoreOS image requires more disk space to boot. * Set os-distro property for CoreOS image. Partial-Bug: #1546101 Change-Id: Ie56a9442ecebe05f39c7669bc950f5a6ca11df33 --- devstack/lib/magnum | 4 + doc/source/dev/functional-test.rst | 4 +- magnum/tests/contrib/gate_hook.sh | 4 +- magnum/tests/contrib/post_test_hook.sh | 6 +- .../functional/k8s/test_k8s_python_client.py | 102 +--------------- .../tests/functional/k8s_coreos/__init__.py | 0 .../k8s_coreos/test_k8s_python_client.py | 22 ++++ magnum/tests/functional/python_client_base.py | 112 ++++++++++++++++++ tox.ini | 10 ++ 9 files changed, 159 insertions(+), 105 deletions(-) create mode 100644 magnum/tests/functional/k8s_coreos/__init__.py create mode 100644 magnum/tests/functional/k8s_coreos/test_k8s_python_client.py diff --git a/devstack/lib/magnum b/devstack/lib/magnum index f787dcbf7a..972eec0d82 100644 --- a/devstack/lib/magnum +++ b/devstack/lib/magnum @@ -272,6 +272,10 @@ function magnum_register_image { if [ ! -z "$ubuntu" ]; then magnum_image_property=$magnum_image_property"ubuntu" fi + local coreos="$(echo $MAGNUM_GUEST_IMAGE_URL | grep -io "coreos" || true;)" + if [ ! -z "$coreos" ]; then + magnum_image_property=$magnum_image_property"coreos" + fi openstack --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT --os-image-api-version 1 image set $(basename "$MAGNUM_GUEST_IMAGE_URL" ".qcow2") $magnum_image_property } diff --git a/doc/source/dev/functional-test.rst b/doc/source/dev/functional-test.rst index 7e7725d74e..a07be30f6f 100644 --- a/doc/source/dev/functional-test.rst +++ b/doc/source/dev/functional-test.rst @@ -49,8 +49,8 @@ Create the necessary keypair and flavor:: source /opt/stack/devstack/openrc admin admin nova keypair-add --pub-key ~/.ssh/id_rsa.pub default - nova flavor-create m1.magnum 100 1024 8 1 - nova flavor-create s1.magnum 200 512 8 1 + nova flavor-create m1.magnum 100 1024 10 1 + nova flavor-create s1.magnum 200 512 10 1 source /opt/stack/devstack/openrc demo demo nova keypair-add --pub-key ~/.ssh/id_rsa.pub default diff --git a/magnum/tests/contrib/gate_hook.sh b/magnum/tests/contrib/gate_hook.sh index 51ebaa7274..1d5717386d 100755 --- a/magnum/tests/contrib/gate_hook.sh +++ b/magnum/tests/contrib/gate_hook.sh @@ -22,7 +22,9 @@ export DEVSTACK_LOCAL_CONFIG="enable_plugin magnum git://git.openstack.org/opens export DEVSTACK_LOCAL_CONFIG+=$'\n'"enable_plugin ceilometer git://git.openstack.org/openstack/ceilometer" if [ "$coe" = "mesos" ]; then - echo "MAGNUM_GUEST_IMAGE_URL="https://fedorapeople.org/groups/magnum/ubuntu-14.04.3-mesos-0.25.0.qcow2"" >> $BASE/new/devstack/localrc + echo "MAGNUM_GUEST_IMAGE_URL=https://fedorapeople.org/groups/magnum/ubuntu-14.04.3-mesos-0.25.0.qcow2" >> $BASE/new/devstack/localrc +elif [ "$coe" = "k8s-coreos" ]; then + echo "MAGNUM_GUEST_IMAGE_URL=http://beta.release.core-os.net/amd64-usr/current/coreos_production_openstack_image.img.bz2" >> $BASE/new/devstack/localrc fi $BASE/new/devstack-gate/devstack-vm-gate.sh diff --git a/magnum/tests/contrib/post_test_hook.sh b/magnum/tests/contrib/post_test_hook.sh index 039f8b7f03..beb7dd442c 100755 --- a/magnum/tests/contrib/post_test_hook.sh +++ b/magnum/tests/contrib/post_test_hook.sh @@ -30,6 +30,8 @@ function create_test_data { coe=$1 if [ $coe == 'mesos' ]; then local image_name="ubuntu-14.04" + elif [ $coe == 'k8s-coreos' ]; then + local image_name="coreos" else local image_name="atomic" fi @@ -138,8 +140,8 @@ function add_flavor { # Create magnum specific flavor for use in functional tests. echo_summary "Create a flavor" - nova flavor-create m1.magnum 100 1024 8 1 - nova flavor-create s1.magnum 200 512 8 1 + nova flavor-create m1.magnum 100 1024 10 1 + nova flavor-create s1.magnum 200 512 10 1 } if ! function_exists echo_summary; then diff --git a/magnum/tests/functional/k8s/test_k8s_python_client.py b/magnum/tests/functional/k8s/test_k8s_python_client.py index 5e50c9170f..f7da2f0696 100644 --- a/magnum/tests/functional/k8s/test_k8s_python_client.py +++ b/magnum/tests/functional/k8s/test_k8s_python_client.py @@ -10,15 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. -from k8sclient.client import api_client -from k8sclient.client.apis import apiv_api - -from magnum.tests.functional.common import utils -from magnum.tests.functional.python_client_base import BayTest +from magnum.tests.functional import python_client_base as base -class TestKubernetesAPIs(BayTest): - coe = 'kubernetes' +class TestKubernetesAPIs(base.BaseK8sTest): baymodel_kwargs = { "tls_disabled": False, "network_driver": 'flannel', @@ -26,99 +21,6 @@ class TestKubernetesAPIs(BayTest): "fixed_network": '192.168.0.0/24' } - def setUp(self): - super(TestKubernetesAPIs, self).setUp() - self.kube_api_url = self.cs.bays.get(self.bay.uuid).api_address - k8s_client = api_client.ApiClient(self.kube_api_url, - key_file=self.key_file, - cert_file=self.cert_file, - ca_certs=self.ca_file) - self.k8s_api = apiv_api.ApivApi(k8s_client) - # TODO(coreypobrien) https://bugs.launchpad.net/magnum/+bug/1551824 - utils.wait_for_condition(self._is_api_ready, 5, 600) - - def _is_api_ready(self): - try: - self.k8s_api.list_namespaced_node() - self.LOG.info("API is ready.") - return True - except Exception: - self.LOG.info("API is not ready yet.") - return False - - def test_pod_apis(self): - pod_manifest = {'apiVersion': 'v1', - 'kind': 'Pod', - 'metadata': {'color': 'blue', 'name': 'test'}, - 'spec': {'containers': [{'image': 'dockerfile/redis', - 'name': 'redis'}]}} - - resp = self.k8s_api.create_namespaced_pod(body=pod_manifest, - namespace='default') - self.assertEqual('test', resp.metadata.name) - self.assertTrue(resp.status.phase) - - resp = self.k8s_api.read_namespaced_pod(name='test', - namespace='default') - self.assertEqual('test', resp.metadata.name) - self.assertTrue(resp.status.phase) - - resp = self.k8s_api.delete_namespaced_pod(name='test', body={}, - namespace='default') - - def test_service_apis(self): - service_manifest = {'apiVersion': 'v1', - 'kind': 'Service', - 'metadata': {'labels': {'name': 'frontend'}, - 'name': 'frontend', - 'resourceversion': 'v1'}, - 'spec': {'ports': [{'port': 80, - 'protocol': 'TCP', - 'targetPort': 80}], - 'selector': {'name': 'frontend'}}} - - resp = self.k8s_api.create_namespaced_service(body=service_manifest, - namespace='default') - self.assertEqual('frontend', resp.metadata.name) - self.assertTrue(resp.status) - - resp = self.k8s_api.read_namespaced_service(name='frontend', - namespace='default') - self.assertEqual('frontend', resp.metadata.name) - self.assertTrue(resp.status) - - resp = self.k8s_api.delete_namespaced_service(name='frontend', - namespace='default') - - def test_replication_controller_apis(self): - rc_manifest = { - 'apiVersion': 'v1', - 'kind': 'ReplicationController', - 'metadata': {'labels': {'name': 'frontend'}, - 'name': 'frontend'}, - 'spec': {'replicas': 2, - 'selector': {'name': 'frontend'}, - 'template': {'metadata': { - 'labels': {'name': 'frontend'}}, - 'spec': {'containers': [{ - 'image': 'nginx', - 'name': 'nginx', - 'ports': [{'containerPort': 80, - 'protocol': 'TCP'}]}]}}}} - - resp = self.k8s_api.create_namespaced_replication_controller( - body=rc_manifest, namespace='default') - self.assertEqual('frontend', resp.metadata.name) - self.assertEqual(2, resp.spec.replicas) - - resp = self.k8s_api.read_namespaced_replication_controller( - name='frontend', namespace='default') - self.assertEqual('frontend', resp.metadata.name) - self.assertEqual(2, resp.spec.replicas) - - resp = self.k8s_api.delete_namespaced_replication_controller( - name='frontend', body={}, namespace='default') - """ NB : Bug1504379. This is placeholder and will be removed when all the objects-from-bay patches are checked in. diff --git a/magnum/tests/functional/k8s_coreos/__init__.py b/magnum/tests/functional/k8s_coreos/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/magnum/tests/functional/k8s_coreos/test_k8s_python_client.py b/magnum/tests/functional/k8s_coreos/test_k8s_python_client.py new file mode 100644 index 0000000000..54f7a09538 --- /dev/null +++ b/magnum/tests/functional/k8s_coreos/test_k8s_python_client.py @@ -0,0 +1,22 @@ +# 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 magnum.tests.functional import python_client_base as base + + +class TestCoreosKubernetesAPIs(base.BaseK8sTest): + baymodel_kwargs = { + "tls_disabled": True, + "network_driver": 'flannel', + "volume_driver": None, + "fixed_network": '192.168.0.0/24' + } diff --git a/magnum/tests/functional/python_client_base.py b/magnum/tests/functional/python_client_base.py index 42153bab97..f68c84ae2d 100644 --- a/magnum/tests/functional/python_client_base.py +++ b/magnum/tests/functional/python_client_base.py @@ -26,6 +26,8 @@ import fixtures from six.moves import configparser from heatclient import client as heatclient +from k8sclient.client import api_client +from k8sclient.client.apis import apiv_api from keystoneclient.v2_0 import client as ksclient from magnum.common.utils import rmtree_without_raise from magnum.tests.functional.common import base @@ -224,6 +226,9 @@ extendedKeyUsage = clientAuth ca_dir = None bay = None baymodel = None + key_file = None + cert_file = None + ca_file = None @classmethod def setUpClass(cls): @@ -337,3 +342,110 @@ extendedKeyUsage = clientAuth resp = cls.cs.certificates.get(cls.bay.uuid) with open(cls.ca_file, 'w') as f: f.write(resp.pem) + + +class BaseK8sTest(BayTest): + coe = 'kubernetes' + + @classmethod + def setUpClass(cls): + super(BaseK8sTest, cls).setUpClass() + cls.kube_api_url = cls.cs.bays.get(cls.bay.uuid).api_address + k8s_client = api_client.ApiClient(cls.kube_api_url, + key_file=cls.key_file, + cert_file=cls.cert_file, + ca_certs=cls.ca_file) + cls.k8s_api = apiv_api.ApivApi(k8s_client) + + def setUp(self): + super(BaseK8sTest, self).setUp() + self.kube_api_url = self.cs.bays.get(self.bay.uuid).api_address + k8s_client = api_client.ApiClient(self.kube_api_url, + key_file=self.key_file, + cert_file=self.cert_file, + ca_certs=self.ca_file) + self.k8s_api = apiv_api.ApivApi(k8s_client) + # TODO(coreypobrien) https://bugs.launchpad.net/magnum/+bug/1551824 + utils.wait_for_condition(self._is_api_ready, 5, 600) + + def _is_api_ready(self): + try: + self.k8s_api.list_namespaced_node() + self.LOG.info("API is ready.") + return True + except Exception: + self.LOG.info("API is not ready yet.") + return False + + def test_pod_apis(self): + pod_manifest = {'apiVersion': 'v1', + 'kind': 'Pod', + 'metadata': {'color': 'blue', 'name': 'test'}, + 'spec': {'containers': [{'image': 'dockerfile/redis', + 'name': 'redis'}]}} + + resp = self.k8s_api.create_namespaced_pod(body=pod_manifest, + namespace='default') + self.assertEqual('test', resp.metadata.name) + self.assertTrue(resp.status.phase) + + resp = self.k8s_api.read_namespaced_pod(name='test', + namespace='default') + self.assertEqual('test', resp.metadata.name) + self.assertTrue(resp.status.phase) + + resp = self.k8s_api.delete_namespaced_pod(name='test', body={}, + namespace='default') + + def test_service_apis(self): + service_manifest = {'apiVersion': 'v1', + 'kind': 'Service', + 'metadata': {'labels': {'name': 'frontend'}, + 'name': 'frontend', + 'resourceversion': 'v1'}, + 'spec': {'ports': [{'port': 80, + 'protocol': 'TCP', + 'targetPort': 80}], + 'selector': {'name': 'frontend'}}} + + resp = self.k8s_api.create_namespaced_service(body=service_manifest, + namespace='default') + self.assertEqual('frontend', resp.metadata.name) + self.assertTrue(resp.status) + + resp = self.k8s_api.read_namespaced_service(name='frontend', + namespace='default') + self.assertEqual('frontend', resp.metadata.name) + self.assertTrue(resp.status) + + resp = self.k8s_api.delete_namespaced_service(name='frontend', + namespace='default') + + def test_replication_controller_apis(self): + rc_manifest = { + 'apiVersion': 'v1', + 'kind': 'ReplicationController', + 'metadata': {'labels': {'name': 'frontend'}, + 'name': 'frontend'}, + 'spec': {'replicas': 2, + 'selector': {'name': 'frontend'}, + 'template': {'metadata': { + 'labels': {'name': 'frontend'}}, + 'spec': {'containers': [{ + 'image': 'nginx', + 'name': 'nginx', + 'ports': [{'containerPort': 80, + 'protocol': 'TCP'}]}]}}}} + + resp = self.k8s_api.create_namespaced_replication_controller( + body=rc_manifest, namespace='default') + self.assertEqual('frontend', resp.metadata.name) + self.assertEqual(2, resp.spec.replicas) + + resp = self.k8s_api.read_namespaced_replication_controller( + name='frontend', namespace='default') + self.assertEqual('frontend', resp.metadata.name) + self.assertEqual(2, resp.spec.replicas) + + resp = self.k8s_api.delete_namespaced_replication_controller( + name='frontend', body={}, namespace='default') diff --git a/tox.ini b/tox.ini index 050b8fc1fe..00c265be88 100644 --- a/tox.ini +++ b/tox.ini @@ -46,6 +46,16 @@ commands = find . -type f -name "*.pyc" -delete bash tools/pretty_tox.sh '{posargs}' +[testenv:functional-k8s-coreos] +sitepackages = True +setenv = OS_TEST_PATH=./magnum/tests/functional/k8s_coreos + OS_TEST_TIMEOUT=7200 +deps = + {[testenv]deps} +commands = + find . -type f -name "*.pyc" -delete + bash tools/pretty_tox.sh '{posargs}' + [testenv:functional-swarm] sitepackages = True setenv = OS_TEST_PATH=./magnum/tests/functional/swarm