istio
156 строк · 4.5 Кб
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
15package controller
16
17import (
18"reflect"
19"testing"
20"time"
21
22corev1 "k8s.io/api/core/v1"
23mcs "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"
24
25"istio.io/api/label"
26"istio.io/istio/pilot/pkg/model"
27"istio.io/istio/pilot/pkg/serviceregistry/kube"
28"istio.io/istio/pkg/config/host"
29"istio.io/istio/pkg/test/util/assert"
30)
31
32func TestEndpointSliceFromMCSShouldBeIgnored(t *testing.T) {
33const (
34ns = "nsa"
35svcName = "svc1"
36appName = "prod-app"
37)
38
39controller, fx := NewFakeControllerWithOptions(t, FakeControllerOptions{})
40
41node := generateNode("node1", map[string]string{
42NodeZoneLabel: "zone1",
43NodeRegionLabel: "region1",
44label.TopologySubzone.Name: "subzone1",
45})
46addNodes(t, controller, node)
47
48pod := generatePod("128.0.0.1", "pod1", ns, "svcaccount", "node1",
49map[string]string{"app": appName}, map[string]string{})
50pods := []*corev1.Pod{pod}
51addPods(t, controller, fx, pods...)
52
53createServiceWait(controller, svcName, ns, nil, nil,
54[]int32{8080}, map[string]string{"app": appName}, t)
55
56// Ensure that the service is available.
57hostname := kube.ServiceHostname(svcName, ns, controller.opts.DomainSuffix)
58svc := controller.GetService(hostname)
59if svc == nil {
60t.Fatal("failed to get service")
61}
62
63// Create an endpoint that indicates it's an MCS endpoint for the service.
64svc1Ips := []string{"128.0.0.1"}
65portNames := []string{"tcp-port"}
66createEndpoints(t, controller, svcName, ns, portNames, svc1Ips, nil, map[string]string{
67mcs.LabelServiceName: svcName,
68})
69fx.AssertEmpty(t, time.Millisecond*50)
70
71// Ensure that no endpoint is create
72endpoints := GetEndpoints(svc, controller.Endpoints)
73assert.Equal(t, len(endpoints), 0)
74}
75
76func TestEndpointSliceCache(t *testing.T) {
77cache := newEndpointSliceCache()
78hostname := host.Name("foo")
79
80// add a endpoint
81ep1 := &model.IstioEndpoint{
82Address: "1.2.3.4",
83ServicePortName: "http",
84}
85cache.Update(hostname, "slice1", []*model.IstioEndpoint{ep1})
86if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep1}) {
87t.Fatalf("unexpected endpoints")
88}
89if !cache.Has(hostname) {
90t.Fatalf("expect to find the host name")
91}
92// add a new endpoint
93ep2 := &model.IstioEndpoint{
94Address: "2.3.4.5",
95ServicePortName: "http",
96}
97cache.Update(hostname, "slice1", []*model.IstioEndpoint{ep1, ep2})
98if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep1, ep2}) {
99t.Fatalf("unexpected endpoints")
100}
101
102// change service port name
103ep1 = &model.IstioEndpoint{
104Address: "1.2.3.4",
105ServicePortName: "http2",
106}
107ep2 = &model.IstioEndpoint{
108Address: "2.3.4.5",
109ServicePortName: "http2",
110}
111cache.Update(hostname, "slice1", []*model.IstioEndpoint{ep1, ep2})
112if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep1, ep2}) {
113t.Fatalf("unexpected endpoints")
114}
115
116// add a new slice
117ep3 := &model.IstioEndpoint{
118Address: "3.4.5.6",
119ServicePortName: "http2",
120}
121cache.Update(hostname, "slice2", []*model.IstioEndpoint{ep3})
122if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep1, ep2, ep3}) {
123t.Fatalf("unexpected endpoints")
124}
125
126// dedup when transitioning
127cache.Update(hostname, "slice2", []*model.IstioEndpoint{ep2, ep3})
128if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep1, ep2, ep3}) {
129t.Fatalf("unexpected endpoints")
130}
131
132cache.Delete(hostname, "slice1")
133if !testEndpointsEqual(cache.Get(hostname), []*model.IstioEndpoint{ep2, ep3}) {
134t.Fatalf("unexpected endpoints")
135}
136
137cache.Delete(hostname, "slice2")
138if cache.Get(hostname) != nil {
139t.Fatalf("unexpected endpoints")
140}
141}
142
143func testEndpointsEqual(a, b []*model.IstioEndpoint) bool {
144if len(a) != len(b) {
145return false
146}
147m1 := make(map[endpointKey]int)
148m2 := make(map[endpointKey]int)
149for _, i := range a {
150m1[endpointKey{i.Address, i.ServicePortName}]++
151}
152for _, i := range b {
153m2[endpointKey{i.Address, i.ServicePortName}]++
154}
155return reflect.DeepEqual(m1, m2)
156}
157