From a62a7e07b67bf24f14ca57197f614d4b7a6bc126 Mon Sep 17 00:00:00 2001 From: Arthur Barr Date: Thu, 28 Sep 2017 16:36:41 +0100 Subject: [PATCH 1/2] Add test for storage classes --- test/kubernetes/helm_test.go | 19 +++++++++++++++--- test/kubernetes/helm_test_util.go | 33 +++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/test/kubernetes/helm_test.go b/test/kubernetes/helm_test.go index 05cb69fd..a90f45f2 100644 --- a/test/kubernetes/helm_test.go +++ b/test/kubernetes/helm_test.go @@ -24,11 +24,24 @@ import ( var namespace = "default" -func TestHelmGoldenPath(t *testing.T) { +// Prior to running this test, a Persistent Volume must be created +func TestHelmPredefinedVolume(t *testing.T) { cs := kubeLogin(t) release := strings.ToLower(t.Name()) helmInstall(t, cs, release, "license=accept", "persistence.useDynamicProvisioning=false") - defer helmDelete(t, release) + defer helmDelete(t, cs, release) + defer helmDeletePVC(t, cs, release) + waitForReady(t, cs, release) +} + +func TestHelmStorageClass(t *testing.T) { + cs := kubeLogin(t) + release := strings.ToLower(t.Name()) + if !storageClassesDefined(t, cs) { + t.Skipf("Skipping test because no storage classes were found") + } + helmInstall(t, cs, release, "license=accept", "persistence.useDynamicProvisioning=true") + defer helmDelete(t, cs, release) defer helmDeletePVC(t, cs, release) waitForReady(t, cs, release) } @@ -37,7 +50,7 @@ func TestPersistenceDisabled(t *testing.T) { cs := kubeLogin(t) release := strings.ToLower(t.Name()) helmInstall(t, cs, release, "license=accept", "persistence.enabled=false") - defer helmDelete(t, release) + defer helmDelete(t, cs, release) waitForReady(t, cs, release) // Check that no PVCs were created diff --git a/test/kubernetes/helm_test_util.go b/test/kubernetes/helm_test_util.go index cf7a3353..5c3658bf 100644 --- a/test/kubernetes/helm_test_util.go +++ b/test/kubernetes/helm_test_util.go @@ -16,6 +16,7 @@ limitations under the License. package main import ( + "bytes" "fmt" "os" "os/exec" @@ -57,9 +58,23 @@ func runCommand(t *testing.T, name string, arg ...string) (string, int, error) { return string(out), 0, nil } +func inspectLogs(t *testing.T, cs *kubernetes.Clientset, release string) string { + pods := getPodsForHelmRelease(t, cs, release) + opt := v1.PodLogOptions{} + r := cs.CoreV1().Pods(namespace).GetLogs(pods.Items[0].Name, &opt) + buf := new(bytes.Buffer) + rc, err := r.Stream() + if err != nil { + t.Fatal(err) + } + buf.ReadFrom(rc) + return buf.String() +} + func helmInstall(t *testing.T, cs *kubernetes.Clientset, release string, values ...string) { chart := "../../charts/ibm-mqadvanced-server-prod" - image := "mycluster.icp:8500/default/mq-devserver" + //image := "mycluster.icp:8500/default/mq-devserver" + image := "ibmcom/mq" tag := "latest" arg := []string{ "install", @@ -85,7 +100,8 @@ func helmInstall(t *testing.T, cs *kubernetes.Clientset, release string, values } } -func helmDelete(t *testing.T, release string) { +func helmDelete(t *testing.T, cs *kubernetes.Clientset, release string) { + t.Log(inspectLogs(t, cs, release)) out, _, err := runCommand(t, "helm", "delete", "--purge", release) if err != nil { t.Error(out) @@ -184,3 +200,16 @@ func getPodsForHelmRelease(t *testing.T, cs *kubernetes.Clientset, release strin } return pods } + +func storageClassesDefined(t *testing.T, cs *kubernetes.Clientset) bool { + c, err := cs.Storage().StorageClasses().List(metav1.ListOptions{}) + if err != nil { + t.Fatal(err) + } + if len(c.Items) > 0 { + return true + } + return false +} + +// TODO: On Minikube, need to make sure Helm is initialized first From 3479b03f8d405d8bee40937819902b0448ba62a3 Mon Sep 17 00:00:00 2001 From: Arthur Barr Date: Mon, 2 Oct 2017 09:08:47 +0100 Subject: [PATCH 2/2] Additional Helm tests --- test/kubernetes/helm_test.go | 3 +++ test/kubernetes/helm_test_util.go | 29 +++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/test/kubernetes/helm_test.go b/test/kubernetes/helm_test.go index a90f45f2..76c94f69 100644 --- a/test/kubernetes/helm_test.go +++ b/test/kubernetes/helm_test.go @@ -28,6 +28,9 @@ var namespace = "default" func TestHelmPredefinedVolume(t *testing.T) { cs := kubeLogin(t) release := strings.ToLower(t.Name()) + if !volumesAvailable(t, cs) { + t.Skipf("Skipping test because no persistent volumes were found") + } helmInstall(t, cs, release, "license=accept", "persistence.useDynamicProvisioning=false") defer helmDelete(t, cs, release) defer helmDeletePVC(t, cs, release) diff --git a/test/kubernetes/helm_test_util.go b/test/kubernetes/helm_test_util.go index 5c3658bf..cdd7a72d 100644 --- a/test/kubernetes/helm_test_util.go +++ b/test/kubernetes/helm_test_util.go @@ -32,6 +32,14 @@ import ( "k8s.io/client-go/tools/clientcmd" ) +func imageName() string { + image, ok := os.LookupEnv("TEST_IMAGE") + if !ok { + image = "ibmcom/mq" + } + return image +} + // runCommand runs an OS command. On Linux it waits for the command to // complete and returns the exit status (return code). // TODO: duplicated from cmd/runmqserver/main.go @@ -74,7 +82,7 @@ func inspectLogs(t *testing.T, cs *kubernetes.Clientset, release string) string func helmInstall(t *testing.T, cs *kubernetes.Clientset, release string, values ...string) { chart := "../../charts/ibm-mqadvanced-server-prod" //image := "mycluster.icp:8500/default/mq-devserver" - image := "ibmcom/mq" + //image := "ibmcom/mq" tag := "latest" arg := []string{ "install", @@ -83,12 +91,13 @@ func helmInstall(t *testing.T, cs *kubernetes.Clientset, release string, values "--name", release, "--set", - "image.repository=" + image, + "image.repository=" + imageName(), "--set", "image.tag=" + tag, "--set", "image.pullSecret=admin.registrykey", } + // Add any extra values to the Helm command for _, value := range values { arg = append(arg, "--set", value) } @@ -212,4 +221,20 @@ func storageClassesDefined(t *testing.T, cs *kubernetes.Clientset) bool { return false } +// volumesAvailable checks to see if any persistent volumes are available. +// On some Kubernetes clusters, only storage classes are used, so there won't +// be any volumes pre-created. +func volumesAvailable(t *testing.T, cs *kubernetes.Clientset) bool { + pvs, err := cs.CoreV1().PersistentVolumes().List(metav1.ListOptions{}) + if err != nil { + t.Fatal(err) + } + for _, pv := range pvs.Items { + if pv.Status.Phase == v1.VolumeAvailable { + return true + } + } + return false +} + // TODO: On Minikube, need to make sure Helm is initialized first