Files
higress/pkg/ingress/kube/gateway/istio/status_test.go
2025-11-20 14:43:30 +08:00

107 lines
3.1 KiB
Go

// Copyright Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package istio
import (
"testing"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"istio.io/istio/pilot/pkg/networking/core"
"istio.io/istio/pilot/pkg/serviceregistry/kube/controller"
"istio.io/istio/pilot/pkg/status"
"istio.io/istio/pkg/kube"
"istio.io/istio/pkg/kube/krt"
"istio.io/istio/pkg/slices"
"istio.io/istio/pkg/test"
"istio.io/istio/pkg/test/util/assert"
)
func TestStatusCollections(t *testing.T) {
stop := test.NewStop(t)
fetch := func(q *TestStatusQueue) []string {
return slices.Sort(slices.Map(q.Statuses(), func(e any) string {
return *(e.(*string))
}))
}
type Status = krt.ObjectWithStatus[*v1.ConfigMap, string]
c := setupControllerWithoutGatewayClasses(t)
obj1 := Status{
Obj: &v1.ConfigMap{},
Status: "hello world",
}
fakeCol := krt.NewStaticCollection[Status](nil, []Status{obj1}, krt.WithStop(stop))
status.RegisterStatus(c.status, fakeCol, func(i *v1.ConfigMap) string {
return ""
})
sq1 := &TestStatusQueue{state: map[status.Resource]any{}}
setAndWait(t, c, sq1)
assert.Equal(t, fetch(sq1), []string{"hello world"})
c.status.UnsetQueue()
// We should not get an update on the un-registered queue
fakeCol.UpdateObject(Status{
Obj: &v1.ConfigMap{},
Status: "hello world2",
})
assert.Equal(t, fetch(sq1), []string{"hello world"})
// New queue should send new events, including existing state
sq2 := &TestStatusQueue{state: map[status.Resource]any{}}
setAndWait(t, c, sq2)
assert.Equal(t, fetch(sq2), []string{"hello world2"})
// And any new state
fakeCol.UpdateObject(Status{
Obj: &v1.ConfigMap{},
Status: "hello world3",
})
// New event, so this is eventually consistent
assert.EventuallyEqual(t, func() []string {
return fetch(sq2)
}, []string{"hello world3"})
}
func setAndWait(t test.Failer, c *Controller, q status.Queue) {
stop := test.NewStop(t)
for _, syncer := range c.status.SetQueue(q) {
syncer.WaitUntilSynced(stop)
}
}
func setupControllerWithoutGatewayClasses(t *testing.T, objs ...runtime.Object) *Controller {
kc := kube.NewFakeClient(objs...)
setupClientCRDs(t, kc)
stop := test.NewStop(t)
controller := NewController(
kc,
func(class schema.GroupVersionResource, stop <-chan struct{}) bool {
return false
},
controller.Options{KrtDebugger: krt.GlobalDebugHandler},
nil)
kc.RunAndWait(stop)
go controller.Run(stop)
cg := core.NewConfigGenTest(t, core.TestOptions{})
controller.Reconcile(cg.PushContext())
kube.WaitForCacheSync("test", stop, controller.HasSynced)
return controller
}