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
20
21
22 var (
23 TestHelper *testutil.TestHelper
24 )
25
26 func TestMain(m *testing.M) {
27 TestHelper = testutil.NewTestHelper()
28
29 TestHelper.WaitUntilDeployReady(testutil.LinkerdDeployReplicasEdge)
30 os.Exit(m.Run())
31 }
32
33
34
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
60 for _, deploy := range []string{"smoke-test-terminus", "smoke-test-gateway"} {
61 if err := TestHelper.CheckPods(ctx, ns, deploy, 1); err != nil {
62
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
72 cmd = []string{"check", "--proxy", "--expected-version", TestHelper.GetVersion(), "--namespace", ns, "--wait=60m"}
73 expected := getCheckOutput(t, "check.proxy.golden", TestHelper.GetLinkerdNamespace())
74
75
76
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
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