def validate_dns_dashboard(): """ Validate the dashboard addon by looking at the grafana URL. Validate DNS by starting a busy box and nslookuping the kubernetes default service. """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=influxGrafana") cluster_info = kubectl("cluster-info") # Cluster info output is colored so we better search for the port in the url pattern # instead of trying to extract the url substring regex = "http://127.0.0.1:([0-9]+)/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy" grafana_pattern = re.compile(regex) for url in cluster_info.split(): port_search = grafana_pattern.search(url) if port_search: break grafana_url = "http://127.0.0.1:{}" \ "/api/v1/namespaces/kube-system/services/" \ "monitoring-grafana/proxy".format(port_search.group(1)) assert grafana_url attempt = 50 while attempt >= 0: resp = requests.get(grafana_url) if resp.status_code == 200: break time.sleep(2) attempt -= 1 assert resp.status_code == 200
def test_basic(self): """ Sets up and tests dashboard, dns, storage, registry, ingress. """ print("Enabling DNS") microk8s_enable("dns") wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") print("Enabling ingress") microk8s_enable("ingress") print("Validating ingress") validate_ingress() print("Disabling ingress") microk8s_disable("ingress") print("Enabling dashboard") microk8s_enable("dashboard") print("Validating dashboard") validate_dns_dashboard() print("Enabling storage") microk8s_enable("storage") print("Validating storage") validate_storage() microk8s_enable("registry") print("Validating registry") validate_registry() print("Validating Port Forward") validate_forward() print("Disabling registry") microk8s_disable("registry") print("Disabling dashboard") microk8s_disable("dashboard") print("Disabling storage") p = Popen("/snap/bin/microk8s.disable storage".split(), stdout=PIPE, stdin=PIPE, stderr=STDOUT) p.communicate(input=b'Y\n')[0] '''
def validate_multus(): """ Validate multus by making sure the multus pod is running. """ wait_for_installation() wait_for_pod_state("", "kube-system", "running", label="app=multus")
def validate_gpu(): """ Validate gpu by trying a cuda-add. """ if platform.machine() != 'x86_64': print("GPU tests are only relevant in x86 architectures") return wait_for_pod_state("", "kube-system", "running", label="name=nvidia-device-plugin-ds") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "cuda-add.yaml") get_pod = kubectl_get("po") if "cuda-vector-add" in str(get_pod): # Cleanup kubectl("delete -f {}".format(manifest)) time.sleep(10) kubectl("apply -f {}".format(manifest)) wait_for_pod_state("cuda-vector-add", "default", "terminated") result = kubectl("logs pod/cuda-vector-add") assert "PASSED" in result
def validate_istio(): """ Validate istio by deploying the bookinfo app. """ if platform.machine() != 'x86_64': print("GPU tests are only relevant in x86 architectures") return wait_for_installation() istio_services = [ "citadel", "egressgateway", "galley", "ingressgateway", "sidecar-injector", "statsd-prom-bridge", ] for service in istio_services: wait_for_pod_state("", "istio-system", "running", label="istio={}".format(service)) here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "bookinfo.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=details") kubectl("delete -f {}".format(manifest))
def test_dashboard(self): """ Validates dashboards works. """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") validate_dashboard()
def test_basic(self): """ Sets up and tests dashboard, dns, storage, registry, ingress. """ print("Enabling DNS") microk8s_enable("dns") wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") print("Enabling ingress") microk8s_enable("ingress") print("Validating ingress") validate_ingress() print("Disabling ingress") microk8s_disable("ingress") print("Enabling dashboard") microk8s_enable("dashboard") print("Validating dashboard") validate_dns_dashboard() print("Enabling storage") microk8s_enable("storage") print("Validating storage") validate_storage() microk8s_enable("registry") print("Validating registry") validate_registry() print("Validating Port Forward") validate_forward() print("Disabling registry") microk8s_disable("registry") print("Disabling dashboard") microk8s_disable("dashboard") print("Disabling storage") microk8s_disable("storage:destroy-storage") '''
def test_basic_s390x(self): """ Sets up and tests dashboard, dns, storage, registry, ingress, metrics server. """ ip_ranges = "8.8.8.8,1.1.1.1" print("Enabling DNS") microk8s_enable("{}:{}".format("dns", ip_ranges), timeout_insec=500) wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") print("Validating DNS config") validate_coredns_config(ip_ranges) print("Enabling metrics-server") microk8s_enable("metrics-server") print("Enabling dashboard") microk8s_enable("dashboard") print("Validating dashboard") validate_dns_dashboard() print("Validating Port Forward") validate_forward() print("Validating the Metrics Server") validate_metrics_server() print("Disabling metrics-server") microk8s_disable("metrics-server") print("Disabling dashboard") microk8s_disable("dashboard")
def validate_cilium(): """ Validate cilium by deploying the bookinfo app. """ if platform.machine() != "x86_64": print("Cilium tests are only relevant in x86 architectures") return wait_for_installation() wait_for_pod_state("", "kube-system", "running", label="k8s-app=cilium") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "nginx-pod.yaml") # Try up to three times to get nginx under cilium for attempt in range(0, 10): kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=nginx") output = cilium("endpoint list -o json", timeout_insec=20) if "nginx" in output: kubectl("delete -f {}".format(manifest)) break else: print("Cilium not ready will retry testing.") kubectl("delete -f {}".format(manifest)) time.sleep(20) else: print("Cilium testing failed.") assert False
def validate_multus(): """ Validate multus by deploying alpine pod with 3 interfaces. """ wait_for_installation() here = os.path.dirname(os.path.abspath(__file__)) shutil.rmtree("/tmp/microk8s-multus-test-nets", ignore_errors=True) networks = os.path.join(here, "templates", "multus-networks.yaml") kubectl("create -f {}".format(networks)) manifest = os.path.join(here, "templates", "multus-alpine.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=multus-alpine") output = kubectl("exec multus-alpine -- ifconfig eth1", timeout_insec=900, err_out="no") assert "10.111.111.111" in output output = kubectl("exec multus-alpine -- ifconfig eth2", timeout_insec=900, err_out="no") assert "10.222.222.222" in output kubectl("delete -f {}".format(manifest)) kubectl("delete -f {}".format(networks)) shutil.rmtree("/tmp/microk8s-multus-test-nets", ignore_errors=True)
def validate_registry(): """ Validate the private registry. """ wait_for_pod_state("", "container-registry", "running", label="app=registry") pvc_stdout = kubectl( "get pvc registry-claim -n container-registry -o yaml") pvc_yaml = yaml.safe_load(pvc_stdout) storage = pvc_yaml["spec"]["resources"]["requests"]["storage"] assert re.match("(^[2-9][0-9]{1,}|^[1-9][0-9]{2,})(Gi$)", storage) docker("pull busybox") docker("tag busybox localhost:32000/my-busybox") docker("push localhost:32000/my-busybox") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "bbox-local.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("busybox", "default", "running") output = kubectl("describe po busybox") assert "localhost:32000/my-busybox" in output kubectl("delete -f {}".format(manifest))
def validate_knative(): """ Validate Knative by deploying the helloworld-go app. """ if platform.machine() != "x86_64": print("Knative tests are only relevant in x86 architectures") return wait_for_installation() knative_services = [ "activator", "autoscaler", "controller", ] for service in knative_services: wait_for_pod_state("", "knative-serving", "running", label="app={}".format(service)) here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "knative-helloworld.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="serving.knative.dev/service=helloworld-go") kubectl("delete -f {}".format(manifest))
def validate_dns_dashboard(): """ Validate the dashboard addon by trying to access the kubernetes dashboard. The dashboard will return an HTML indicating that it is up and running. """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=kubernetes-dashboard") wait_for_pod_state("", "kube-system", "running", label="k8s-app=dashboard-metrics-scraper") attempt = 30 while attempt > 0: try: output = kubectl( "get " "--raw " "/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/" ) if "Kubernetes Dashboard" in output: break except subprocess.CalledProcessError: pass time.sleep(10) attempt -= 1 assert attempt > 0
def validate_ambassador(): """ Validate the Ambassador API Gateway by creating a ingress rule. """ if platform.machine() != "x86_64": print("Ambassador tests are only relevant in x86 architectures") return wait_for_pod_state("", "ambassador", "running", label="product=aes") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "ingress.yaml") update_yaml_with_arch(manifest) kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=microbot") # `Ingress`es must be annotatated for being recognized by Ambassador kubectl( "annotate ingress microbot-ingress-nip kubernetes.io/ingress.class=ambassador" ) kubectl( "annotate ingress microbot-ingress-xip kubernetes.io/ingress.class=ambassador" ) common_ingress() kubectl("delete -f {}".format(manifest))
def validate_storage(): """ Validate storage by creating a PVC. """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=hostpath-provisioner") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "pvc.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("hostpath-test-pod", "default", "running") attempt = 50 while attempt >= 0: output = kubectl("get pvc") if "Bound" in output: break time.sleep(2) attempt -= 1 # Make sure the test pod writes data sto the storage found = False for root, dirs, files in os.walk( "/var/snap/microk8s/common/default-storage"): for file in files: if file == "dates": found = True assert found assert "myclaim" in output assert "Bound" in output kubectl("delete -f {}".format(manifest))
def test_dns(self): """ Validates DNS works. """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") # Create a bbox validate_dns()
def validate_portainer(): """ Validate portainer """ wait_for_pod_state("", "portainer", "running", label="app.kubernetes.io/name=portainer")
def validate_traefik(): """ Validate traefik """ wait_for_pod_state("", "traefik", "running", label="name=traefik-ingress-lb")
def validate_kubeflow(): """ Validate kubeflow """ if platform.machine() != "x86_64": print("Kubeflow tests are only relevant in x86 architectures") return wait_for_pod_state("ambassador-operator-0", "kubeflow", "running")
def validate_kata(): """ Validate Kata """ wait_for_installation() here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "nginx-kata.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=kata") kubectl("delete -f {}".format(manifest))
def validate_prometheus(): """ Validate the prometheus operator """ if platform.machine() != 'x86_64': print("Prometheus tests are only relevant in x86 architectures") return wait_for_pod_state("prometheus-k8s-0", "monitoring", "running", timeout_insec=1200) wait_for_pod_state("alertmanager-main-0", "monitoring", "running", timeout_insec=1200)
def validate_dns(): """ Validate DNS by starting a busy box and nslookuping the kubernetes default service. """ here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "bbox.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("busybox", "default", "running") output = kubectl("exec -ti busybox -- nslookup kubernetes.default.svc.cluster.local") assert "10.152.183.1" in output kubectl("delete -f {}".format(manifest))
def test_dns_addon(self): ip_ranges = "8.8.8.8,1.1.1.1" print("Enabling DNS") microk8s_enable("{}:{}".format("dns", ip_ranges), timeout_insec=500) wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") print("Validating DNS config") validate_coredns_config(ip_ranges) print("Disabling DNS") microk8s_disable("dns")
def validate_keda(): """ Validate keda """ wait_for_installation() wait_for_pod_state("", "keda", "running", label="app=keda-operator") print("KEDA operator up and running.") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "keda-scaledobject.yaml") kubectl("apply -f {}".format(manifest)) scaledObject = kubectl("-n gonuts get scaledobject.keda.sh") assert "stan-scaledobject" in scaledObject kubectl("delete -f {}".format(manifest))
def test_dns(self): """ Sets up DNS addon and validates it works. """ print("Enabling DNS") microk8s_enable("dns") wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") # Create a bbox print("Validating dns") validate_dns() print("Disabling DNS") microk8s_disable("dns")
def validate_ingress(): """ Validate ingress by creating a ingress rule. """ daemonset = kubectl("get ds") if "nginx-ingress-microk8s-controller" in daemonset: wait_for_pod_state("", "default", "running", label="app=default-http-backend") wait_for_pod_state("", "default", "running", label="name=nginx-ingress-microk8s") else: wait_for_pod_state("", "ingress", "running", label="name=nginx-ingress-microk8s") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "ingress.yaml") update_yaml_with_arch(manifest) kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=microbot") common_ingress() kubectl("delete -f {}".format(manifest))
def validate_ingress(): """ Validate ingress by creating a ingress rule. """ daemonset = kubectl("get ds") if "nginx-ingress-microk8s-controller" in daemonset: wait_for_pod_state("", "default", "running", label="app=default-http-backend") wait_for_pod_state("", "default", "running", label="name=nginx-ingress-microk8s") else: wait_for_pod_state("", "ingress", "running", label="name=nginx-ingress-microk8s") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "ingress.yaml") update_yaml_with_arch(manifest) kubectl("apply -f {}".format(manifest)) wait_for_pod_state("", "default", "running", label="app=microbot") attempt = 50 while attempt >= 0: output = kubectl("get ing") if "microbot.127.0.0.1.xip.io" in output: break time.sleep(5) attempt -= 1 assert "microbot.127.0.0.1.xip.io" in output attempt = 50 while attempt >= 0: output = kubectl("get ing") if "microbot.127.0.0.1.nip.io" in output: break time.sleep(5) attempt -= 1 assert "microbot.127.0.0.1.nip.io" in output service_ok = False attempt = 50 while attempt >= 0: try: resp = requests.get("http://microbot.127.0.0.1.xip.io/") if resp.status_code == 200 and "microbot.png" in resp.content.decode("utf-8"): service_ok = True break except: time.sleep(5) attempt -= 1 if resp.status_code != 200 or "microbot.png" not in resp.content.decode("utf-8"): attempt = 50 while attempt >= 0: try: resp = requests.get("http://microbot.127.0.0.1.nip.io/") if resp.status_code == 200 and "microbot.png" in resp.content.decode("utf-8"): service_ok = True break except: time.sleep(5) attempt -= 1 assert service_ok kubectl("delete -f {}".format(manifest))
def validate_metrics_server(): """ Validate the metrics server works """ wait_for_pod_state("", "kube-system", "running", label="k8s-app=metrics-server") attempt = 5 while attempt > 0: try: output = kubectl("get --raw /apis/metrics.k8s.io/v1beta1/pods") if "PodMetricsList" in output: break except: pass time.sleep(10) attempt -= 1
def validate_registry(): """ Validate the private registry. """ wait_for_pod_state("", "container-registry", "running", label="app=registry") docker("pull busybox") docker("tag busybox localhost:32000/my-busybox") docker("push localhost:32000/my-busybox") here = os.path.dirname(os.path.abspath(__file__)) manifest = os.path.join(here, "templates", "bbox-local.yaml") kubectl("apply -f {}".format(manifest)) wait_for_pod_state("busybox", "default", "running") output = kubectl("describe po busybox") assert "localhost:32000/my-busybox" in output kubectl("delete -f {}".format(manifest))
def test_dashboard(self): """ Sets up dashboard and validates it works. """ print("Enabling DNS") microk8s_enable("dns") wait_for_pod_state("", "kube-system", "running", label="k8s-app=kube-dns") print("Enabling dashboard") microk8s_enable("dashboard") print("Validating dashboard") validate_dashboard() print("Disabling DNS") microk8s_disable("dns") print("Disabling dashboard") microk8s_disable("dashboard")