1 package multiclustertraffic
2
3 import (
4 "context"
5 "fmt"
6 "strings"
7 "testing"
8 "time"
9
10 "github.com/linkerd/linkerd2/pkg/k8s"
11 "github.com/linkerd/linkerd2/testutil"
12 kerrors "k8s.io/apimachinery/pkg/api/errors"
13 )
14
15
16
17
18
19
20
21
22 func TestPodToPodTraffic(t *testing.T) {
23 if err := TestHelper.SwitchContext(contexts[testutil.TargetContextKey]); err != nil {
24 testutil.AnnotatedFatalf(t,
25 "failed to rebuild helper clientset with new context",
26 "failed to rebuild helper clientset with new context [%s]: %v",
27 contexts[testutil.TargetContextKey], err)
28 }
29
30 ctx := context.Background()
31
32 annotations := map[string]string{
33
34 }
35 TestHelper.WithDataPlaneNamespace(ctx, "emojivoto-p2p", annotations, t, func(t *testing.T, ns string) {
36 t.Run("Deploy resources in source and target clusters", func(t *testing.T) {
37
38 o, err := TestHelper.KubectlWithContext("", contexts[testutil.SourceContextKey], "create", "ns", ns)
39 if err != nil {
40 testutil.AnnotatedFatalf(t, "failed to create ns", "failed to create ns: %s\n%s", err, o)
41 }
42 o, err = TestHelper.KubectlApplyWithContext("", contexts[testutil.SourceContextKey], "--namespace", ns, "-f", "testdata/vote-bot.yml")
43 if err != nil {
44 testutil.AnnotatedFatalf(t, "failed to install vote-bot", "failed to install vote-bot: %s\n%s", err, o)
45 }
46
47 out, err := TestHelper.KubectlApplyWithContext("", contexts[testutil.TargetContextKey], "--namespace", ns, "-f", "testdata/emojivoto-no-bot.yml")
48 if err != nil {
49 testutil.AnnotatedFatalf(t, "failed to install emojivoto", "failed to install emojivoto: %s\n%s", err, out)
50 }
51
52 timeout := time.Minute
53 err = testutil.RetryFor(timeout, func() error {
54 out, err = TestHelper.KubectlWithContext("", contexts[testutil.TargetContextKey], "--namespace", ns, "label", "service/web-svc", "mirror.linkerd.io/exported=remote-discovery")
55 return err
56 })
57 if err != nil {
58 testutil.AnnotatedFatalf(t, "failed to label web-svc", "%s\n%s", err, out)
59 }
60 })
61
62 t.Run("Wait until target workloads are ready", func(t *testing.T) {
63
64 voteBotDeployReplica := map[string]testutil.DeploySpec{"vote-bot": {Namespace: ns, Replicas: 1}}
65 TestHelper.WaitRolloutWithContext(t, voteBotDeployReplica, contexts[testutil.SourceContextKey])
66
67
68 emojiDeployReplicas := map[string]testutil.DeploySpec{
69 "web": {Namespace: ns, Replicas: 1},
70 "emoji": {Namespace: ns, Replicas: 1},
71 "voting": {Namespace: ns, Replicas: 1},
72 }
73 TestHelper.WaitRolloutWithContext(t, emojiDeployReplicas, targetCtx)
74 })
75
76 timeout := time.Minute
77 t.Run("Ensure mirror service exists and has no endpoints", func(t *testing.T) {
78 err := TestHelper.SwitchContext(contexts[testutil.SourceContextKey])
79 if err != nil {
80 testutil.AnnotatedFatal(t, "failed to switch contexts", err)
81 }
82 err = testutil.RetryFor(timeout, func() error {
83 svc, err := TestHelper.GetService(ctx, ns, "web-svc-target")
84 if err != nil {
85 return err
86 }
87 remoteDiscovery, found := svc.Labels[k8s.RemoteDiscoveryLabel]
88 if !found {
89 testutil.AnnotatedFatal(t, "mirror service missing label", "mirror service missing label: "+k8s.RemoteDiscoveryLabel)
90 }
91 if remoteDiscovery != "target" {
92 testutil.AnnotatedFatal(t, "mirror service has incorrect remote discovery", fmt.Sprintf("mirror service remote discovery was %s, expected %s", remoteDiscovery, "target"))
93 }
94 remoteService, found := svc.Labels[k8s.RemoteServiceLabel]
95 if !found {
96 testutil.AnnotatedFatal(t, "mirror service missing label", "mirror service missing label: "+k8s.RemoteServiceLabel)
97 }
98 if remoteService != "web-svc" {
99 testutil.AnnotatedFatal(t, "mirror service has incorrect remote service", fmt.Sprintf("mirror service remote service was %s, expected %s", remoteService, "web-svc"))
100 }
101 _, err = TestHelper.GetEndpoints(ctx, ns, "web-svc-target")
102 if err == nil {
103 testutil.AnnotatedFatal(t, "mirror service should not have endpoints", "mirror service should not have endpoints")
104 }
105 if !kerrors.IsNotFound(err) {
106 testutil.AnnotatedFatalf(t, "failed to retrieve mirror service endpoints", err.Error())
107 }
108 return nil
109 })
110 if err != nil {
111 testutil.AnnotatedFatal(t, "timed-out verifying mirror service", err)
112 }
113 })
114
115 err := testutil.RetryFor(timeout, func() error {
116 out, err := TestHelper.KubectlWithContext("",
117 targetCtx,
118 "--namespace", ns,
119 "logs",
120 "--selector", "app=web-svc",
121 "--container", "web-svc",
122 )
123 if err != nil {
124 return fmt.Errorf("%w\n%s", err, out)
125 }
126
127 for _, row := range strings.Split(out, "\n") {
128 if strings.Contains(row, " /api/vote?choice=:doughnut: ") {
129 return nil
130 }
131 }
132 return fmt.Errorf("web-svc logs in target cluster do not include voting errors\n%s", out)
133 })
134 if err != nil {
135 testutil.AnnotatedFatal(t, fmt.Sprintf("timed-out waiting for traffic (%s)", timeout), err)
136 }
137 })
138 }
139
View as plain text