github.com/mponton/terratest@v0.44.0/modules/k8s/pod_test.go (about) 1 //go:build kubeall || kubernetes 2 // +build kubeall kubernetes 3 4 // NOTE: we have build tags to differentiate kubernetes tests from non-kubernetes tests. This is done because minikube 5 // is heavy and can interfere with docker related tests in terratest. Specifically, many of the tests start to fail with 6 // `connection refused` errors from `minikube`. To avoid overloading the system, we run the kubernetes tests and helm 7 // tests separately from the others. This may not be necessary if you have a sufficiently powerful machine. We 8 // recommend at least 4 cores and 16GB of RAM if you want to run all the tests together. 9 10 package k8s 11 12 import ( 13 "fmt" 14 "strings" 15 "testing" 16 "time" 17 18 "github.com/stretchr/testify/require" 19 corev1 "k8s.io/api/core/v1" 20 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 22 "github.com/mponton/terratest/modules/random" 23 ) 24 25 func TestListPodsReturnsPodsInNamespace(t *testing.T) { 26 t.Parallel() 27 28 uniqueID := strings.ToLower(random.UniqueId()) 29 options := NewKubectlOptions("", "", uniqueID) 30 configData := fmt.Sprintf(EXAMPLE_POD_YAML_TEMPLATE, uniqueID, uniqueID) 31 defer KubectlDeleteFromString(t, options, configData) 32 KubectlApplyFromString(t, options, configData) 33 34 pods := ListPods(t, options, metav1.ListOptions{}) 35 require.Equal(t, len(pods), 1) 36 pod := pods[0] 37 require.Equal(t, pod.Name, "nginx-pod") 38 require.Equal(t, pod.Namespace, uniqueID) 39 } 40 41 func TestGetPodEReturnsErrorForNonExistantPod(t *testing.T) { 42 t.Parallel() 43 44 options := NewKubectlOptions("", "", "default") 45 _, err := GetPodE(t, options, "nginx-pod") 46 require.Error(t, err) 47 } 48 49 func TestGetPodEReturnsCorrectPodInCorrectNamespace(t *testing.T) { 50 t.Parallel() 51 52 uniqueID := strings.ToLower(random.UniqueId()) 53 options := NewKubectlOptions("", "", uniqueID) 54 configData := fmt.Sprintf(EXAMPLE_POD_YAML_TEMPLATE, uniqueID, uniqueID) 55 defer KubectlDeleteFromString(t, options, configData) 56 KubectlApplyFromString(t, options, configData) 57 58 pod := GetPod(t, options, "nginx-pod") 59 require.Equal(t, pod.Name, "nginx-pod") 60 require.Equal(t, pod.Namespace, uniqueID) 61 } 62 63 func TestWaitUntilNumPodsCreatedReturnsSuccessfully(t *testing.T) { 64 t.Parallel() 65 66 uniqueID := strings.ToLower(random.UniqueId()) 67 options := NewKubectlOptions("", "", uniqueID) 68 configData := fmt.Sprintf(EXAMPLE_POD_YAML_TEMPLATE, uniqueID, uniqueID) 69 defer KubectlDeleteFromString(t, options, configData) 70 KubectlApplyFromString(t, options, configData) 71 72 WaitUntilNumPodsCreated(t, options, metav1.ListOptions{}, 1, 60, 1*time.Second) 73 } 74 75 func TestWaitUntilPodAvailableReturnsSuccessfully(t *testing.T) { 76 t.Parallel() 77 78 uniqueID := strings.ToLower(random.UniqueId()) 79 options := NewKubectlOptions("", "", uniqueID) 80 configData := fmt.Sprintf(EXAMPLE_POD_YAML_TEMPLATE, uniqueID, uniqueID) 81 defer KubectlDeleteFromString(t, options, configData) 82 KubectlApplyFromString(t, options, configData) 83 84 WaitUntilPodAvailable(t, options, "nginx-pod", 60, 1*time.Second) 85 } 86 87 func TestWaitUntilPodWithMultipleContainersAvailableReturnsSuccessfully(t *testing.T) { 88 t.Parallel() 89 90 uniqueID := strings.ToLower(random.UniqueId()) 91 options := NewKubectlOptions("", "", uniqueID) 92 configData := fmt.Sprintf(EXAMPLE_POD_WITH_MULTIPLE_CONTAINERS_YAML_TEMPLATE, uniqueID, uniqueID) 93 defer KubectlDeleteFromString(t, options, configData) 94 KubectlApplyFromString(t, options, configData) 95 96 WaitUntilPodAvailable(t, options, "nginx-pod", 60, 1*time.Second) 97 } 98 99 func TestWaitUntilPodAvailableWithReadinessProbe(t *testing.T) { 100 t.Parallel() 101 102 uniqueID := strings.ToLower(random.UniqueId()) 103 options := NewKubectlOptions("", "", uniqueID) 104 configData := fmt.Sprintf(EXAMPLE_POD_WITH_READINESS_PROBE, uniqueID, uniqueID) 105 defer KubectlDeleteFromString(t, options, configData) 106 KubectlApplyFromString(t, options, configData) 107 108 WaitUntilPodAvailable(t, options, "nginx-pod", 60, 1*time.Second) 109 } 110 111 func TestWaitUntilPodAvailableWithFailingReadinessProbe(t *testing.T) { 112 t.Parallel() 113 114 uniqueID := strings.ToLower(random.UniqueId()) 115 options := NewKubectlOptions("", "", uniqueID) 116 configData := fmt.Sprintf(EXAMPLE_POD_WITH_FAILING_READINESS_PROBE, uniqueID, uniqueID) 117 defer KubectlDeleteFromString(t, options, configData) 118 KubectlApplyFromString(t, options, configData) 119 120 err := WaitUntilPodAvailableE(t, options, "nginx-pod", 60, 1*time.Second) 121 require.Error(t, err) 122 } 123 124 const EXAMPLE_POD_YAML_TEMPLATE = `--- 125 apiVersion: v1 126 kind: Namespace 127 metadata: 128 name: %s 129 --- 130 apiVersion: v1 131 kind: Pod 132 metadata: 133 name: nginx-pod 134 namespace: %s 135 spec: 136 containers: 137 - name: nginx 138 image: nginx:1.15.7 139 ports: 140 - containerPort: 80 141 ` 142 143 const EXAMPLE_POD_WITH_MULTIPLE_CONTAINERS_YAML_TEMPLATE = EXAMPLE_POD_YAML_TEMPLATE + ` 144 - name: nginx-two 145 image: nginx:1.15.7 146 ports: 147 - containerPort: 80 148 ` 149 150 const EXAMPLE_POD_WITH_READINESS_PROBE = EXAMPLE_POD_YAML_TEMPLATE + ` 151 readinessProbe: 152 httpGet: 153 path: / 154 port: 80 155 ` 156 157 const EXAMPLE_POD_WITH_FAILING_READINESS_PROBE = EXAMPLE_POD_YAML_TEMPLATE + ` 158 readinessProbe: 159 httpGet: 160 path: /not-ready 161 port: 80 162 periodSeconds: 1 163 ` 164 165 func TestIsPodAvailable(t *testing.T) { 166 t.Parallel() 167 168 cases := []struct { 169 title string 170 pod *corev1.Pod 171 expectedResult bool 172 }{ 173 { 174 title: "TestIsPodAvailableStartedButNotReady", 175 pod: &corev1.Pod{ 176 Status: corev1.PodStatus{ 177 ContainerStatuses: []corev1.ContainerStatus{ 178 { 179 Name: "container1", 180 Ready: false, 181 Started: &[]bool{true}[0], 182 }, 183 }, 184 Phase: corev1.PodRunning, 185 }, 186 }, 187 expectedResult: false, 188 }, 189 { 190 title: "TestIsPodAvailableStartedAndReady", 191 pod: &corev1.Pod{ 192 Status: corev1.PodStatus{ 193 ContainerStatuses: []corev1.ContainerStatus{ 194 { 195 Name: "container1", 196 Ready: true, 197 Started: &[]bool{true}[0], 198 }, 199 }, 200 Phase: corev1.PodRunning, 201 }, 202 }, 203 expectedResult: true, 204 }, 205 } 206 for _, tc := range cases { 207 tc := tc 208 t.Run(tc.title, func(t *testing.T) { 209 t.Parallel() 210 actualResult := IsPodAvailable(tc.pod) 211 require.Equal(t, tc.expectedResult, actualResult) 212 }) 213 } 214 }