rally-openstack/tests/unit/scenarios/magnum/test_utils.py

396 lines
18 KiB
Python

# 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 os
import mock
from kubernetes import client as kubernetes_client
from kubernetes.client.rest import ApiException
from rally import exceptions
from rally_openstack.scenarios.magnum import utils
from tests.unit import test
MAGNUM_UTILS = "rally_openstack.scenarios.magnum.utils"
CONF = utils.CONF
class MagnumScenarioTestCase(test.ScenarioTestCase):
def setUp(self):
super(MagnumScenarioTestCase, self).setUp()
self.cluster_template = mock.Mock()
self.cluster = mock.Mock()
self.pod = mock.Mock()
self.scenario = utils.MagnumScenario(self.context)
def test_list_cluster_templates(self):
fake_list = [self.cluster_template]
self.clients("magnum").cluster_templates.list.return_value = fake_list
return_ct_list = self.scenario._list_cluster_templates()
self.assertEqual(fake_list, return_ct_list)
self.clients("magnum").cluster_templates.list.assert_called_once_with()
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"magnum.list_cluster_templates")
def test_create_cluster_template(self):
self.scenario.generate_random_name = mock.Mock(
return_value="generated_name")
fake_ct = self.cluster_template
self.clients("magnum").cluster_templates.create.return_value = fake_ct
return_cluster_template = self.scenario._create_cluster_template(
image="test_image",
keypair="test_key",
external_network="public",
dns_nameserver="8.8.8.8",
flavor="m1.large",
docker_volume_size=50,
network_driver="docker",
coe="swarm")
self.assertEqual(fake_ct, return_cluster_template)
_, kwargs = self.clients("magnum").cluster_templates.create.call_args
self.assertEqual("generated_name", kwargs["name"])
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"magnum.create_cluster_template")
def test_get_cluster_template(self):
client = self.clients("magnum")
client.cluster_templates.get.return_value = self.cluster_template
return_cluster_template = self.scenario._get_cluster_template("uuid")
client.cluster_templates.get.assert_called_once_with("uuid")
self.assertEqual(self.cluster_template, return_cluster_template)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.get_cluster_template")
def test_list_clusters(self):
return_clusters_list = self.scenario._list_clusters(limit="foo1")
client = self.clients("magnum")
client.clusters.list.assert_called_once_with(limit="foo1")
self.assertEqual(client.clusters.list.return_value,
return_clusters_list)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.list_clusters")
def test_create_cluster(self):
self.scenario.generate_random_name = mock.Mock(
return_value="generated_name")
self.clients("magnum").clusters.create.return_value = self.cluster
return_cluster = self.scenario._create_cluster(
cluster_template="generated_uuid", node_count=2)
self.mock_wait_for_status.mock.assert_called_once_with(
self.cluster,
ready_statuses=["CREATE_COMPLETE"],
failure_statuses=["CREATE_FAILED", "ERROR"],
update_resource=self.mock_get_from_manager.mock.return_value,
check_interval=CONF.openstack.
magnum_cluster_create_poll_interval,
timeout=CONF.openstack.magnum_cluster_create_timeout,
id_attr="uuid")
_, kwargs = self.clients("magnum").clusters.create.call_args
self.assertEqual("generated_name", kwargs["name"])
self.assertEqual("generated_uuid", kwargs["cluster_template_id"])
self.mock_get_from_manager.mock.assert_called_once_with()
self.assertEqual(
self.mock_wait_for_status.mock.return_value, return_cluster)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.create_cluster")
def test_get_cluster(self):
self.clients("magnum").clusters.get.return_value = self.cluster
return_cluster = self.scenario._get_cluster("uuid")
self.clients("magnum").clusters.get.assert_called_once_with("uuid")
self.assertEqual(self.cluster, return_cluster)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.get_cluster")
def test_get_ca_certificate(self):
self.scenario._get_ca_certificate(self.cluster.uuid)
self.clients("magnum").certificates.get.assert_called_once_with(
self.cluster.uuid)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.get_ca_certificate")
def test_create_ca_certificate(self):
csr_req = {"cluster_uuid": "uuid", "csr": "csr file"}
self.scenario._create_ca_certificate(csr_req)
self.clients("magnum").certificates.create.assert_called_once_with(
**csr_req)
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.create_ca_certificate")
@mock.patch("kubernetes.client.api_client.ApiClient")
@mock.patch("kubernetes.client.api.core_v1_api.CoreV1Api")
def test_get_k8s_api_client_using_tls(self, mock_core_v1_api,
mock_api_client):
if hasattr(kubernetes_client, "ConfigurationObject"):
# it is k8s-client < 4.0.0
m = mock.patch("kubernetes.client.ConfigurationObject")
else:
m = mock.patch("kubernetes.client.Configuration")
mock_configuration_object = m.start()
self.addCleanup(m.stop)
self.context.update({
"ca_certs_directory": "/home/stack",
"tenant": {
"id": "rally_tenant_id",
"cluster": "rally_cluster_uuid"
}
})
self.scenario = utils.MagnumScenario(self.context)
cluster_uuid = self.context["tenant"]["cluster"]
client = self.clients("magnum")
client.clusters.get.return_value = self.cluster
cluster = self.scenario._get_cluster(cluster_uuid)
self.cluster_template.tls_disabled = False
client.cluster_templates.get.return_value = self.cluster_template
dir = self.context["ca_certs_directory"]
key_file = os.path.join(dir, cluster_uuid.__add__(".key"))
cert_file = os.path.join(dir, cluster_uuid.__add__(".crt"))
ca_certs = os.path.join(dir, cluster_uuid.__add__("_ca.crt"))
config = mock_configuration_object.return_value
config.host = cluster.api_address
config.ssl_ca_cert = ca_certs
config.cert_file = cert_file
config.key_file = key_file
_api_client = mock_api_client.return_value
self.scenario._get_k8s_api_client()
mock_configuration_object.assert_called_once_with()
if hasattr(kubernetes_client, "ConfigurationObject"):
# k8s-python < 4.0.0
mock_api_client.assert_called_once_with(config=config)
else:
mock_api_client.assert_called_once_with(config)
mock_core_v1_api.assert_called_once_with(_api_client)
@mock.patch("kubernetes.client.api_client.ApiClient")
@mock.patch("kubernetes.client.api.core_v1_api.CoreV1Api")
def test_get_k8s_api_client(self, mock_core_v1_api, mock_api_client):
if hasattr(kubernetes_client, "ConfigurationObject"):
# it is k8s-client < 4.0.0
m = mock.patch("kubernetes.client.ConfigurationObject")
else:
m = mock.patch("kubernetes.client.Configuration")
mock_configuration_object = m.start()
self.addCleanup(m.stop)
self.context.update({
"tenant": {
"id": "rally_tenant_id",
"cluster": "rally_cluster_uuid"
}
})
self.scenario = utils.MagnumScenario(self.context)
cluster_uuid = self.context["tenant"]["cluster"]
client = self.clients("magnum")
client.clusters.get.return_value = self.cluster
cluster = self.scenario._get_cluster(cluster_uuid)
self.cluster_template.tls_disabled = True
client.cluster_templates.get.return_value = self.cluster_template
config = mock_configuration_object.return_value
config.host = cluster.api_address
config.ssl_ca_cert = None
config.cert_file = None
config.key_file = None
_api_client = mock_api_client.return_value
self.scenario._get_k8s_api_client()
mock_configuration_object.assert_called_once_with()
if hasattr(kubernetes_client, "ConfigurationObject"):
# k8s-python < 4.0.0
mock_api_client.assert_called_once_with(config=config)
else:
mock_api_client.assert_called_once_with(config)
mock_core_v1_api.assert_called_once_with(_api_client)
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_list_v1pods(self, mock__get_k8s_api_client):
k8s_api = mock__get_k8s_api_client.return_value
self.scenario._list_v1pods()
k8s_api.list_node.assert_called_once_with(
namespace="default")
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.k8s_list_v1pods")
@mock.patch("random.choice")
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_create_v1pod(self, mock__get_k8s_api_client,
mock_random_choice):
k8s_api = mock__get_k8s_api_client.return_value
manifest = (
{"apiVersion": "v1", "kind": "Pod",
"metadata": {"name": "nginx"}})
podname = manifest["metadata"]["name"] + "-"
for i in range(5):
podname = podname + mock_random_choice.return_value
k8s_api.create_namespaced_pod = mock.MagicMock(
side_effect=[ApiException(status=403), self.pod])
not_ready_pod = kubernetes_client.models.V1Pod()
not_ready_status = kubernetes_client.models.V1PodStatus()
not_ready_status.phase = "not_ready"
not_ready_pod.status = not_ready_status
almost_ready_pod = kubernetes_client.models.V1Pod()
almost_ready_status = kubernetes_client.models.V1PodStatus()
almost_ready_status.phase = "almost_ready"
almost_ready_pod.status = almost_ready_status
ready_pod = kubernetes_client.models.V1Pod()
ready_condition = kubernetes_client.models.V1PodCondition(
status="True", type="Ready")
ready_status = kubernetes_client.models.V1PodStatus()
ready_status.phase = "Running"
ready_status.conditions = [ready_condition]
ready_pod_metadata = kubernetes_client.models.V1ObjectMeta()
ready_pod_metadata.uid = "123456789"
ready_pod_spec = kubernetes_client.models.V1PodSpec(
node_name="host_abc",
containers=[]
)
ready_pod.status = ready_status
ready_pod.metadata = ready_pod_metadata
ready_pod.spec = ready_pod_spec
k8s_api.read_namespaced_pod = mock.MagicMock(
side_effect=[not_ready_pod, almost_ready_pod, ready_pod])
self.scenario._create_v1pod(manifest)
k8s_api.create_namespaced_pod.assert_called_with(
body=manifest, namespace="default")
k8s_api.read_namespaced_pod.assert_called_with(
name=podname, namespace="default")
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.k8s_create_v1pod")
@mock.patch("time.time")
@mock.patch("random.choice")
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_create_v1pod_timeout(self, mock__get_k8s_api_client,
mock_random_choice, mock_time):
k8s_api = mock__get_k8s_api_client.return_value
manifest = (
{"apiVersion": "v1", "kind": "Pod",
"metadata": {"name": "nginx"}})
k8s_api.create_namespaced_pod.return_value = self.pod
mock_time.side_effect = [1, 2, 3, 4, 5, 1800, 1801]
not_ready_pod = kubernetes_client.models.V1Pod()
not_ready_status = kubernetes_client.models.V1PodStatus()
not_ready_status.phase = "not_ready"
not_ready_pod_metadata = kubernetes_client.models.V1ObjectMeta()
not_ready_pod_metadata.uid = "123456789"
not_ready_pod.status = not_ready_status
not_ready_pod.metadata = not_ready_pod_metadata
k8s_api.read_namespaced_pod = mock.MagicMock(
side_effect=[not_ready_pod
for i in range(4)])
self.assertRaises(
exceptions.TimeoutException,
self.scenario._create_v1pod, manifest)
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_list_v1rcs(self, mock__get_k8s_api_client):
k8s_api = mock__get_k8s_api_client.return_value
self.scenario._list_v1rcs()
(k8s_api.list_namespaced_replication_controller
.assert_called_once_with(namespace="default"))
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.k8s_list_v1rcs")
@mock.patch("random.choice")
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_create_v1rc(self, mock__get_k8s_api_client,
mock_random_choice):
k8s_api = mock__get_k8s_api_client.return_value
manifest = (
{"apiVersion": "v1",
"kind": "ReplicationController",
"metadata": {"name": "nginx-controller"},
"spec": {"replicas": 2,
"selector": {"name": "nginx"},
"template": {"metadata":
{"labels":
{"name": "nginx"}}}}})
suffix = "-"
for i in range(5):
suffix = suffix + mock_random_choice.return_value
rcname = manifest["metadata"]["name"] + suffix
rc = kubernetes_client.models.V1ReplicationController()
rc.spec = kubernetes_client.models.V1ReplicationControllerSpec()
rc.spec.replicas = manifest["spec"]["replicas"]
k8s_api.create_namespaced_replication_controller.return_value = rc
not_ready_rc = kubernetes_client.models.V1ReplicationController()
not_ready_rc_status = (
kubernetes_client.models.V1ReplicationControllerStatus(replicas=0))
not_ready_rc.status = not_ready_rc_status
ready_rc = kubernetes_client.models.V1ReplicationController()
ready_rc_status = (
kubernetes_client.models.V1ReplicationControllerStatus(
replicas=manifest["spec"]["replicas"])
)
ready_rc_metadata = kubernetes_client.models.V1ObjectMeta()
ready_rc_metadata.uid = "123456789"
ready_rc_metadata.name = rcname
ready_rc.status = ready_rc_status
ready_rc.metadata = ready_rc_metadata
k8s_api.read_namespaced_replication_controller = mock.MagicMock(
side_effect=[not_ready_rc, ready_rc])
self.scenario._create_v1rc(manifest)
(k8s_api.create_namespaced_replication_controller
.assert_called_once_with(body=manifest, namespace="default"))
(k8s_api.read_namespaced_replication_controller
.assert_called_with(name=rcname, namespace="default"))
self._test_atomic_action_timer(
self.scenario.atomic_actions(), "magnum.k8s_create_v1rc")
@mock.patch("time.time")
@mock.patch("random.choice")
@mock.patch(MAGNUM_UTILS + ".MagnumScenario._get_k8s_api_client")
def test_create_v1rc_timeout(self, mock__get_k8s_api_client,
mock_random_choice, mock_time):
k8s_api = mock__get_k8s_api_client.return_value
manifest = (
{"apiVersion": "v1",
"kind": "ReplicationController",
"metadata": {"name": "nginx-controller"},
"spec": {"replicas": 2,
"selector": {"app": "nginx"},
"template": {"metadata":
{"labels":
{"name": "nginx"}}}}})
rc = kubernetes_client.models.V1ReplicationController()
rc.spec = kubernetes_client.models.V1ReplicationControllerSpec()
rc.spec.replicas = manifest["spec"]["replicas"]
mock_time.side_effect = [1, 2, 3, 4, 5, 1800, 1801]
k8s_api.create_namespaced_replication_controller.return_value = rc
not_ready_rc = kubernetes_client.models.V1ReplicationController()
not_ready_rc_status = (
kubernetes_client.models.V1ReplicationControllerStatus(replicas=0))
not_ready_rc_metadata = kubernetes_client.models.V1ObjectMeta()
not_ready_rc_metadata.uid = "123456789"
not_ready_rc.status = not_ready_rc_status
not_ready_rc.metadata = not_ready_rc_metadata
k8s_api.read_namespaced_replication_controller = mock.MagicMock(
side_effect=[not_ready_rc
for i in range(4)])
self.assertRaises(
exceptions.TimeoutException,
self.scenario._create_v1rc, manifest)