istio

Форк
0
/
controller_test.go 
431 строка · 10.1 Кб
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
package ingress
16

17
import (
18
	"testing"
19
	"time"
20

21
	corev1 "k8s.io/api/core/v1"
22
	net "k8s.io/api/networking/v1"
23
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24

25
	meshconfig "istio.io/api/mesh/v1alpha1"
26
	"istio.io/istio/pilot/pkg/model"
27
	kubecontroller "istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
28
	"istio.io/istio/pkg/config"
29
	"istio.io/istio/pkg/config/mesh"
30
	"istio.io/istio/pkg/config/schema/gvk"
31
	"istio.io/istio/pkg/kube"
32
	"istio.io/istio/pkg/kube/kclient/clienttest"
33
	"istio.io/istio/pkg/util/sets"
34
)
35

36
func newFakeController() (model.ConfigStoreController, kube.Client) {
37
	meshHolder := mesh.NewTestWatcher(&meshconfig.MeshConfig{
38
		IngressControllerMode: meshconfig.MeshConfig_DEFAULT,
39
	})
40
	fakeClient := kube.NewFakeClient()
41
	return NewController(fakeClient, meshHolder, kubecontroller.Options{}), fakeClient
42
}
43

44
func TestIngressController(t *testing.T) {
45
	ingress1 := net.Ingress{
46
		ObjectMeta: metav1.ObjectMeta{
47
			Namespace: "mock", // goes into backend full name
48
			Name:      "test",
49
		},
50
		Spec: net.IngressSpec{
51
			Rules: []net.IngressRule{
52
				{
53
					Host: "my.host.com",
54
					IngressRuleValue: net.IngressRuleValue{
55
						HTTP: &net.HTTPIngressRuleValue{
56
							Paths: []net.HTTPIngressPath{
57
								{
58
									Path: "/test",
59
									Backend: net.IngressBackend{
60
										Service: &net.IngressServiceBackend{
61
											Name: "foo",
62
											Port: net.ServiceBackendPort{
63
												Number: 8000,
64
											},
65
										},
66
									},
67
								},
68
							},
69
						},
70
					},
71
				},
72
				{
73
					Host: "my2.host.com",
74
					IngressRuleValue: net.IngressRuleValue{
75
						HTTP: &net.HTTPIngressRuleValue{
76
							Paths: []net.HTTPIngressPath{
77
								{
78
									Path: "/test1.*",
79
									Backend: net.IngressBackend{
80
										Service: &net.IngressServiceBackend{
81
											Name: "bar",
82
											Port: net.ServiceBackendPort{
83
												Number: 8000,
84
											},
85
										},
86
									},
87
								},
88
							},
89
						},
90
					},
91
				},
92
				{
93
					Host: "my3.host.com",
94
					IngressRuleValue: net.IngressRuleValue{
95
						HTTP: &net.HTTPIngressRuleValue{
96
							Paths: []net.HTTPIngressPath{
97
								{
98
									Path: "/test/*",
99
									Backend: net.IngressBackend{
100
										Service: &net.IngressServiceBackend{
101
											Name: "bar",
102
											Port: net.ServiceBackendPort{
103
												Number: 8000,
104
											},
105
										},
106
									},
107
								},
108
							},
109
						},
110
					},
111
				},
112
			},
113
		},
114
	}
115

116
	ingress2 := net.Ingress{
117
		ObjectMeta: metav1.ObjectMeta{
118
			Namespace: "mock",
119
			Name:      "test",
120
		},
121
		Spec: net.IngressSpec{
122
			Rules: []net.IngressRule{
123
				{
124
					Host: "my.host.com",
125
					IngressRuleValue: net.IngressRuleValue{
126
						HTTP: &net.HTTPIngressRuleValue{
127
							Paths: []net.HTTPIngressPath{
128
								{
129
									Path: "/test2",
130
									Backend: net.IngressBackend{
131
										Service: &net.IngressServiceBackend{
132
											Name: "foo",
133
											Port: net.ServiceBackendPort{
134
												Number: 8000,
135
											},
136
										},
137
									},
138
								},
139
							},
140
						},
141
					},
142
				},
143
			},
144
		},
145
	}
146

147
	controller, client := newFakeController()
148
	ingress := clienttest.NewWriter[*net.Ingress](t, client)
149
	configCh := make(chan config.Config)
150

151
	configHandler := func(_, curr config.Config, event model.Event) {
152
		configCh <- curr
153
	}
154

155
	wait := func() config.Config {
156
		select {
157
		case x := <-configCh:
158
			return x
159
		case <-time.After(time.Second * 10):
160
			t.Fatalf("timed out waiting for config")
161
		}
162
		return config.Config{}
163
	}
164

165
	controller.RegisterEventHandler(gvk.VirtualService, configHandler)
166
	stopCh := make(chan struct{})
167
	go controller.Run(stopCh)
168
	defer close(stopCh)
169

170
	client.RunAndWait(stopCh)
171

172
	ingress.Create(&ingress1)
173
	vs := wait()
174
	if vs.Name != ingress1.Name+"-"+"virtualservice" || vs.Namespace != ingress1.Namespace {
175
		t.Errorf("received unecpected config %v/%v", vs.Namespace, vs.Name)
176
	}
177
	ingress.Update(&ingress2)
178
	vs = wait()
179
	if vs.Name != ingress1.Name+"-"+"virtualservice" || vs.Namespace != ingress1.Namespace {
180
		t.Errorf("received unecpected config %v/%v", vs.Namespace, vs.Name)
181
	}
182
}
183

184
func TestIngressControllerWithPortName(t *testing.T) {
185
	ingressConfig := net.Ingress{
186
		ObjectMeta: metav1.ObjectMeta{
187
			Namespace: "mock",
188
			Name:      "test",
189
		},
190
		Spec: net.IngressSpec{
191
			Rules: []net.IngressRule{
192
				{
193
					Host: "my.host.com",
194
					IngressRuleValue: net.IngressRuleValue{
195
						HTTP: &net.HTTPIngressRuleValue{
196
							Paths: []net.HTTPIngressPath{
197
								{
198
									Path: "/foo",
199
									Backend: net.IngressBackend{
200
										Service: &net.IngressServiceBackend{
201
											Name: "foo",
202
											Port: net.ServiceBackendPort{
203
												Number: 8000,
204
											},
205
										},
206
									},
207
								},
208
							},
209
						},
210
					},
211
				},
212
				{
213
					Host: "my2.host.com",
214
					IngressRuleValue: net.IngressRuleValue{
215
						HTTP: &net.HTTPIngressRuleValue{
216
							Paths: []net.HTTPIngressPath{
217
								{
218
									Path: "/bar",
219
									Backend: net.IngressBackend{
220
										Service: &net.IngressServiceBackend{
221
											Name: "bar",
222
											Port: net.ServiceBackendPort{
223
												Name: "http",
224
											},
225
										},
226
									},
227
								},
228
							},
229
						},
230
					},
231
				},
232
			},
233
		},
234
	}
235

236
	serviceConfig := corev1.Service{
237
		ObjectMeta: metav1.ObjectMeta{
238
			Namespace: "mock",
239
			Name:      "bar",
240
		},
241
		Spec: corev1.ServiceSpec{
242
			Ports: []corev1.ServicePort{
243
				{
244
					Name: "http",
245
					Port: 8080,
246
				},
247
			},
248
		},
249
	}
250

251
	controller, client := newFakeController()
252
	ingress := clienttest.NewWriter[*net.Ingress](t, client)
253
	service := clienttest.NewWriter[*corev1.Service](t, client)
254
	configCh := make(chan config.Config)
255

256
	configHandler := func(_, curr config.Config, event model.Event) {
257
		configCh <- curr
258
	}
259

260
	wait := func() config.Config {
261
		select {
262
		case x := <-configCh:
263
			return x
264
		case <-time.After(time.Second * 10):
265
			t.Fatalf("timed out waiting for config")
266
		}
267
		return config.Config{}
268
	}
269

270
	controller.RegisterEventHandler(gvk.VirtualService, configHandler)
271
	stopCh := make(chan struct{})
272
	go controller.Run(stopCh)
273
	defer close(stopCh)
274

275
	client.RunAndWait(stopCh)
276

277
	// First create ingress.
278
	ingress.Create(&ingressConfig)
279
	vs := wait()
280
	if vs.Name != ingressConfig.Name+"-"+"virtualservice" || vs.Namespace != ingressConfig.Namespace {
281
		t.Errorf("received unecpected config %v/%v", vs.Namespace, vs.Name)
282
	}
283

284
	// Then we create service.
285
	service.Create(&serviceConfig)
286
	vs = wait()
287
	if vs.Name != ingressConfig.Name+"-"+"virtualservice" || vs.Namespace != ingressConfig.Namespace {
288
		t.Errorf("received unecpected config %v/%v", vs.Namespace, vs.Name)
289
	}
290

291
	// We change service port number.
292
	serviceConfig.Spec.Ports[0].Port = 8090
293
	service.Update(&serviceConfig)
294
	vs = wait()
295
	if vs.Name != ingressConfig.Name+"-"+"virtualservice" || vs.Namespace != ingressConfig.Namespace {
296
		t.Errorf("received unecpected config %v/%v", vs.Namespace, vs.Name)
297
	}
298
}
299

300
func TestExtractServicesByPortNameType(t *testing.T) {
301
	testCases := []struct {
302
		name   string
303
		input  net.Ingress
304
		expect sets.String
305
	}{
306
		{
307
			name: "has no port name",
308
			input: net.Ingress{
309
				ObjectMeta: metav1.ObjectMeta{
310
					Namespace: "ingress",
311
					Name:      "test",
312
				},
313
				Spec: net.IngressSpec{
314
					Rules: []net.IngressRule{
315
						{
316
							Host: "my.host.com",
317
							IngressRuleValue: net.IngressRuleValue{
318
								HTTP: &net.HTTPIngressRuleValue{
319
									Paths: []net.HTTPIngressPath{
320
										{
321
											Path: "/test",
322
											Backend: net.IngressBackend{
323
												Service: &net.IngressServiceBackend{
324
													Name: "foo",
325
													Port: net.ServiceBackendPort{
326
														Number: 8000,
327
													},
328
												},
329
											},
330
										},
331
									},
332
								},
333
							},
334
						},
335
					},
336
				},
337
			},
338
			expect: nil,
339
		},
340
		{
341
			name: "has no port name",
342
			input: net.Ingress{
343
				ObjectMeta: metav1.ObjectMeta{
344
					Namespace: "ingress",
345
					Name:      "test",
346
				},
347
				Spec: net.IngressSpec{
348
					Rules: []net.IngressRule{
349
						{
350
							Host: "my.host.com",
351
							IngressRuleValue: net.IngressRuleValue{
352
								HTTP: &net.HTTPIngressRuleValue{
353
									Paths: []net.HTTPIngressPath{
354
										{
355
											Path: "/test",
356
											Backend: net.IngressBackend{
357
												Service: &net.IngressServiceBackend{
358
													Name: "foo",
359
													Port: net.ServiceBackendPort{
360
														Number: 8000,
361
													},
362
												},
363
											},
364
										},
365
										{
366
											Path: "/bar",
367
											Backend: net.IngressBackend{
368
												Service: &net.IngressServiceBackend{
369
													Name: "bar",
370
													Port: net.ServiceBackendPort{
371
														Name: "http",
372
													},
373
												},
374
											},
375
										},
376
									},
377
								},
378
							},
379
						},
380
						{
381
							Host: "my1.host.com",
382
							IngressRuleValue: net.IngressRuleValue{
383
								HTTP: &net.HTTPIngressRuleValue{
384
									Paths: []net.HTTPIngressPath{
385
										{
386
											Path: "/mock",
387
											Backend: net.IngressBackend{
388
												Service: &net.IngressServiceBackend{
389
													Name: "mock",
390
													Port: net.ServiceBackendPort{
391
														Name: "grpc",
392
													},
393
												},
394
											},
395
										},
396
									},
397
								},
398
							},
399
						},
400
					},
401
				},
402
			},
403
			expect: sets.String{}.InsertAll("ingress/bar", "ingress/mock"),
404
		},
405
	}
406

407
	for _, testCase := range testCases {
408
		t.Run(testCase.name, func(t *testing.T) {
409
			if !testCase.expect.Equals(extractServicesByPortNameType(&testCase.input)) {
410
				t.Fatal("should be equal.")
411
			}
412
		})
413
	}
414
}
415

416
func TestExtractPorts(t *testing.T) {
417
	ports := []corev1.ServicePort{
418
		{
419
			Port: 80,
420
		},
421
		{
422
			Name: "http",
423
			Port: 8080,
424
		},
425
	}
426

427
	expect := sets.New("80|", "8080|http")
428
	if !expect.Equals(extractPorts(ports)) {
429
		t.Fatal("should be equal")
430
	}
431
}
432

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

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

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

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