mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
Implement support for CacheableObject
This commit is contained in:
parent
1dd43724ce
commit
970f103e2c
@ -21,6 +21,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
|
@ -352,7 +352,14 @@ func (s unstructuredJSONScheme) Decode(data []byte, _ *schema.GroupVersionKind,
|
||||
return obj, &gvk, nil
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) Encode(obj runtime.Object, w io.Writer) error {
|
||||
func (s unstructuredJSONScheme) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(s.Identifier(), s.doEncode, w)
|
||||
}
|
||||
return s.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (unstructuredJSONScheme) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
switch t := obj.(type) {
|
||||
case *Unstructured:
|
||||
return json.NewEncoder(w).Encode(t.Object)
|
||||
|
@ -21,6 +21,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -159,3 +161,7 @@ func TestNestedFieldCopy(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
assert.Nil(t, res)
|
||||
}
|
||||
|
||||
func TestCacheableObject(t *testing.T) {
|
||||
runtimetesting.CacheableObjectTest(t, UnstructuredJSONScheme)
|
||||
}
|
||||
|
@ -107,6 +107,8 @@ var _ Serializer = NoopEncoder{}
|
||||
const noopEncoderIdentifier Identifier = "noop"
|
||||
|
||||
func (n NoopEncoder) Encode(obj Object, w io.Writer) error {
|
||||
// There is no need to handle runtime.CacheableObject, as we don't
|
||||
// process the obj at all.
|
||||
return fmt.Errorf("encoding is not allowed for this codec: %v", reflect.TypeOf(n.Decoder))
|
||||
}
|
||||
|
||||
@ -231,6 +233,13 @@ func identifier(e Encoder) Identifier {
|
||||
}
|
||||
|
||||
func (s base64Serializer) Encode(obj Object, stream io.Writer) error {
|
||||
if co, ok := obj.(CacheableObject); ok {
|
||||
return co.CacheEncode(s.Identifier(), s.doEncode, stream)
|
||||
}
|
||||
return s.doEncode(obj, stream)
|
||||
}
|
||||
|
||||
func (s base64Serializer) doEncode(obj Object, stream io.Writer) error {
|
||||
e := base64.NewEncoder(base64.StdEncoding, stream)
|
||||
err := s.Encoder.Encode(obj, e)
|
||||
e.Close()
|
||||
|
@ -14,12 +14,15 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
)
|
||||
|
||||
func gv(group, version string) schema.GroupVersion {
|
||||
@ -69,7 +72,7 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
v := NewCoercingMultiGroupVersioner(tc.target, tc.preferredKinds...)
|
||||
v := runtime.NewCoercingMultiGroupVersioner(tc.target, tc.preferredKinds...)
|
||||
kind, ok := v.KindForGroupVersionKinds(tc.kinds)
|
||||
if !ok {
|
||||
t.Error("got no kind")
|
||||
@ -83,3 +86,19 @@ func TestCoercingMultiGroupVersioner(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type mockEncoder struct{}
|
||||
|
||||
func (m *mockEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
_, err := w.Write([]byte("mock-result"))
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *mockEncoder) Identifier() runtime.Identifier {
|
||||
return runtime.Identifier("mock-identifier")
|
||||
}
|
||||
|
||||
func TestCacheableObject(t *testing.T) {
|
||||
serializer := runtime.NewBase64Serializer(&mockEncoder{}, nil)
|
||||
runtimetesting.CacheableObjectTest(t, serializer)
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ go_test(
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -304,6 +304,13 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
|
||||
|
||||
// Encode serializes the provided object to the given writer.
|
||||
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(s.Identifier(), s.doEncode, w)
|
||||
}
|
||||
return s.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
if s.options.Yaml {
|
||||
json, err := caseSensitiveJsonIterator.Marshal(obj)
|
||||
if err != nil {
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
@ -456,6 +457,15 @@ func TestDecode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheableObject(t *testing.T) {
|
||||
gvk := schema.GroupVersionKind{Group: "group", Version: "version", Kind: "MockCacheableObject"}
|
||||
creater := &mockCreater{obj: &runtimetesting.MockCacheableObject{}}
|
||||
typer := &mockTyper{gvk: &gvk}
|
||||
serializer := json.NewSerializer(json.DefaultMetaFactory, creater, typer, false)
|
||||
|
||||
runtimetesting.CacheableObjectTest(t, serializer)
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
apiVersion string
|
||||
kind string
|
||||
|
@ -1,9 +1,6 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
@ -35,3 +32,14 @@ filegroup(
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["protobuf_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
@ -178,6 +178,13 @@ func (s *Serializer) Decode(originalData []byte, gvk *schema.GroupVersionKind, i
|
||||
|
||||
// Encode serializes the provided object to the given writer.
|
||||
func (s *Serializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(s.Identifier(), s.doEncode, w)
|
||||
}
|
||||
return s.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (s *Serializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
prefixSize := uint64(len(s.prefix))
|
||||
|
||||
var unk runtime.Unknown
|
||||
@ -428,6 +435,13 @@ func unmarshalToObject(typer runtime.ObjectTyper, creater runtime.ObjectCreater,
|
||||
|
||||
// Encode serializes the provided object to the given writer. Overrides is ignored.
|
||||
func (s *RawSerializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(s.Identifier(), s.doEncode, w)
|
||||
}
|
||||
return s.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (s *RawSerializer) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
switch t := obj.(type) {
|
||||
case bufferedReverseMarshaller:
|
||||
// this path performs a single allocation during write but requires the caller to implement
|
||||
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
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 protobuf
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
)
|
||||
|
||||
func TestCacheableObject(t *testing.T) {
|
||||
gvk := schema.GroupVersionKind{Group: "group", Version: "version", Kind: "MockCacheableObject"}
|
||||
creater := &mockCreater{obj: &runtimetesting.MockCacheableObject{}}
|
||||
typer := &mockTyper{gvk: &gvk}
|
||||
|
||||
encoders := []runtime.Encoder{
|
||||
NewSerializer(creater, typer),
|
||||
NewRawSerializer(creater, typer),
|
||||
}
|
||||
|
||||
for _, encoder := range encoders {
|
||||
runtimetesting.CacheableObjectTest(t, encoder)
|
||||
}
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
apiVersion string
|
||||
kind string
|
||||
err error
|
||||
obj runtime.Object
|
||||
}
|
||||
|
||||
func (c *mockCreater) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||
c.apiVersion, c.kind = kind.GroupVersion().String(), kind.Kind
|
||||
return c.obj, c.err
|
||||
}
|
||||
|
||||
type mockTyper struct {
|
||||
gvk *schema.GroupVersionKind
|
||||
err error
|
||||
}
|
||||
|
||||
func (t *mockTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||
if t.gvk == nil {
|
||||
return nil, false, t.err
|
||||
}
|
||||
return []schema.GroupVersionKind{*t.gvk}, false, t.err
|
||||
}
|
||||
|
||||
func (t *mockTyper) Recognizes(_ schema.GroupVersionKind) bool {
|
||||
return false
|
||||
}
|
@ -17,6 +17,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/testing:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
|
@ -196,6 +196,13 @@ func (c *codec) Decode(data []byte, defaultGVK *schema.GroupVersionKind, into ru
|
||||
// Encode ensures the provided object is output in the appropriate group and version, invoking
|
||||
// conversion if necessary. Unversioned objects (according to the ObjectTyper) are output as is.
|
||||
func (c *codec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(c.Identifier(), c.doEncode, w)
|
||||
}
|
||||
return c.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (c *codec) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
switch obj := obj.(type) {
|
||||
case *runtime.Unknown:
|
||||
return c.encoder.Encode(obj, w)
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
runtimetesting "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
@ -376,6 +377,10 @@ func (s *mockSerializer) Encode(obj runtime.Object, w io.Writer) error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
func (s *mockSerializer) Identifier() runtime.Identifier {
|
||||
return runtime.Identifier("mock")
|
||||
}
|
||||
|
||||
type mockCreater struct {
|
||||
err error
|
||||
obj runtime.Object
|
||||
@ -424,3 +429,17 @@ func TestDirectCodecEncode(t *testing.T) {
|
||||
t.Errorf("expected group to be %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheableObject(t *testing.T) {
|
||||
gvk1 := schema.GroupVersionKind{Group: "group", Version: "version1", Kind: "MockCacheableObject"}
|
||||
gvk2 := schema.GroupVersionKind{Group: "group", Version: "version2", Kind: "MockCacheableObject"}
|
||||
|
||||
encoder := NewCodec(
|
||||
&mockSerializer{}, &mockSerializer{},
|
||||
&mockConvertor{}, nil,
|
||||
&mockTyper{gvks: []schema.GroupVersionKind{gvk1, gvk2}}, nil,
|
||||
gvk1.GroupVersion(), gvk2.GroupVersion(),
|
||||
"TestCacheableObject")
|
||||
|
||||
runtimetesting.CacheableObjectTest(t, encoder)
|
||||
}
|
||||
|
@ -64,6 +64,13 @@ func identifier(e runtime.Encoder) runtime.Identifier {
|
||||
}
|
||||
|
||||
func (c stripVersionEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
||||
if co, ok := obj.(runtime.CacheableObject); ok {
|
||||
return co.CacheEncode(c.Identifier(), c.doEncode, w)
|
||||
}
|
||||
return c.doEncode(obj, w)
|
||||
}
|
||||
|
||||
func (c stripVersionEncoder) doEncode(obj runtime.Object, w io.Writer) error {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
err := c.encoder.Encode(obj, buf)
|
||||
if err != nil {
|
||||
|
@ -55,6 +55,8 @@ func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtim
|
||||
}
|
||||
|
||||
func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error {
|
||||
// There is no need to handle runtime.CacheableObject, as we only
|
||||
// fallback to other encoders here.
|
||||
return unstructured.UnstructuredJSONScheme.Encode(obj, w)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user