1 package edges
2
3 import (
4 "bytes"
5 "context"
6 "fmt"
7 "os"
8 "regexp"
9 "strings"
10 "testing"
11 "text/template"
12 "time"
13
14 "github.com/linkerd/linkerd2/testutil"
15 )
16
17 var TestHelper *testutil.TestHelper
18
19 func TestMain(m *testing.M) {
20 TestHelper = testutil.NewTestHelper()
21
22 TestHelper.WaitUntilDeployReady(testutil.LinkerdVizDeployReplicas)
23 os.Exit(m.Run())
24 }
25
26
27
28
29
30 func TestEdges(t *testing.T) {
31 ns := TestHelper.GetLinkerdNamespace()
32 promNs := TestHelper.GetVizNamespace()
33 vars := struct {
34 Ns string
35 PromNs string
36 }{ns, promNs}
37
38 var b bytes.Buffer
39 tpl := template.Must(template.ParseFiles("testdata/linkerd_edges.golden"))
40 if err := tpl.Execute(&b, vars); err != nil {
41 t.Fatalf("failed to parse linkerd_edges.golden template: %s", err)
42 }
43
44 timeout := 50 * time.Second
45 cmd := []string{
46 "edges",
47 "-n", ns,
48 "deploy",
49 "-ojson",
50 }
51 r := regexp.MustCompile(b.String())
52 err := testutil.RetryFor(timeout, func() error {
53 out, err := TestHelper.LinkerdRun(cmd...)
54 if err != nil {
55 t.Fatal(err)
56 }
57 pods, err := TestHelper.Kubectl("", []string{"get", "pods", "-A"}...)
58 if err != nil {
59 return err
60 }
61 if !r.MatchString(out) {
62 t.Errorf("Expected output:\n%s\nactual:\n%s\nAll pods: %s", b.String(), out, pods)
63 }
64 return nil
65 })
66 if err != nil {
67 testutil.AnnotatedError(t, fmt.Sprintf("timed-out checking edges (%s)", timeout), err)
68 }
69 }
70
71
72
73 func TestDirectEdges(t *testing.T) {
74
75 ctx := context.Background()
76
77 TestHelper.WithDataPlaneNamespace(ctx, "direct-edges-test", map[string]string{}, t, func(t *testing.T, testNamespace string) {
78
79
80
81 out, err := TestHelper.LinkerdRun("inject", "--manual", "testdata/terminus.yaml")
82 if err != nil {
83 testutil.AnnotatedFatalf(t, "'linkerd inject' command failed", "'linkerd inject' command failed: %s", err)
84 }
85
86
87
88 out, err = TestHelper.KubectlApply(out, testNamespace)
89 if err != nil {
90 testutil.AnnotatedFatalf(t, "kubectl apply command failed", "kubectl apply command failed\n%s", out)
91 }
92
93 if err := TestHelper.CheckPods(ctx, testNamespace, "terminus", 1); err != nil {
94
95 if rce, ok := err.(*testutil.RestartCountError); ok {
96 testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
97 } else {
98 testutil.AnnotatedError(t, "CheckPods timed-out", err)
99 }
100 }
101
102
103
104 ip, err := TestHelper.Kubectl("", "-n", testNamespace, "get", "pod", "-ojsonpath=\"{.items[*].status.podIP}\"")
105 if err != nil {
106 testutil.AnnotatedError(t, "'kubectl get pod' command failed", err)
107 }
108 ip = strings.Trim(ip, "\"")
109
110 b, err := os.ReadFile("testdata/slow-cooker.yaml")
111 if err != nil {
112 testutil.AnnotatedError(t, "error reading file slow-cooker.yaml", err)
113 }
114
115 slowcooker := string(b)
116 slowcooker = strings.ReplaceAll(slowcooker, "___TERMINUS_POD_IP___", ip)
117
118
119
120 out, stderr, err := TestHelper.PipeToLinkerdRun(slowcooker, "inject", "--manual", "-")
121 if err != nil {
122 testutil.AnnotatedFatalf(t, "'linkerd 'inject' command failed", "'linkerd %s' command failed with %s: %s\n", "inject", err.Error(), stderr)
123 }
124
125
126
127 out, err = TestHelper.KubectlApply(out, testNamespace)
128 if err != nil {
129 testutil.AnnotatedFatalf(t, "kubectl apply command failed", "kubectl apply command failed\n%s", out)
130 }
131
132 if err := TestHelper.CheckPods(ctx, testNamespace, "slow-cooker", 1); err != nil {
133
134 if rce, ok := err.(*testutil.RestartCountError); ok {
135 testutil.AnnotatedWarn(t, "CheckPods timed-out", rce)
136 } else {
137 testutil.AnnotatedError(t, "CheckPods timed-out", err)
138 }
139 }
140
141
142 timeout := 50 * time.Second
143 testDataPath := "testdata"
144 err = testutil.RetryFor(timeout, func() error {
145 out, err = TestHelper.LinkerdRun("-n", testNamespace, "-o", "json", "viz", "edges", "deploy")
146 if err != nil {
147 return err
148 }
149
150 tpl := template.Must(template.ParseFiles(testDataPath + "/direct_edges.golden"))
151 vars := struct {
152 Ns string
153 VizNs string
154 }{
155 testNamespace,
156 TestHelper.GetVizNamespace(),
157 }
158 var buf bytes.Buffer
159 if err := tpl.Execute(&buf, vars); err != nil {
160 return fmt.Errorf("failed to parse direct_edges.golden template: %w", err)
161 }
162
163 pods, err := TestHelper.Kubectl("", []string{"get", "pods", "-A"}...)
164 if err != nil {
165 return err
166 }
167
168 r := regexp.MustCompile(buf.String())
169 if !r.MatchString(out) {
170 return fmt.Errorf("Expected output:\n%s\nactual:\n%s\nAll pods: %s", buf.String(), out, pods)
171 }
172 return nil
173 })
174
175 if err != nil {
176 testutil.AnnotatedError(t, fmt.Sprintf("timed-out checking edges (%s)", timeout), err)
177 }
178 })
179
180 }
181
View as plain text