github.com/someshkoli/terratest@v0.41.1/modules/k8s/tunnel_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  	"crypto/tls"
    14  	"fmt"
    15  	"strings"
    16  	"testing"
    17  	"time"
    18  
    19  	http_helper "github.com/gruntwork-io/terratest/modules/http-helper"
    20  	"github.com/gruntwork-io/terratest/modules/random"
    21  )
    22  
    23  func TestTunnelOpensAPortForwardTunnelToPod(t *testing.T) {
    24  	t.Parallel()
    25  
    26  	uniqueID := strings.ToLower(random.UniqueId())
    27  	options := NewKubectlOptions("", "", uniqueID)
    28  	configData := fmt.Sprintf(EXAMPLE_POD_YAML_TEMPLATE, uniqueID, uniqueID)
    29  	defer KubectlDeleteFromString(t, options, configData)
    30  	KubectlApplyFromString(t, options, configData)
    31  	WaitUntilPodAvailable(t, options, "nginx-pod", 60, 1*time.Second)
    32  
    33  	// Open a tunnel to pod from any available port locally
    34  	tunnel := NewTunnel(options, ResourceTypePod, "nginx-pod", 0, 80)
    35  	defer tunnel.Close()
    36  	tunnel.ForwardPort(t)
    37  
    38  	// Setup a TLS configuration to submit with the helper, a blank struct is acceptable
    39  	tlsConfig := tls.Config{}
    40  
    41  	// Try to access the nginx service on the local port, retrying until we get a good response for up to 5 minutes
    42  	http_helper.HttpGetWithRetryWithCustomValidation(
    43  		t,
    44  		fmt.Sprintf("http://%s", tunnel.Endpoint()),
    45  		&tlsConfig,
    46  		60,
    47  		5*time.Second,
    48  		verifyNginxWelcomePage,
    49  	)
    50  }
    51  
    52  func TestTunnelOpensAPortForwardTunnelToService(t *testing.T) {
    53  	t.Parallel()
    54  
    55  	uniqueID := strings.ToLower(random.UniqueId())
    56  	options := NewKubectlOptions("", "", uniqueID)
    57  	configData := fmt.Sprintf(ExamplePodWithServiceYAMLTemplate, uniqueID, uniqueID, uniqueID)
    58  	defer KubectlDeleteFromString(t, options, configData)
    59  	KubectlApplyFromString(t, options, configData)
    60  	WaitUntilPodAvailable(t, options, "nginx-pod", 60, 1*time.Second)
    61  	WaitUntilServiceAvailable(t, options, "nginx-service", 60, 1*time.Second)
    62  
    63  	// Open a tunnel from any available port locally
    64  	tunnel := NewTunnel(options, ResourceTypeService, "nginx-service", 0, 80)
    65  	defer tunnel.Close()
    66  	tunnel.ForwardPort(t)
    67  
    68  	// Setup a TLS configuration to submit with the helper, a blank struct is acceptable
    69  	tlsConfig := tls.Config{}
    70  
    71  	// Try to access the nginx service on the local port, retrying until we get a good response for up to 5 minutes
    72  	http_helper.HttpGetWithRetryWithCustomValidation(
    73  		t,
    74  		fmt.Sprintf("http://%s", tunnel.Endpoint()),
    75  		&tlsConfig,
    76  		60,
    77  		5*time.Second,
    78  		verifyNginxWelcomePage,
    79  	)
    80  }
    81  
    82  func verifyNginxWelcomePage(statusCode int, body string) bool {
    83  	if statusCode != 200 {
    84  		return false
    85  	}
    86  	return strings.Contains(body, "Welcome to nginx")
    87  }
    88  
    89  const ExamplePodWithServiceYAMLTemplate = `---
    90  apiVersion: v1
    91  kind: Namespace
    92  metadata:
    93    name: %s
    94  ---
    95  apiVersion: v1
    96  kind: Pod
    97  metadata:
    98    name: nginx-pod
    99    namespace: %s
   100    labels:
   101      app: nginx
   102  spec:
   103    containers:
   104    - name: nginx
   105      image: nginx:1.15.7
   106      ports:
   107      - containerPort: 80
   108      readinessProbe:
   109        httpGet:
   110          path: /
   111          port: 80
   112  ---
   113  apiVersion: v1
   114  kind: Service
   115  metadata:
   116    name: nginx-service
   117    namespace: %s
   118  spec:
   119    selector:
   120      app: nginx
   121    ports:
   122    - protocol: TCP
   123      targetPort: 80
   124      port: 80
   125  `