istio
128 строк · 4.4 Кб
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 distribution
16
17import (
18"testing"
19"time"
20
21. "github.com/onsi/gomega"
22"k8s.io/utils/clock"
23
24"istio.io/istio/pilot/pkg/status"
25"istio.io/istio/pilot/pkg/xds"
26"istio.io/istio/pkg/config"
27"istio.io/istio/pkg/config/schema/collections"
28"istio.io/istio/pkg/ledger"
29"istio.io/istio/pkg/util/sets"
30)
31
32func TestStatusMaps(t *testing.T) {
33r := initReporterWithoutStarting()
34typ := ""
35r.processEvent("conA", typ, "a")
36r.processEvent("conB", typ, "a")
37r.processEvent("conC", typ, "c")
38r.processEvent("conD", typ, "d")
39RegisterTestingT(t)
40x := struct{}{}
41Expect(r.status).To(Equal(map[string]string{"conA~": "a", "conB~": "a", "conC~": "c", "conD~": "d"}))
42Expect(r.reverseStatus).To(Equal(map[string]sets.String{"a": {"conA~": x, "conB~": x}, "c": {"conC~": x}, "d": {"conD~": x}}))
43r.processEvent("conA", typ, "d")
44Expect(r.status).To(Equal(map[string]string{"conA~": "d", "conB~": "a", "conC~": "c", "conD~": "d"}))
45Expect(r.reverseStatus).To(Equal(map[string]sets.String{"a": {"conB~": x}, "c": {"conC~": x}, "d": {"conD~": x, "conA~": x}}))
46r.RegisterDisconnect("conA", sets.New[xds.EventType](typ))
47Expect(r.status).To(Equal(map[string]string{"conB~": "a", "conC~": "c", "conD~": "d"}))
48Expect(r.reverseStatus).To(Equal(map[string]sets.String{"a": {"conB~": x}, "c": {"conC~": x}, "d": {"conD~": x}}))
49}
50
51func initReporterWithoutStarting() (out Reporter) {
52out.PodName = "tespod"
53out.inProgressResources = map[string]*inProgressEntry{}
54out.client = nil // TODO
55out.clock = clock.RealClock{} // TODO
56out.UpdateInterval = 300 * time.Millisecond
57out.cm = nil // TODO
58out.reverseStatus = make(map[string]sets.String)
59out.status = make(map[string]string)
60return
61}
62
63func TestBuildReport(t *testing.T) {
64RegisterTestingT(t)
65r := initReporterWithoutStarting()
66r.ledger = ledger.Make(time.Minute)
67resources := []*config.Config{
68{
69Meta: config.Meta{
70Namespace: "default",
71Name: "foo",
72ResourceVersion: "1",
73},
74},
75{
76Meta: config.Meta{
77Namespace: "default",
78Name: "bar",
79ResourceVersion: "1",
80},
81},
82{
83Meta: config.Meta{
84Namespace: "alternate",
85Name: "boo",
86ResourceVersion: "1",
87},
88},
89}
90// cast our model.Configs to Resource because these types aren't compatible
91var myResources []status.Resource
92col := collections.VirtualService
93for _, res := range resources {
94// Set Group Version and GroupVersionKind to real world values from VS
95res.GroupVersionKind = col.GroupVersionKind()
96myResources = append(myResources, status.ResourceFromModelConfig(*res))
97// Add each resource to our ledger for tracking history
98// mark each of our resources as in flight so they are included in the report.
99r.AddInProgressResource(*res)
100}
101firstNoncePrefix := r.ledger.RootHash()
102connections := []string{
103"conA", "conB", "conC",
104}
105// mark each fake connection as having acked version 1 of all resources
106for _, con := range connections {
107r.processEvent(con, "", firstNoncePrefix)
108}
109// modify one resource to version 2
110resources[1].Generation = int64(2)
111myResources[1].Generation = "2"
112// notify the ledger of the new version
113r.AddInProgressResource(*resources[1])
114// mark only one connection as having acked version 2
115r.processEvent(connections[1], "", r.ledger.RootHash())
116// mark one connection as having disconnected.
117r.RegisterDisconnect(connections[2], sets.New[xds.EventType](""))
118// build a report, which should have only two dataplanes, with 50% acking v2 of config
119rpt, prunes := r.buildReport()
120r.removeCompletedResource(prunes)
121Expect(rpt.DataPlaneCount).To(Equal(2))
122Expect(rpt.InProgressResources).To(Equal(map[string]int{
123myResources[0].String(): 2,
124myResources[1].String(): 1,
125myResources[2].String(): 2,
126}))
127Expect(r.inProgressResources).NotTo(ContainElement(resources[0]))
128}
129