Files
higress/pkg/ingress/kube/gateway/istio/route_collections_test.go

141 lines
4.8 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 (
"strings"
"testing"
"time"
istio "istio.io/api/networking/v1alpha3"
"istio.io/istio/pkg/config"
"istio.io/istio/pkg/config/constants"
"istio.io/istio/pkg/config/gateway/kube"
"istio.io/istio/pkg/kube/krt"
"istio.io/istio/pkg/test"
)
func TestMergeHTTPRoutesMergesInferencePoolExtra(t *testing.T) {
stop := test.NewStop(t)
routeKey := "default/gateway/example.com"
baseRouteName := "default/local-ai-chat"
otherRouteName := "default/local-ai-chat-360m"
baseInferenceConfigs := map[string]kube.InferencePoolRouteRuleConfig{
baseRouteName: {
FQDN: "local-ai-chat-pool-epp.default.svc.cluster.local",
Port: "9002",
FailureModeAllow: true,
},
}
otherInferenceConfigs := map[string]kube.InferencePoolRouteRuleConfig{
otherRouteName: {
FQDN: "local-ai-chat-360m-pool-epp.default.svc.cluster.local",
Port: "9002",
},
}
baseCfg := &config.Config{
Meta: config.Meta{
Name: "local-ai-chat",
Namespace: "default",
CreationTimestamp: time.Unix(1, 0),
Annotations: map[string]string{
constants.InternalParentNames: "parent-a",
},
},
Spec: &istio.VirtualService{
Hosts: []string{"example.com"},
Gateways: []string{"default/gateway"},
Http: []*istio.HTTPRoute{{
Name: baseRouteName,
}},
},
Extra: map[string]any{
constants.ConfigExtraPerRouteRuleInferencePoolConfigs: baseInferenceConfigs,
"non-inference-extra": "kept-from-base",
},
}
otherCfg := &config.Config{
Meta: config.Meta{
Name: "local-ai-chat-360m",
Namespace: "default",
CreationTimestamp: time.Unix(2, 0),
Annotations: map[string]string{
constants.InternalParentNames: "parent-b",
},
},
Spec: &istio.VirtualService{
Hosts: []string{"example.com"},
Gateways: []string{"default/gateway"},
Http: []*istio.HTTPRoute{{
Name: otherRouteName,
}},
},
Extra: map[string]any{
constants.ConfigExtraPerRouteRuleInferencePoolConfigs: otherInferenceConfigs,
"non-inference-extra": "ignored-from-later-route",
"other-extra": "added-from-later-route",
},
}
baseVirtualServices := krt.NewStaticCollection[RouteWithKey](nil, []RouteWithKey{
{
Config: baseCfg,
Key: routeKey,
},
{
Config: otherCfg,
Key: routeKey,
},
}, krt.WithStop(stop), krt.WithName("base"))
merged := mergeHTTPRoutes(baseVirtualServices, krt.WithStop(stop), krt.WithName("merged"))
merged.WaitUntilSynced(stop)
gotList := merged.List()
if len(gotList) != 1 {
t.Fatalf("expected one merged VirtualService, got %d", len(gotList))
}
got := gotList[0]
if got.Name != strings.ReplaceAll(routeKey, "/", "~") {
t.Fatalf("expected merged VirtualService name %q, got %q", strings.ReplaceAll(routeKey, "/", "~"), got.Name)
}
gotVS := got.Spec.(*istio.VirtualService)
if len(gotVS.Http) != 2 {
t.Fatalf("expected merged VirtualService to contain 2 HTTP routes, got %d", len(gotVS.Http))
}
gotInferenceConfigs, ok := got.Extra[constants.ConfigExtraPerRouteRuleInferencePoolConfigs].(map[string]kube.InferencePoolRouteRuleConfig)
if !ok {
t.Fatalf("expected merged InferencePool configs, got %T", got.Extra[constants.ConfigExtraPerRouteRuleInferencePoolConfigs])
}
if len(gotInferenceConfigs) != 2 {
t.Fatalf("expected 2 merged InferencePool configs, got %d: %v", len(gotInferenceConfigs), gotInferenceConfigs)
}
if gotInferenceConfigs[baseRouteName].FQDN != baseInferenceConfigs[baseRouteName].FQDN {
t.Fatalf("expected base route InferencePool config to be preserved, got %v", gotInferenceConfigs[baseRouteName])
}
if gotInferenceConfigs[otherRouteName].FQDN != otherInferenceConfigs[otherRouteName].FQDN {
t.Fatalf("expected later route InferencePool config to be merged, got %v", gotInferenceConfigs[otherRouteName])
}
if got.Extra["non-inference-extra"] != "kept-from-base" {
t.Fatalf("expected non-InferencePool Extra to keep base value, got %v", got.Extra["non-inference-extra"])
}
if got.Extra["other-extra"] != "added-from-later-route" {
t.Fatalf("expected missing non-InferencePool Extra to be added, got %v", got.Extra["other-extra"])
}
if _, found := baseInferenceConfigs[otherRouteName]; found {
t.Fatalf("expected base InferencePool config map not to be mutated by merge")
}
}