...

Source file src/github.com/linkerd/linkerd2/test/integration/install/smoke/install_smoke_test.go

Documentation: github.com/linkerd/linkerd2/test/integration/install/smoke

     1  package smoke
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"html/template"
     8  	"os"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/linkerd/linkerd2/pkg/healthcheck"
    14  	"github.com/linkerd/linkerd2/pkg/version"
    15  	"github.com/linkerd/linkerd2/testutil"
    16  )
    17  
    18  //////////////////////
    19  ///   TEST SETUP   ///
    20  //////////////////////
    21  
    22  var (
    23  	TestHelper *testutil.TestHelper
    24  )
    25  
    26  func TestMain(m *testing.M) {
    27  	TestHelper = testutil.NewTestHelper()
    28  	// Block test execution until control plane pods are running
    29  	TestHelper.WaitUntilDeployReady(testutil.LinkerdDeployReplicasEdge)
    30  	os.Exit(m.Run())
    31  }
    32  
    33  //////////////////////
    34  /// TEST EXECUTION ///
    35  //////////////////////
    36  
    37  func TestSmoke(t *testing.T) {
    38  	ctx := context.Background()
    39  	TestHelper.WithDataPlaneNamespace(ctx, "smoke-test", map[string]string{}, t, func(t *testing.T, ns string) {
    40  		cmd := []string{"inject", "testdata/smoke_test.yaml"}
    41  		out, injectReport, err := TestHelper.PipeToLinkerdRun("", cmd...)
    42  		if err != nil {
    43  			testutil.AnnotatedFatalf(t, "'linkerd inject' command failed",
    44  				"'linkerd inject' command failed: %s\n%s", err, out)
    45  		}
    46  
    47  		err = TestHelper.ValidateOutput(injectReport, "inject.report.golden")
    48  		if err != nil {
    49  			testutil.AnnotatedFatalf(t, "received unexpected output",
    50  				"received unexpected output\n%s", err.Error())
    51  		}
    52  
    53  		out, err = TestHelper.KubectlApply(out, ns)
    54  		if err != nil {
    55  			testutil.AnnotatedFatalf(t, "'kubectl apply' command failed",
    56  				"'kubectl apply' command failed\n%s", out)
    57  		}
    58  
    59  		// Wait for pods to in smoke-test deployment to come up
    60  		for _, deploy := range []string{"smoke-test-terminus", "smoke-test-gateway"} {
    61  			if err := TestHelper.CheckPods(ctx, ns, deploy, 1); err != nil {
    62  				//nolint:errorlint
    63  				if rce, ok := err.(*testutil.RestartCountError); ok {
    64  					testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
    65  				} else {
    66  					testutil.AnnotatedFatal(t, "CheckPods timed-out", err)
    67  				}
    68  			}
    69  		}
    70  
    71  		// Test 'linkerd check --proxy' with the current image version
    72  		cmd = []string{"check", "--proxy", "--expected-version", TestHelper.GetVersion(), "--namespace", ns, "--wait=60m"}
    73  		expected := getCheckOutput(t, "check.proxy.golden", TestHelper.GetLinkerdNamespace())
    74  
    75  		// Use a short time window for check tests to get rid of transient
    76  		// errors
    77  		timeout := 5 * time.Minute
    78  		err = testutil.RetryFor(timeout, func() error {
    79  			out, err := TestHelper.LinkerdRun(cmd...)
    80  			if err != nil {
    81  				return fmt.Errorf("'linkerd check' command failed\n%w\n%s", err, out)
    82  			}
    83  
    84  			if !strings.Contains(out, expected) {
    85  				return fmt.Errorf(
    86  					"Expected:\n%s\nActual:\n%s", expected, out)
    87  			}
    88  
    89  			return nil
    90  		})
    91  
    92  		if err != nil {
    93  			testutil.AnnotatedFatal(t, fmt.Sprintf("'linkerd check' command timed-out (%s)", timeout), err)
    94  		}
    95  
    96  		// Test traffic from smoke-test client to server
    97  		url, err := TestHelper.URLFor(ctx, ns, "smoke-test-gateway", 8080)
    98  		if err != nil {
    99  			testutil.AnnotatedFatalf(t, "failed to get URL",
   100  				"failed to get URL: %s", err)
   101  		}
   102  
   103  		output, err := TestHelper.HTTPGetURL(url)
   104  		if err != nil {
   105  			testutil.AnnotatedFatalf(t, "unexpected error",
   106  				"unexpected error: %v %s", err, output)
   107  		}
   108  
   109  		expectedStringInPayload := "\"payload\":\"BANANA\""
   110  		if !strings.Contains(output, expectedStringInPayload) {
   111  			testutil.AnnotatedFatalf(t, "application response doesn't contain the expected response",
   112  				"expected application response to contain string [%s], but it was [%s]",
   113  				expectedStringInPayload, output)
   114  		}
   115  	})
   116  
   117  }
   118  
   119  func getCheckOutput(t *testing.T, goldenFile string, namespace string) string {
   120  	pods, err := TestHelper.KubernetesHelper.GetPods(context.Background(), namespace, nil)
   121  	if err != nil {
   122  		testutil.AnnotatedFatal(t, fmt.Sprintf("failed to retrieve pods: %s", err), err)
   123  	}
   124  
   125  	proxyVersionErr := ""
   126  	err = healthcheck.CheckProxyVersionsUpToDate(pods, version.Channels{})
   127  	if err != nil {
   128  		proxyVersionErr = err.Error()
   129  	}
   130  
   131  	tpl := template.Must(template.ParseFiles("testdata" + "/" + goldenFile))
   132  	vars := struct {
   133  		ProxyVersionErr string
   134  		HintURL         string
   135  	}{
   136  		proxyVersionErr,
   137  		healthcheck.HintBaseURL(TestHelper.GetVersion()),
   138  	}
   139  
   140  	var expected bytes.Buffer
   141  	if err := tpl.Execute(&expected, vars); err != nil {
   142  		testutil.AnnotatedFatal(t, fmt.Sprintf("failed to parse %s template: %s", goldenFile, err), err)
   143  	}
   144  
   145  	return expected.String()
   146  }
   147  

View as plain text