mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Add cost stability tests for chained and nested CEL comprehensions
This commit is contained in:
parent
d49949b642
commit
31f7efab20
@ -25,6 +25,7 @@ import (
|
||||
"k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
celconfig "k8s.io/apiserver/pkg/apis/cel"
|
||||
"k8s.io/utils/ptr"
|
||||
)
|
||||
|
||||
func TestCelCostStability(t *testing.T) {
|
||||
@ -1093,6 +1094,20 @@ func TestCelCostStability(t *testing.T) {
|
||||
"self.listOfMap[0]['z'] == 'g'": 5,
|
||||
"self.listOfObj[0].field3 == 'h'": 5,
|
||||
"self.listOfListMap[0].exists(e, e.k3 == '3' && e.v3 == 'i')": 14,
|
||||
|
||||
// chained comprehensions
|
||||
"self.mapOfMap.map(k, k).map(k, k).size() == 1": 32,
|
||||
"self.mapOfListMap.map(k, k).map(k, k).size() == 1": 32,
|
||||
"self.mapOfList.map(k, k).map(k, k).size() == 1": 32,
|
||||
"self.listOfMap.map(e, e).map(e, e).size() == 1": 32,
|
||||
"self.listOfListMap.map(e, e).map(e, e).size() == 1": 32,
|
||||
|
||||
// nested comprehensions
|
||||
"self.mapOfMap.map(k, self.mapOfMap[k].map(m, m)).size() == 1": 34,
|
||||
"self.mapOfListMap.map(k, self.mapOfListMap[k].map(m, m)).size() == 1": 34,
|
||||
"self.mapOfList.map(k, self.mapOfList[k].map(l, l)).size() == 1": 34,
|
||||
"self.listOfMap.map(e, e.map(m, m)).size() == 1": 32,
|
||||
"self.listOfListMap.map(e, e.map(e, e)).size() == 1": 32,
|
||||
},
|
||||
},
|
||||
{name: "optionals",
|
||||
@ -1520,7 +1535,7 @@ func TestCelEstimatedCostStability(t *testing.T) {
|
||||
"!self.listMap.exists_one(m, m.k.startsWith('a'))": 5242880,
|
||||
"size(self.listMap.filter(m, m.k == 'a1')) == 1": 16777215,
|
||||
"self.listMap.exists(m, m.k == 'a1' && m.v == 'b1')": 10485753,
|
||||
"self.listMap.map(m, m.v).exists(v, v == 'b1')": uint64(18446744073709551615),
|
||||
"self.listMap.map(m, m.v).exists(v, v == 'b1')": uint64(19922939),
|
||||
|
||||
// test comprehensions where the field used in predicates is unset on all but one of the elements:
|
||||
// - with has checks:
|
||||
@ -1531,7 +1546,7 @@ func TestCelEstimatedCostStability(t *testing.T) {
|
||||
"self.listMap.filter(m, has(m.v2) && m.v2 == 'z').size() == 1": 17825790,
|
||||
// undocumented overload of map that takes a filter argument. This is the same as .filter().map()
|
||||
"self.listMap.map(m, has(m.v2) && m.v2 == 'z', m.v2).size() == 1": 18874365,
|
||||
"self.listMap.filter(m, has(m.v2) && m.v2 == 'z').map(m, m.v2).size() == 1": uint64(18446744073709551615),
|
||||
"self.listMap.filter(m, has(m.v2) && m.v2 == 'z').map(m, m.v2).size() == 1": uint64(32505851),
|
||||
// - without has checks:
|
||||
|
||||
// all() and exists() macros ignore errors from predicates so long as the condition holds for at least one element
|
||||
@ -1553,7 +1568,7 @@ func TestCelEstimatedCostStability(t *testing.T) {
|
||||
"!self.array.exists_one(e, e == 2)": 4718594,
|
||||
"self.array.all(e, e < 100)": 7864318,
|
||||
"size(self.array.filter(e, e%2 == 0)) == 3": 25165823,
|
||||
"self.array.map(e, e * 20).filter(e, e > 50).exists(e, e == 60)": uint64(18446744073709551615),
|
||||
"self.array.map(e, e * 20).filter(e, e > 50).exists(e, e == 60)": uint64(53477367),
|
||||
"size(self.array) == 8": 4,
|
||||
},
|
||||
},
|
||||
@ -1571,7 +1586,7 @@ func TestCelEstimatedCostStability(t *testing.T) {
|
||||
"!self.set.exists_one(e, e > 3)": 6291457,
|
||||
"self.set.all(e, e < 10)": 7864318,
|
||||
"size(self.set.filter(e, e%2 == 0)) == 2": 25165823,
|
||||
"self.set.map(e, e * 20).filter(e, e > 50).exists_one(e, e == 60)": uint64(18446744073709551615),
|
||||
"self.set.map(e, e * 20).filter(e, e > 50).exists_one(e, e == 60)": uint64(50331642),
|
||||
"size(self.set) == 5": 4,
|
||||
},
|
||||
},
|
||||
@ -1901,38 +1916,65 @@ func TestCelEstimatedCostStability(t *testing.T) {
|
||||
"obj": objectType(map[string]schema.Structural{
|
||||
"field": stringType,
|
||||
}),
|
||||
"mapOfMap": mapType(mapTypePtr(&stringType)),
|
||||
"mapOfMap": withMaxProperties(mapType(ptr.To(
|
||||
withMaxProperties(mapType(&stringType), ptr.To[int64](10)))), ptr.To[int64](10)),
|
||||
"mapOfObj": mapType(objectTypePtr(map[string]schema.Structural{
|
||||
"field2": stringType,
|
||||
})),
|
||||
"mapOfListMap": mapType(listMapTypePtr([]string{"k"}, objectTypePtr(map[string]schema.Structural{
|
||||
"k": stringType,
|
||||
"v": stringType,
|
||||
}))),
|
||||
"mapOfList": mapType(listTypePtr(&stringType)),
|
||||
"listMapOfObj": listMapType([]string{"k2"}, objectTypePtr(map[string]schema.Structural{
|
||||
"mapOfListMap": withMaxProperties(mapType(
|
||||
ptr.To(withMaxItems(listMapType([]string{"k"},
|
||||
objectTypePtr(map[string]schema.Structural{
|
||||
"k": stringType,
|
||||
"v": stringType,
|
||||
}),
|
||||
), ptr.To[int64](10))),
|
||||
), ptr.To[int64](10)),
|
||||
"mapOfList": withMaxProperties(mapType(
|
||||
ptr.To(withMaxItems(listType(&stringType), ptr.To[int64](10))),
|
||||
), ptr.To[int64](10)),
|
||||
"listMapOfObj": withMaxItems(listMapType([]string{"k2"}, objectTypePtr(map[string]schema.Structural{
|
||||
"k2": stringType,
|
||||
"v2": stringType,
|
||||
})),
|
||||
"listOfMap": listType(mapTypePtr(&stringType)),
|
||||
})), ptr.To[int64](10)),
|
||||
"listOfMap": withMaxItems(listType(
|
||||
ptr.To(withMaxProperties(mapType(&stringType), ptr.To[int64](10))),
|
||||
), ptr.To[int64](10)),
|
||||
"listOfObj": listType(objectTypePtr(map[string]schema.Structural{
|
||||
"field3": stringType,
|
||||
})),
|
||||
"listOfListMap": listType(listMapTypePtr([]string{"k3"}, objectTypePtr(map[string]schema.Structural{
|
||||
"k3": stringType,
|
||||
"v3": stringType,
|
||||
}))),
|
||||
"listOfListMap": withMaxItems(listType(
|
||||
ptr.To(withMaxItems(listMapType([]string{"k"},
|
||||
objectTypePtr(map[string]schema.Structural{
|
||||
"k3": stringType,
|
||||
"v3": stringType,
|
||||
}),
|
||||
), ptr.To[int64](10))),
|
||||
), ptr.To[int64](10)),
|
||||
}),
|
||||
expectCost: map[string]uint64{
|
||||
"self.obj.field == 'a'": 4,
|
||||
"self.mapOfMap['x']['y'] == 'b'": 5,
|
||||
"self.mapOfObj['k'].field2 == 'c'": 5,
|
||||
"self.mapOfListMap['o'].exists(e, e.k == '1' && e.v == 'd')": 10485754,
|
||||
"self.mapOfListMap['o'].exists(e, e.k == '1' && e.v == 'd')": 104,
|
||||
"self.mapOfList['l'][0] == 'e'": 5,
|
||||
"self.listMapOfObj.exists(e, e.k2 == '2' && e.v2 == 'f')": 10485753,
|
||||
"self.listMapOfObj.exists(e, e.k2 == '2' && e.v2 == 'f')": 103,
|
||||
"self.listOfMap[0]['z'] == 'g'": 5,
|
||||
"self.listOfObj[0].field3 == 'h'": 5,
|
||||
"self.listOfListMap[0].exists(e, e.k3 == '3' && e.v3 == 'i')": 10485754,
|
||||
"self.listOfListMap[0].exists(e, e.k3 == '3' && e.v3 == 'i')": 104,
|
||||
|
||||
// chained comprehensions
|
||||
"self.mapOfMap.map(k, k).map(k, k).size() == 1": 286,
|
||||
"self.mapOfListMap.map(k, k).map(k, k).size() == 1": 286,
|
||||
"self.mapOfList.map(k, k).map(k, k).size() == 1": 286,
|
||||
"self.listOfMap.map(e, e).map(e, e).size() == 1": 286,
|
||||
"self.listOfListMap.map(e, e).map(e, e).size() == 1": 286,
|
||||
|
||||
// nested comprehensions
|
||||
"self.mapOfMap.map(k, self.mapOfMap[k].map(m, m)).size() == 1": 1585,
|
||||
"self.mapOfListMap.map(k, self.mapOfListMap[k].map(m, m)).size() == 1": 1585,
|
||||
"self.mapOfList.map(k, self.mapOfList[k].map(l, l)).size() == 1": 1585,
|
||||
"self.listOfMap.map(e, e.map(m, m)).size() == 1": 1555,
|
||||
"self.listOfListMap.map(e, e.map(e, e)).size() == 1": 1555,
|
||||
},
|
||||
},
|
||||
{name: "optionals",
|
||||
|
@ -4569,6 +4569,14 @@ func withMaxItems(s schema.Structural, maxItems *int64) schema.Structural {
|
||||
return s
|
||||
}
|
||||
|
||||
func withMaxProperties(s schema.Structural, maxProperties *int64) schema.Structural {
|
||||
if s.ValueValidation == nil {
|
||||
s.ValueValidation = &schema.ValueValidation{}
|
||||
}
|
||||
s.ValueValidation.MaxProperties = maxProperties
|
||||
return s
|
||||
}
|
||||
|
||||
func withDefault(dflt interface{}, s schema.Structural) schema.Structural {
|
||||
s.Generic.Default = schema.JSON{Object: dflt}
|
||||
return s
|
||||
|
Loading…
Reference in New Issue
Block a user