kuma

Форк
0
/
change_service.go 
190 строк · 5.8 Кб
1
package graceful
2

3
import (
4
	"fmt"
5
	"time"
6

7
	. "github.com/onsi/ginkgo/v2"
8
	. "github.com/onsi/gomega"
9
	corev1 "k8s.io/api/core/v1"
10
	kube_meta "k8s.io/apimachinery/pkg/apis/meta/v1"
11
	"k8s.io/apimachinery/pkg/util/intstr"
12

13
	"github.com/kumahq/kuma/pkg/plugins/policies/meshretry/api/v1alpha1"
14
	"github.com/kumahq/kuma/pkg/util/channels"
15
	"github.com/kumahq/kuma/pkg/util/pointer"
16
	. "github.com/kumahq/kuma/test/framework"
17
	"github.com/kumahq/kuma/test/framework/client"
18
	"github.com/kumahq/kuma/test/framework/deployments/testserver"
19
	"github.com/kumahq/kuma/test/framework/envs/kubernetes"
20
)
21

22
func ChangeService() {
23
	const namespace = "changesvc"
24
	const mesh = "changesvc"
25

26
	firstTestServerLabels := map[string]string{
27
		"app":                  "test-server",
28
		"changesvc-test-label": "first",
29
	}
30

31
	secondTestServerLabels := map[string]string{
32
		"app":                  "test-server",
33
		"changesvc-test-label": "second",
34
	}
35

36
	thirdTestServerLabels := map[string]string{
37
		"kuma.io/sidecar-injection": "disabled",
38
		"app":                       "test-server",
39
		"changesvc-test-label":      "third",
40
	}
41

42
	newSvc := func(selector map[string]string) *corev1.Service {
43
		return &corev1.Service{
44
			TypeMeta: kube_meta.TypeMeta{
45
				Kind:       "Service",
46
				APIVersion: "v1",
47
			},
48
			ObjectMeta: kube_meta.ObjectMeta{
49
				Name:      "test-server",
50
				Namespace: namespace,
51
			},
52
			Spec: corev1.ServiceSpec{
53
				Ports: []corev1.ServicePort{
54
					{
55
						Name:        "main",
56
						Port:        int32(80),
57
						TargetPort:  intstr.FromString("main"),
58
						AppProtocol: pointer.To("htt"),
59
					},
60
				},
61
				Selector: selector,
62
			},
63
		}
64
	}
65

66
	BeforeAll(func() {
67
		err := NewClusterSetup().
68
			Install(MTLSMeshKubernetes(mesh)).
69
			Install(MeshTrafficPermissionAllowAllKubernetes(mesh)).
70
			Install(NamespaceWithSidecarInjection(namespace)).
71
			Install(testserver.Install(
72
				testserver.WithNamespace(namespace),
73
				testserver.WithMesh(mesh),
74
				testserver.WithName("demo-client"),
75
			)).
76
			Install(testserver.Install(
77
				testserver.WithNamespace(namespace),
78
				testserver.WithMesh(mesh),
79
				testserver.WithName("test-server-first"),
80
				testserver.WithEchoArgs("echo", "--instance", "test-server-first"),
81
				testserver.WithoutService(),
82
				testserver.WithoutWaitingToBeReady(), // WaitForPods assumes that app label is name, but we change this in WithPodLabels
83
				testserver.WithPodLabels(firstTestServerLabels),
84
			)).
85
			Install(testserver.Install(
86
				testserver.WithNamespace(namespace),
87
				testserver.WithMesh(mesh),
88
				testserver.WithName("test-server-second"),
89
				testserver.WithEchoArgs("echo", "--instance", "test-server-second"),
90
				testserver.WithoutService(),
91
				testserver.WithoutWaitingToBeReady(), // WaitForPods assumes that app label is name, but we change this in WithPodLabels
92
				testserver.WithPodLabels(secondTestServerLabels),
93
			)).
94
			Install(testserver.Install(
95
				testserver.WithNamespace(namespace),
96
				testserver.WithName("test-server-third"),
97
				testserver.WithEchoArgs("echo", "--instance", "test-server-third"),
98
				testserver.WithoutService(),
99
				testserver.WithoutWaitingToBeReady(), // WaitForPods assumes that app label is name, but we change this in WithPodLabels
100
				testserver.WithPodLabels(thirdTestServerLabels),
101
			)).
102
			Install(YamlK8sObject(newSvc(firstTestServerLabels))).
103
			Setup(kubernetes.Cluster)
104
		Expect(err).To(Succeed())
105

106
		// remove retries to avoid covering failed request
107
		Expect(DeleteMeshPolicyOrError(
108
			kubernetes.Cluster,
109
			v1alpha1.MeshRetryResourceTypeDescriptor,
110
			fmt.Sprintf("mesh-retry-all-%s", mesh),
111
		)).To(Succeed())
112
	})
113

114
	E2EAfterAll(func() {
115
		Expect(kubernetes.Cluster.TriggerDeleteNamespace(namespace)).To(Succeed())
116
		Expect(kubernetes.Cluster.DeleteMesh(mesh)).To(Succeed())
117
	})
118

119
	doRequest := func() (string, error) {
120
		resp, err := client.CollectEchoResponse(
121
			kubernetes.Cluster,
122
			"demo-client",
123
			"test-server:80",
124
			client.FromKubernetesPod(namespace, "demo-client"),
125
		)
126
		return resp.Instance, err
127
	}
128

129
	It("should gracefully switch to other service", func() {
130
		// given traffic to the first server
131
		Eventually(func(g Gomega) {
132
			instance, err := doRequest()
133
			g.Expect(err).ToNot(HaveOccurred())
134
			g.Expect(instance).To(Equal("test-server-first"))
135
		}, "30s", "1s").Should(Succeed())
136

137
		// and constant traffic in the background
138
		var failedErr error
139
		closeCh := make(chan struct{})
140
		defer close(closeCh)
141
		go func() {
142
			for {
143
				if channels.IsClosed(closeCh) {
144
					return
145
				}
146
				if _, err := doRequest(); err != nil {
147
					failedErr = err
148
					return
149
				}
150
				// add a slight delay to not overwhelm completely the host running this test and leave more resources to other tests running in parallel.
151
				time.Sleep(50 * time.Millisecond)
152
			}
153
		}()
154

155
		// when
156
		err := kubernetes.Cluster.Install(YamlK8sObject(newSvc(secondTestServerLabels)))
157

158
		// then traffic shifted
159
		Expect(err).To(Succeed())
160
		Eventually(func(g Gomega) {
161
			instance, err := doRequest()
162
			g.Expect(err).ToNot(HaveOccurred())
163
			g.Expect(instance).To(Equal("test-server-second"))
164
		}, "30s", "1s").Should(Succeed())
165

166
		// and we did not drop a single request
167
		Expect(failedErr).ToNot(HaveOccurred())
168
	})
169

170
	It("should switch to the instance of a service that in not in the mesh", func() {
171
		// given
172
		Expect(kubernetes.Cluster.Install(YamlK8sObject(newSvc(firstTestServerLabels)))).To(Succeed())
173
		Eventually(func(g Gomega) {
174
			instance, err := doRequest()
175
			g.Expect(err).ToNot(HaveOccurred())
176
			g.Expect(instance).To(Equal("test-server-first"))
177
		}, "30s", "1s").Should(Succeed())
178

179
		// when
180
		err := kubernetes.Cluster.Install(YamlK8sObject(newSvc(thirdTestServerLabels)))
181

182
		// then
183
		Expect(err).To(Succeed())
184
		Eventually(func(g Gomega) {
185
			instance, err := doRequest()
186
			g.Expect(err).ToNot(HaveOccurred())
187
			g.Expect(instance).To(Equal("test-server-third"))
188
		}, "30s", "1s").Should(Succeed())
189
	})
190
}
191

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.