kubernetes algorithm_test 源码
kubernetes algorithm_test 代码
文件路径:/staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/schema/pruning/algorithm_test.go
/*
Copyright 2019 The Kubernetes 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 pruning
import (
"bytes"
"reflect"
"strings"
"testing"
structuralschema "k8s.io/apiextensions-apiserver/pkg/apiserver/schema"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/json"
)
func TestPrune(t *testing.T) {
tests := []struct {
name string
json string
isResourceRoot bool
schema *structuralschema.Structural
expectedObject string
expectedPruned []string
}{
{name: "empty", json: "null", expectedObject: "null"},
{name: "scalar", json: "4", schema: &structuralschema.Structural{}, expectedObject: "4"},
{name: "scalar array", json: "[1,2]", schema: &structuralschema.Structural{
Items: &structuralschema.Structural{},
}, expectedObject: "[1,2]"},
{name: "object array", json: `[{"a":1},{"b":1},{"a":1,"b":2,"c":3}]`, schema: &structuralschema.Structural{
Items: &structuralschema.Structural{
Properties: map[string]structuralschema.Structural{
"a": {},
"c": {},
},
},
}, expectedObject: `[{"a":1},{},{"a":1,"c":3}]`, expectedPruned: []string{"[1].b", "[2].b"}},
{name: "object array with nil schema", json: `[{"a":1},{"b":1},{"a":1,"b":2,"c":3}]`, expectedObject: `[{},{},{}]`,
expectedPruned: []string{"[0].a", "[1].b", "[2].a", "[2].b", "[2].c"}},
{name: "object array object", json: `{"array":[{"a":1},{"b":1},{"a":1,"b":2,"c":3}],"unspecified":{"a":1},"specified":{"a":1,"b":2,"c":3}}`, schema: &structuralschema.Structural{
Properties: map[string]structuralschema.Structural{
"array": {
Items: &structuralschema.Structural{
Properties: map[string]structuralschema.Structural{
"a": {},
"c": {},
},
},
},
"specified": {
Properties: map[string]structuralschema.Structural{
"a": {},
"c": {},
},
},
},
}, expectedObject: `{"array":[{"a":1},{},{"a":1,"c":3}],"specified":{"a":1,"c":3}}`,
expectedPruned: []string{"array[1].b", "array[2].b", "specified.b", "unspecified"}},
{name: "nested x-kubernetes-preserve-unknown-fields", json: `
{
"unspecified":"bar",
"alpha": "abc",
"beta": 42.0,
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {
"unspecified": "bar",
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {"unspecified": "bar"},
"apiVersion": "unknown",
"preserving": {"unspecified": "bar"}
},
"preserving": {
"unspecified": "bar",
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {"unspecified": "bar"},
"preserving": {"unspecified": "bar"},
"preservingUnknownType": [{"foo":true},{"bar":true}]
},
"preservingAdditionalPropertiesNotInheritingXPreserveUnknownFields": {
"foo": {
"specified": {"unspecified":"bar"},
"unspecified": "bar"
}
},
"preservingAdditionalPropertiesKeyPruneValues": {
"foo": {
"specified": {"unspecified":"bar"},
"unspecified": "bar"
}
}
}
`, schema: &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
Properties: map[string]structuralschema.Structural{
"alpha": {Generic: structuralschema.Generic{Type: "string"}},
"beta": {Generic: structuralschema.Generic{Type: "number"}},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
Properties: map[string]structuralschema.Structural{
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
},
"preservingUnknownType": {
Generic: structuralschema.Generic{Type: ""},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
"preservingAdditionalPropertiesNotInheritingXPreserveUnknownFields": {
// this x-kubernetes-preserve-unknown-fields is not inherited by the schema inside of additionalProperties
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
Generic: structuralschema.Generic{
Type: "object",
AdditionalProperties: &structuralschema.StructuralOrBool{
Structural: &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"specified": {Generic: structuralschema.Generic{Type: "object"}},
},
},
},
},
},
"preservingAdditionalPropertiesKeyPruneValues": {
Generic: structuralschema.Generic{
Type: "object",
AdditionalProperties: &structuralschema.StructuralOrBool{
Structural: &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"specified": {Generic: structuralschema.Generic{Type: "object"}},
},
},
},
},
},
},
}, expectedObject: `
{
"unspecified":"bar",
"alpha": "abc",
"beta": 42.0,
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {
"pruning": {},
"preserving": {"unspecified": "bar"}
},
"preserving": {
"unspecified": "bar",
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {},
"preserving": {"unspecified": "bar"},
"preservingUnknownType": [{"foo":true},{"bar":true}]
},
"preservingAdditionalPropertiesNotInheritingXPreserveUnknownFields": {
"foo": {
"specified": {}
}
},
"preservingAdditionalPropertiesKeyPruneValues": {
"foo": {
"specified": {}
}
}
}
`, expectedPruned: []string{"preserving.pruning.unspecified", "preservingAdditionalPropertiesKeyPruneValues.foo.specified.unspecified", "preservingAdditionalPropertiesKeyPruneValues.foo.unspecified", "preservingAdditionalPropertiesNotInheritingXPreserveUnknownFields.foo.specified.unspecified", "preservingAdditionalPropertiesNotInheritingXPreserveUnknownFields.foo.unspecified", "pruning.apiVersion", "pruning.pruning.unspecified", "pruning.unspecified", "pruning.unspecifiedObject"}},
{name: "additionalProperties with schema", json: `{"a":1,"b":1,"c":{"a":1,"b":2,"c":{"a":1}}}`, schema: &structuralschema.Structural{
Properties: map[string]structuralschema.Structural{
"a": {},
"c": {
Generic: structuralschema.Generic{
AdditionalProperties: &structuralschema.StructuralOrBool{
Structural: &structuralschema.Structural{
Generic: structuralschema.Generic{
Type: "integer",
},
},
},
},
},
},
}, expectedObject: `{"a":1,"c":{"a":1,"b":2,"c":{}}}`,
expectedPruned: []string{"b", "c.c.a"}},
{name: "additionalProperties with bool", json: `{"a":1,"b":1,"c":{"a":1,"b":2,"c":{"a":1, "apiVersion": "unknown"}}}`, schema: &structuralschema.Structural{
Properties: map[string]structuralschema.Structural{
"a": {},
"c": {
Generic: structuralschema.Generic{
AdditionalProperties: &structuralschema.StructuralOrBool{
Bool: false,
},
},
},
},
}, expectedObject: `{"a":1,"c":{"a":1,"b":2,"c":{}}}`,
expectedPruned: []string{"b", "c.c.a", "c.c.apiVersion"}},
{name: "x-kubernetes-embedded-resource", json: `
{
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"unspecified":"bar",
"pruned": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"preserving": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"nested": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"unspecified": "bar",
"embedded": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
}
}
}
}
`, schema: &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"pruned": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"spec": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
XPreserveUnknownFields: true,
},
},
"nested": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"spec": {
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"embedded": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"spec": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
},
},
},
},
},
}, expectedObject: `
{
"pruned": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
}
},
"preserving": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"nested": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
"embedded": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"unspecified": "bar"
},
"spec": {
}
}
}
}
}
`, expectedPruned: []string{"nested.spec.embedded.spec.unspecified", "nested.spec.embedded.unspecified", "nested.spec.unspecified", "nested.unspecified", "pruned.spec.unspecified", "pruned.unspecified", "unspecified"}},
{name: "x-kubernetes-embedded-resource, with root=true", json: `
{
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels":{"foo":"bar"},
"unspecified": "bar"
},
"unspecified":"bar",
"pruned": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels":{"foo":"bar"},
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"preserving": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels":{"foo":"bar"},
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"nested": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels":{"foo":"bar"},
"unspecified": "bar"
},
"spec": {
"unspecified": "bar",
"embedded": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels":{"foo":"bar"},
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
}
}
}
}
`, isResourceRoot: true, schema: &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"metadata": {
Generic: structuralschema.Generic{Type: "object"},
},
"pruned": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"metadata": {
Generic: structuralschema.Generic{Type: "object"},
},
"spec": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
XPreserveUnknownFields: true,
},
},
"nested": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"spec": {
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"embedded": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{
XEmbeddedResource: true,
},
Properties: map[string]structuralschema.Structural{
"metadata": {
Generic: structuralschema.Generic{Type: "object"},
},
"spec": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
},
},
},
},
},
}, expectedObject: `
{
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels": {"foo": "bar"},
"unspecified": "bar"
},
"pruned": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels": {"foo": "bar"},
"unspecified": "bar"
},
"spec": {
}
},
"preserving": {
"apiVersion": "foo/v1",
"kind": "Foo",
"unspecified": "bar",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels": {"foo": "bar"},
"unspecified": "bar"
},
"spec": {
"unspecified": "bar"
}
},
"nested": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels": {"foo": "bar"},
"unspecified": "bar"
},
"spec": {
"embedded": {
"apiVersion": "foo/v1",
"kind": "Foo",
"metadata": {
"name": "instance",
"namespace": "myns",
"labels": {"foo": "bar"},
"unspecified": "bar"
},
"spec": {
}
}
}
}
}
`, expectedPruned: []string{"nested.spec.embedded.spec.unspecified", "nested.spec.embedded.unspecified", "nested.spec.unspecified", "nested.unspecified", "pruned.spec.unspecified", "pruned.unspecified", "unspecified"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var in interface{}
if err := json.Unmarshal([]byte(tt.json), &in); err != nil {
t.Fatal(err)
}
var expectedObject interface{}
if err := json.Unmarshal([]byte(tt.expectedObject), &expectedObject); err != nil {
t.Fatal(err)
}
pruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, structuralschema.UnknownFieldPathOptions{
TrackUnknownFieldPaths: true,
})
if !reflect.DeepEqual(in, expectedObject) {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetIndent("", " ")
err := enc.Encode(in)
if err != nil {
t.Fatalf("unexpected result mashalling error: %v", err)
}
t.Errorf("expected object: %s\ngot: %s\ndiff: %s", tt.expectedObject, buf.String(), diff.ObjectDiff(expectedObject, in))
}
if !reflect.DeepEqual(pruned, tt.expectedPruned) {
t.Errorf("expected pruned:\n\t%v\ngot:\n\t%v\n", strings.Join(tt.expectedPruned, "\n\t"), strings.Join(pruned, "\n\t"))
}
// now check that pruned is empty when TrackUnknownFieldPaths is false
emptyPruned := PruneWithOptions(in, tt.schema, tt.isResourceRoot, structuralschema.UnknownFieldPathOptions{})
if !reflect.DeepEqual(in, expectedObject) {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetIndent("", " ")
err := enc.Encode(in)
if err != nil {
t.Fatalf("unexpected result mashalling error: %v", err)
}
t.Errorf("expected object: %s\ngot: %s\ndiff: %s", tt.expectedObject, buf.String(), diff.ObjectDiff(expectedObject, in))
}
if len(emptyPruned) > 0 {
t.Errorf("unexpectedly returned pruned fields: %v", emptyPruned)
}
})
}
}
const smallInstance = `
{
"unspecified":"bar",
"alpha": "abc",
"beta": 42.0,
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {
"pruning": {},
"preserving": {"unspecified": "bar"}
},
"preserving": {
"unspecified": "bar",
"unspecifiedObject": {"unspecified": "bar"},
"pruning": {},
"preserving": {"unspecified": "bar"}
}
}
`
func BenchmarkPrune(b *testing.B) {
b.StopTimer()
b.ReportAllocs()
schema := &structuralschema.Structural{
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
Properties: map[string]structuralschema.Structural{
"alpha": {Generic: structuralschema.Generic{Type: "string"}},
"beta": {Generic: structuralschema.Generic{Type: "number"}},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
Properties: map[string]structuralschema.Structural{
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
Properties: map[string]structuralschema.Structural{
"preserving": {
Generic: structuralschema.Generic{Type: "object"},
Extensions: structuralschema.Extensions{XPreserveUnknownFields: true},
},
"pruning": {
Generic: structuralschema.Generic{Type: "object"},
},
},
},
},
}
var obj map[string]interface{}
err := json.Unmarshal([]byte(smallInstance), &obj)
if err != nil {
b.Fatal(err)
}
instances := make([]map[string]interface{}, 0, b.N)
for i := 0; i < b.N; i++ {
instances = append(instances, runtime.DeepCopyJSON(obj))
}
b.StartTimer()
for i := 0; i < b.N; i++ {
Prune(instances[i], schema, true)
}
}
func BenchmarkDeepCopy(b *testing.B) {
b.StopTimer()
b.ReportAllocs()
var obj map[string]interface{}
err := json.Unmarshal([]byte(smallInstance), &obj)
if err != nil {
b.Fatal(err)
}
instances := make([]map[string]interface{}, 0, b.N)
b.StartTimer()
for i := 0; i < b.N; i++ {
//nolint:staticcheck //iccheck // SA4010 the result of append is never used, it's acceptable since in benchmark testing.
instances = append(instances, runtime.DeepCopyJSON(obj))
}
}
func BenchmarkUnmarshal(b *testing.B) {
b.StopTimer()
b.ReportAllocs()
instances := make([]map[string]interface{}, b.N)
b.StartTimer()
for i := 0; i < b.N; i++ {
err := json.Unmarshal([]byte(smallInstance), &instances[i])
if err != nil {
b.Fatal(err)
}
}
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦