diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000000..16e98d15fa --- /dev/null +++ b/test/Makefile @@ -0,0 +1,25 @@ +tests = $(wildcard **/*.robot) +RF_VENV :=../_output/.venv +RF_BINARY :=../_output/.venv/bin/robot +OUTPUT_DIR ?= ../_output/e2e-$$(date +''%Y%m%d-%H%M%S) +RF_VARIABLES ?=suites/variables.yaml +RF_OPTIONS :=--randomize all --loglevel DEBUG -x junit.xml -V $(RF_VARIABLES) --outputdir $(OUTPUT_DIR) + +.PHONY: setup dry-run all $(tests) + +setup: + python3 -m venv $(RF_VENV) && \ + $(RF_VENV)/bin/python3 -m pip install -r requirements.txt + +$(tests): + $(RF_BINARY) \ + $(RF_OPTIONS) \ + $@ + +dry-run: ROBOT_OPTIONS=--dryrun +dry-run: $(tests) + +all: + $(RF_BINARY) \ + $(RF_OPTIONS) \ + ./suites diff --git a/test/assets/hello-microshift.yaml b/test/assets/hello-microshift.yaml new file mode 100644 index 0000000000..11b27c5b90 --- /dev/null +++ b/test/assets/hello-microshift.yaml @@ -0,0 +1,26 @@ +kind: Pod +apiVersion: v1 +metadata: + name: hello-microshift + labels: + app: hello-microshift +spec: + terminationGracePeriodSeconds: 0 + containers: + - name: hello-microshift + image: busybox:1.35 + command: ["/bin/sh"] + args: ["-c", "while true; do echo -ne \"HTTP/1.0 200 OK\r\nContent-Length: 16\r\n\r\nHello MicroShift\" | nc -l -p 8080 ; done"] + ports: + - containerPort: 8080 + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + runAsUser: 1001 + runAsGroup: 1001 + seccompProfile: + type: RuntimeDefault diff --git a/test/requirements.txt b/test/requirements.txt new file mode 100644 index 0000000000..6423a3c296 --- /dev/null +++ b/test/requirements.txt @@ -0,0 +1,5 @@ +robotframework==6.0.2 +robotframework-requests==0.9.4 +robotframework-scplibrary==1.2.0 +robotframework-sshlibrary==3.8.0 +pyyaml==6.0 diff --git a/test/resources/common.resource b/test/resources/common.resource new file mode 100644 index 0000000000..5945f0ac35 --- /dev/null +++ b/test/resources/common.resource @@ -0,0 +1,34 @@ +*** Settings *** +Library OperatingSystem +Library String +Resource ../resources/kubeconfig.resource + +*** Keywords *** +Setup Suite + [Documentation] Setup a namespace-less test suite by configuring Kubeconfig + Check Required Env Variables + Setup Kubeconfig + +Setup Suite With Namespace + [Documentation] Setup a test suite by creating a unique namespace and configuring Kubeconfig + Check Required Env Variables + Setup Kubeconfig + ${rand}= Generate Random String + ${rand}= Convert To Lower Case ${rand} + ${ns}= Catenate SEPARATOR=- "test" ${rand} + Set Suite Variable \${NAMESPACE} ${ns} + Create Namespace ${ns} + +Teardown Suite + [Documentation] Teardown the namespace-less test suite by removing the Kubeconfig. + Remove Kubeconfig + +Teardown Suite With Namespace + [Documentation] Teardown the namespaced test suite by removing the namespace and removing the Kubeconfig. + Remove Namespace ${NAMESPACE} + Remove Kubeconfig + +Check Required Env Variables + [Documentation] Fail if any of the required environment variables is missing. + Run Keyword If "${USHIFT_HOST}"=="${EMPTY}" Fatal Error USHIFT_HOST variable is required + Run Keyword If "${USHIFT_USER}"=="${EMPTY}" Fatal Error USHIFT_USER variable is required diff --git a/test/resources/kubeconfig.resource b/test/resources/kubeconfig.resource new file mode 100644 index 0000000000..362f58fd37 --- /dev/null +++ b/test/resources/kubeconfig.resource @@ -0,0 +1,50 @@ +*** Settings *** +Library OperatingSystem +Library SSHLibrary +Library String + +*** Keywords *** +Get Kubeconfig + [Documentation] Get the kubeconfig file from the host argument and return contents + [Arguments] ${host} + SSHLibrary.Open Connection ${host} + SSHLibrary.Login With Public Key ${USHIFT_USER} ${SSH_PRIV_KEY} + ${kubeconfig} ${rc}= Execute Command + ... cat /var/lib/microshift/resources/kubeadmin/${host}/kubeconfig + ... sudo=True return_rc=True + SSHLibrary.Close Connection + Should Be Equal As Integers ${rc} 0 + Should Not Be Empty ${kubeconfig} + [Return] ${kubeconfig} + +Setup Kubeconfig + [Documentation] Get the kubeconfig file from the configured $USHIFT_HOST, create a temporary file + ... and export it as $KUBECONFIG variable. + ${kubeconfig}= Get Kubeconfig ${USHIFT_HOST} + ${rand}= Generate Random String + ${path}= Join Path /tmp ${rand} + Create File ${path} ${kubeconfig} + Set Suite Variable \${KUBECONFIG} ${path} + +Remove Kubeconfig + [Documentation] Remove kubeconfig ${KUBECONFIG} file. + Remove File ${KUBECONFIG} + +Run With Kubeconfig + [Documentation] Run a command using KUBECONFIG from the test suite. + [Arguments] ${cmd} ${allow_fail}=False + ${result}= Run Process ${cmd} env:KUBECONFIG=${KUBECONFIG} stderr=STDOUT shell=True + Log ${result.stdout} + IF ${allow_fail} == False + Should Be Equal As Integers ${result.rc} 0 + END + +Create Namespace + [Documentation] Creates a namespace with the given name. + [Arguments] ${ns} + Run With Kubeconfig oc create namespace ${ns} + +Remove Namespace + [Documentation] Removes the given namespace. + [Arguments] ${ns} + Run With Kubeconfig oc delete namespace ${ns} diff --git a/test/suites/load-balancer.robot b/test/suites/load-balancer.robot new file mode 100644 index 0000000000..586b17f9cd --- /dev/null +++ b/test/suites/load-balancer.robot @@ -0,0 +1,48 @@ +*** Settings *** +Documentation Load balancer test suite. + +Library Process + +Resource ../resources/common.resource +Resource ../resources/kubeconfig.resource + +Suite Setup Setup Suite With Namespace +Suite Teardown Teardown Suite With Namespace + +*** Variables *** +${HELLO_USHIFT} assets/hello-microshift.yaml + +*** Test Cases *** +Load Balancer Smoke Test + [Documentation] Verify that Load Balancer correctly exposes HTTP service + [Tags] smoke + [Setup] Run Keywords + ... Create Hello MicroShift Pod AND + ... Expose Hello MicroShift Pod Via LB + + Wait Until Keyword Succeeds 3x 3s Access Hello Microshift via LB + + [Teardown] Run Keywords + ... Delete Hello MicroShift Pod Route And Service + +*** Keywords *** +Create Hello MicroShift Pod + Run With Kubeconfig oc create -f ${HELLO_USHIFT} -n ${NAMESPACE} + Run With Kubeconfig oc wait pods -l app\=hello-microshift --for condition\=Ready --timeout\=60s -n ${NAMESPACE} + +Expose Hello MicroShift Pod Via LB + Run With Kubeconfig oc create service loadbalancer hello-microshift --tcp=5678:8080 -n ${NAMESPACE} + +Access Hello Microshift via LB + ${result}= Run Process + ... curl -i http://hello-microshift.cluster.local --connect-to "hello-microshift.cluster.local:80:${USHIFT_HOST}:5678" + ... shell=True timeout=15s + Log ${result} + Should Be Equal As Integers ${result.rc} 0 + Should Match Regexp ${result.stdout} HTTP.*200 + Should Match ${result.stdout} *Hello MicroShift* + +Delete Hello MicroShift Pod Route And Service + Run With Kubeconfig oc delete route hello-microshift -n ${NAMESPACE} True + Run With Kubeconfig oc delete service hello-microshift -n ${NAMESPACE} True + Run With Kubeconfig oc delete -f ${HELLO_USHIFT} -n ${NAMESPACE} True diff --git a/test/suites/variables.yaml b/test/suites/variables.yaml new file mode 100644 index 0000000000..ff5625cc4c --- /dev/null +++ b/test/suites/variables.yaml @@ -0,0 +1,6 @@ +# USHIFT_HOST: MicroShift host, can be a name or IP +USHIFT_HOST: microshift +# USHIFT_USER: User to log into MicroShift's host +USHIFT_USER: microshift +# SSH Private key to use when logging into MicroShift's host. +SSH_PRIV_KEY: /home/microshift/.ssh/id_rsa