github.com/terraform-modules-krish/terratest@v0.29.0/modules/helm/install_test.go (about)

     1  // +build kubeall helm
     2  
     3  // NOTE: we have build tags to differentiate kubernetes tests from non-kubernetes tests, and further differentiate helm
     4  // tests. This is done because minikube is heavy and can interfere with docker related tests in terratest. Similarly,
     5  // helm can overload the minikube system and thus interfere with the other kubernetes tests. To avoid overloading the
     6  // system, we run the kubernetes tests and helm tests separately from the others.
     7  
     8  package helm
     9  
    10  import (
    11  	"crypto/tls"
    12  	"fmt"
    13  	"strings"
    14  	"testing"
    15  	"time"
    16  
    17  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    18  
    19  	http_helper "github.com/terraform-modules-krish/terratest/modules/http-helper"
    20  	"github.com/terraform-modules-krish/terratest/modules/k8s"
    21  	"github.com/terraform-modules-krish/terratest/modules/random"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  // Test that we can install a remote chart (e.g stable/chartmuseum)
    26  func TestRemoteChartInstall(t *testing.T) {
    27  	t.Parallel()
    28  
    29  	helmChart := "stable/chartmuseum"
    30  
    31  	namespaceName := fmt.Sprintf(
    32  		"%s-%s",
    33  		strings.ToLower(t.Name()),
    34  		strings.ToLower(random.UniqueId()),
    35  	)
    36  
    37  	// Use default kubectl options to create a new namespace for this test, and then update the namespace for kubectl
    38  	kubectlOptions := k8s.NewKubectlOptions("", "", namespaceName)
    39  
    40  	defer k8s.DeleteNamespace(t, kubectlOptions, namespaceName)
    41  	k8s.CreateNamespace(t, kubectlOptions, namespaceName)
    42  
    43  	// Override service type to node port
    44  	options := &Options{
    45  		KubectlOptions: kubectlOptions,
    46  		SetValues: map[string]string{
    47  			"service.type": "NodePort",
    48  		},
    49  	}
    50  
    51  	// Generate a unique release name so we can defer the delete before installing
    52  	releaseName := fmt.Sprintf(
    53  		"chartmuseum-%s",
    54  		strings.ToLower(random.UniqueId()),
    55  	)
    56  	defer Delete(t, options, releaseName, true)
    57  
    58  	// Test if helm.install will return an error if the chart version is incorrect
    59  	options.Version = "notValidVersion.0.0.0"
    60  	require.Error(t, InstallE(t, options, helmChart, releaseName))
    61  
    62  	// Fix chart version and retry install
    63  	options.Version = "2.3.0"
    64  	require.NoError(t, InstallE(t, options, helmChart, releaseName))
    65  	waitForRemoteChartPods(t, kubectlOptions, releaseName, 1)
    66  
    67  	// Verify service is accessible. Wait for it to become available and then hit the endpoint.
    68  	// Service name is RELEASE_NAME-CHART_NAME
    69  	serviceName := fmt.Sprintf("%s-chartmuseum", releaseName)
    70  	k8s.WaitUntilServiceAvailable(t, kubectlOptions, serviceName, 10, 1*time.Second)
    71  	service := k8s.GetService(t, kubectlOptions, serviceName)
    72  	endpoint := k8s.GetServiceEndpoint(t, kubectlOptions, service, 8080)
    73  
    74  	// Setup a TLS configuration to submit with the helper, a blank struct is acceptable
    75  	tlsConfig := tls.Config{}
    76  
    77  	http_helper.HttpGetWithRetryWithCustomValidation(
    78  		t,
    79  		fmt.Sprintf("http://%s", endpoint),
    80  		&tlsConfig,
    81  		30,
    82  		10*time.Second,
    83  		func(statusCode int, body string) bool {
    84  			return statusCode == 200
    85  		},
    86  	)
    87  }
    88  
    89  func waitForRemoteChartPods(t *testing.T, kubectlOptions *k8s.KubectlOptions, releaseName string, podCount int) {
    90  	// Get pod and wait for it to be avaialable
    91  	// To get the pod, we need to filter it using the labels that the helm chart creates
    92  	filters := metav1.ListOptions{
    93  		LabelSelector: fmt.Sprintf("app=chartmuseum,release=%s", releaseName),
    94  	}
    95  	k8s.WaitUntilNumPodsCreated(t, kubectlOptions, filters, podCount, 30, 10*time.Second)
    96  	pods := k8s.ListPods(t, kubectlOptions, filters)
    97  	for _, pod := range pods {
    98  		k8s.WaitUntilPodAvailable(t, kubectlOptions, pod.Name, 30, 10*time.Second)
    99  	}
   100  }