![Andrey Kurilin](/assets/img/avatar_default.png)
Move all modules under the next structure: - rally_openstack.common - rally_openstack.enviromnet - rally_openstack.task - rally_openstack.verification Change-Id: I41702d017cd49b117da3b8e12b19c7327229ae32
396 lines
18 KiB
Python
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.
|
|
|
|
from unittest import mock
|
|
|
|
import os
|
|
|
|
from kubernetes import client as kubernetes_client
|
|
from kubernetes.client.rest import ApiException
|
|
from rally import exceptions
|
|
from rally_openstack.task.scenarios.magnum import utils
|
|
from tests.unit import test
|
|
|
|
MAGNUM_UTILS = "rally_openstack.task.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)
|