From 78582802d0c36b9d64c5e0f8bdfe3f462905c55c Mon Sep 17 00:00:00 2001 From: Sergey Dudoladov Date: Thu, 2 May 2019 13:15:51 +0200 Subject: [PATCH] refactor into helper methods --- e2e/tests/test_smoke.py | 118 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/e2e/tests/test_smoke.py b/e2e/tests/test_smoke.py index edbb3ab8c..cae18a22b 100755 --- a/e2e/tests/test_smoke.py +++ b/e2e/tests/test_smoke.py @@ -1,4 +1,3 @@ - import unittest import time import timeout_decorator @@ -8,21 +7,14 @@ import git from kubernetes import client, config, utils -class K8sApi: - - def __init__(self): - self.config = config.load_kube_config() - self.k8s_client = client.ApiClient() - self.core_v1 = client.CoreV1Api() - self.crd = client.CustomObjectsApi() - self.apps_v1 = client.AppsV1Api() - - class SmokeTestCase(unittest.TestCase): ''' - Test the most basic e2e functionality of the operator. + Test the most basic functions of the operator. ''' + TEST_TIMEOUT_SEC = 240 + RETRY_TIMEOUT_SEC = 5 + @classmethod def setUpClass(cls): ''' @@ -34,22 +26,19 @@ class SmokeTestCase(unittest.TestCase): next invocation of "make e2e" will re-create it. ''' + k8s_api = K8sApi() + # HACK # 1. creating RBAC entites with a separate client fails # with "AttributeError: object has no attribute 'select_header_accept'" # 2. utils.create_from_yaml cannot create multiple entites from a single file subprocess.run(["kubectl", "create", "-f", "manifests/operator-service-account-rbac.yaml"]) - k8s_api = K8sApi() - for filename in ["configmap.yaml", "postgres-operator.yaml"]: - path = "manifests/" + filename - utils.create_from_yaml(k8s_api.k8s_client, path) - - # submit most recent operator image built locally; see VERSION in Makefile - repo = git.Repo(".") - version = repo.git.describe("--tags", "--always", "--dirty") + utils.create_from_yaml(k8s_api.k8s_client, "manifests/" + filename) + # submit the most recent operator image built locally; see VERSION in Makefile + version = git.Repo(".").git.describe("--tags", "--always", "--dirty") body = { "spec": { "template": { @@ -66,71 +55,80 @@ class SmokeTestCase(unittest.TestCase): } k8s_api.apps_v1.patch_namespaced_deployment("postgres-operator", "default", body) - pod_phase = None - while pod_phase != 'Running': - pods = k8s_api.core_v1.list_namespaced_pod('default', label_selector='name=postgres-operator').items - if pods: - operator_pod = pods[0] - pod_phase = operator_pod.status.phase - print("Waiting for the operator pod to start. Current phase of pod lifecycle: " + str(pod_phase)) - time.sleep(5) + Utils.wait_for_pod_start(k8s_api, 'name=postgres-operator', cls.RETRY_TIMEOUT_SEC) # HACK around the lack of Python client for the acid.zalan.do resource subprocess.run(["kubectl", "create", "-f", "manifests/minimal-postgres-manifest.yaml"]) - pod_phase = 'None' - while pod_phase != 'Running': - pods = k8s_api.core_v1.list_namespaced_pod('default', label_selector='spilo-role=master').items - if pods: - operator_pod = pods[0] - pod_phase = operator_pod.status.phase - print("Waiting for the Spilo master pod to start. Current phase: " + str(pod_phase)) - time.sleep(5) + Utils.wait_for_pod_start(k8s_api, 'spilo-role=master', cls.RETRY_TIMEOUT_SEC) - @timeout_decorator.timeout(240) + @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_master_is_unique(self): """ Check that there is a single pod in the k8s cluster with the label "spilo-role=master". """ k8s = K8sApi() labels = 'spilo-role=master,version=acid-minimal-cluster' - master_pods = k8s.core_v1.list_namespaced_pod('default', label_selector=labels).items - self.assertEqual(len(master_pods), 1, "Expected 1 master pod, found " + str(len(master_pods))) - @timeout_decorator.timeout(240) + num_of_master_pods = Utils.count_pods_with_label(k8s, labels) + self.assertEqual(num_of_master_pods, 1, f"Expected 1 master pod, found {num_of_master_pods}") + + @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_scaling(self): """ Scale up from 2 to 3 pods and back to 2 by updating the Postgres manifest at runtime. """ k8s = K8sApi() + labels = "version=acid-minimal-cluster" + + Utils.wait_for_pg_to_scale(k8s, 3, self.RETRY_TIMEOUT_SEC) + self.assertEqual(3, Utils.count_pods_with_label(k8s, labels)) + + Utils.wait_for_pg_to_scale(k8s, 2, self.RETRY_TIMEOUT_SEC) + self.assertEqual(2, Utils.count_pods_with_label(k8s, labels)) + + +class K8sApi: + + def __init__(self): + self.config = config.load_kube_config() + self.k8s_client = client.ApiClient() + self.core_v1 = client.CoreV1Api() + self.crd = client.CustomObjectsApi() + self.apps_v1 = client.AppsV1Api() + + +class Utils: + + @staticmethod + def wait_for_pod_start(k8s_api, pod_labels, retry_timeout_sec): + pod_phase = 'No pod running' + while pod_phase != 'Running': + pods = k8s_api.core_v1.list_namespaced_pod('default', label_selector=pod_labels).items + if pods: + pod_phase = pods[0].status.phase + print(f"Wait for the {pod_labels} pod to start. Current pod phase: " + pod_phase) + time.sleep(retry_timeout_sec) + + @staticmethod + def wait_for_pg_to_scale(k8s_api, number_of_instances, retry_timeout_sec): body = { "spec": { - "numberOfInstances": 3 + "numberOfInstances": number_of_instances } } - _ = k8s.crd.patch_namespaced_custom_object("acid.zalan.do", - "v1", "default", "postgresqls", "acid-minimal-cluster", body) + _ = k8s_api.crd.patch_namespaced_custom_object("acid.zalan.do", + "v1", "default", "postgresqls", "acid-minimal-cluster", body) labels = 'version=acid-minimal-cluster' - while len(k8s.core_v1.list_namespaced_pod('default', label_selector=labels).items) != 3: - print("Waiting for the cluster to scale up to 3 pods.") - time.sleep(5) - self.assertEqual(3, len(k8s.core_v1.list_namespaced_pod('default', label_selector=labels).items)) + while Utils.count_pods_with_label(k8s_api, labels) != number_of_instances: + print(f"Waiting for the cluster to scale to {number_of_instances} pods.") + time.sleep(retry_timeout_sec) - body = { - "spec": { - "numberOfInstances": 2 - } - } - - _ = k8s.crd.patch_namespaced_custom_object("acid.zalan.do", - "v1", "default", "postgresqls", "acid-minimal-cluster", body) - - while len(k8s.core_v1.list_namespaced_pod('default', label_selector=labels).items) != 2: - print("Waiting for the cluster to scale down to 2 pods.") - time.sleep(5) - self.assertEqual(2, len(k8s.core_v1.list_namespaced_pod('default', label_selector=labels).items)) + @staticmethod + def count_pods_with_label(k8s_api, labels): + return len(k8s_api.core_v1.list_namespaced_pod('default', label_selector=labels).items) if __name__ == '__main__':