mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 23:15:14 +00:00
Add tests for encoding collections in JSON for KEP-5116
Used test cases from: * Original PR https://github.com/kubernetes/kubernetes/pull/129334 * KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests For now testing current serializer implementation to show encoder behavior and agree on set of tests. Having a separate PR should make review easier. In separate PR will add the implementation for streaming that should provide same response byte-to-byte.
This commit is contained in:
parent
9a9f10bc7b
commit
26fe6bc6e0
@ -0,0 +1,655 @@
|
||||
/*
|
||||
Copyright 2025 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 json
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
testapigroupv1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestCollectionsEncoding(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
testCollectionsEncoding(t, NewSerializerWithOptions(DefaultMetaFactory, nil, nil, SerializerOptions{}))
|
||||
})
|
||||
// Leave place for testing streaming collection serializer proposed as part of KEP-5116
|
||||
}
|
||||
|
||||
// testCollectionsEncoding should provide comprehensive tests to validate streaming implementation of encoder.
|
||||
func testCollectionsEncoding(t *testing.T, s *Serializer) {
|
||||
var buf bytes.Buffer
|
||||
var remainingItems int64 = 1
|
||||
// As defined in KEP-5116 we it should include the following scenarios:
|
||||
// Context: https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in runtime.Object
|
||||
expect string
|
||||
}{
|
||||
// Preserving the distinction between integers and floating-point numbers
|
||||
{
|
||||
name: "Struct with floats",
|
||||
in: &StructWithFloatsList{
|
||||
Items: []StructWithFloats{
|
||||
{
|
||||
Int: 1,
|
||||
Float32: float32(1),
|
||||
Float64: 1.1,
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"Int\":1,\"Float32\":1,\"Float64\":1.1}]}\n",
|
||||
},
|
||||
{
|
||||
name: "Unstructured object float",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"int": 1,
|
||||
"float32": float32(1),
|
||||
"float64": 1.1,
|
||||
},
|
||||
},
|
||||
expect: "{\"float32\":1,\"float64\":1.1,\"int\":1,\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "Unstructured items float",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"int": 1,
|
||||
"float32": float32(1),
|
||||
"float64": 1.1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"float32\":1,\"float64\":1.1,\"int\":1}]}\n",
|
||||
},
|
||||
// Handling structs with duplicate field names (JSON tag names) without producing duplicate keys in the encoded output
|
||||
{
|
||||
name: "StructWithDuplicatedTags",
|
||||
in: &StructWithDuplicatedTagsList{
|
||||
Items: []StructWithDuplicatedTags{
|
||||
{
|
||||
Key1: "key1",
|
||||
Key2: "key2",
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null}}]}\n",
|
||||
},
|
||||
// Encoding Go strings containing invalid UTF-8 sequences without error
|
||||
{
|
||||
name: "UnstructuredList object invalid UTF-8 ",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"key": "\x80", // first byte is a continuation byte
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[],\"key\":\"\\ufffd\"}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items invalid UTF-8 ",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"key": "\x80", // first byte is a continuation byte
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"key\":\"\\ufffd\"}]}\n",
|
||||
},
|
||||
// Preserving the distinction between absent, present-but-null, and present-and-empty states for slices and maps
|
||||
{
|
||||
name: "CarpList items nil",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: nil,
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":null}\n",
|
||||
},
|
||||
{
|
||||
name: "CarpList slice nil",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: []testapigroupv1.Carp{
|
||||
{
|
||||
Status: testapigroupv1.CarpStatus{
|
||||
Conditions: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"spec\":{},\"status\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "CarpList map nil",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: []testapigroupv1.Carp{
|
||||
{
|
||||
Spec: testapigroupv1.CarpSpec{
|
||||
NodeSelector: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"spec\":{},\"status\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: nil,
|
||||
},
|
||||
expect: "{\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items slice nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"slice": ([]string)(nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"slice\":null}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items map nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"map": (map[string]string)(nil),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"map\":null}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: nil,
|
||||
},
|
||||
expect: "{\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object slice nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"slice": ([]string)(nil),
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[],\"slice\":null}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object map nil",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"map": (map[string]string)(nil),
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[],\"map\":null}\n",
|
||||
},
|
||||
{
|
||||
name: "CarpList items empty",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: []testapigroupv1.Carp{},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "CarpList slice empty",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: []testapigroupv1.Carp{
|
||||
{
|
||||
Status: testapigroupv1.CarpStatus{
|
||||
Conditions: []testapigroupv1.CarpCondition{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"spec\":{},\"status\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "CarpList map empty",
|
||||
in: &testapigroupv1.CarpList{
|
||||
Items: []testapigroupv1.Carp{
|
||||
{
|
||||
Spec: testapigroupv1.CarpSpec{
|
||||
NodeSelector: map[string]string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"spec\":{},\"status\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{},
|
||||
},
|
||||
expect: "{\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items slice empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"slice": []string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"slice\":[]}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items map empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"map": map[string]string{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"map\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{},
|
||||
},
|
||||
expect: "{\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object slice empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"slice": []string{},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[],\"slice\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object map empty",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"map": map[string]string{},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[],\"map\":{}}\n",
|
||||
},
|
||||
// Handling structs implementing MarshallJSON method, especially built-in collection types.
|
||||
{
|
||||
name: "List with MarshallJSON",
|
||||
in: &ListWithMarshalJSONList{},
|
||||
expect: "\"marshallJSON\"\n",
|
||||
},
|
||||
{
|
||||
name: "Struct with MarshallJSON",
|
||||
in: &StructWithMarshalJSONList{
|
||||
Items: []StructWithMarshalJSON{
|
||||
{},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[\"marshallJSON\"]}\n",
|
||||
},
|
||||
// Handling raw bytes.
|
||||
{
|
||||
name: "Struct with raw bytes",
|
||||
in: &StructWithRawBytesList{
|
||||
Items: []StructWithRawBytes{
|
||||
{
|
||||
Slice: []byte{0x01, 0x02, 0x03},
|
||||
Array: [3]byte{0x01, 0x02, 0x03},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"metadata\":{},\"items\":[{\"metadata\":{\"creationTimestamp\":null},\"Slice\":\"AQID\",\"Array\":[1,2,3]}]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList object raw bytes",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{
|
||||
"slice": []byte{0x01, 0x02, 0x03},
|
||||
"array": [3]byte{0x01, 0x02, 0x03},
|
||||
},
|
||||
},
|
||||
expect: "{\"array\":[1,2,3],\"items\":[],\"slice\":\"AQID\"}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList items raw bytes",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"slice": []byte{0x01, 0x02, 0x03},
|
||||
"array": [3]byte{0x01, 0x02, 0x03},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"array\":[1,2,3],\"slice\":\"AQID\"}]}\n",
|
||||
},
|
||||
// Other scenarios:
|
||||
{
|
||||
name: "List just kind",
|
||||
in: &testapigroupv1.CarpList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "List",
|
||||
},
|
||||
},
|
||||
expect: "{\"kind\":\"List\",\"metadata\":{},\"items\":null}\n",
|
||||
},
|
||||
{
|
||||
name: "List just apiVersion",
|
||||
in: &testapigroupv1.CarpList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
},
|
||||
},
|
||||
expect: "{\"apiVersion\":\"v1\",\"metadata\":{},\"items\":null}\n",
|
||||
},
|
||||
{
|
||||
name: "List no elements",
|
||||
in: &testapigroupv1.CarpList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "List",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ListMeta: metav1.ListMeta{
|
||||
ResourceVersion: "2345",
|
||||
},
|
||||
Items: []testapigroupv1.Carp{},
|
||||
},
|
||||
expect: "{\"kind\":\"List\",\"apiVersion\":\"v1\",\"metadata\":{\"resourceVersion\":\"2345\"},\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "List one element with continue",
|
||||
in: &testapigroupv1.CarpList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "List",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ListMeta: metav1.ListMeta{
|
||||
ResourceVersion: "2345",
|
||||
Continue: "abc",
|
||||
RemainingItemCount: &remainingItems,
|
||||
},
|
||||
Items: []testapigroupv1.Carp{
|
||||
{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Carp"}, ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod",
|
||||
Namespace: "default",
|
||||
}},
|
||||
},
|
||||
},
|
||||
expect: "{\"kind\":\"List\",\"apiVersion\":\"v1\",\"metadata\":{\"resourceVersion\":\"2345\",\"continue\":\"abc\",\"remainingItemCount\":1},\"items\":[{\"kind\":\"Carp\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"pod\",\"namespace\":\"default\",\"creationTimestamp\":null},\"spec\":{},\"status\":{}}]}\n",
|
||||
},
|
||||
{
|
||||
name: "List two elements",
|
||||
in: &testapigroupv1.CarpList{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "List",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ListMeta: metav1.ListMeta{
|
||||
ResourceVersion: "2345",
|
||||
},
|
||||
Items: []testapigroupv1.Carp{
|
||||
{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Carp"}, ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod",
|
||||
Namespace: "default",
|
||||
}},
|
||||
{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Carp"}, ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod2",
|
||||
Namespace: "default2",
|
||||
}},
|
||||
},
|
||||
},
|
||||
expect: `{"kind":"List","apiVersion":"v1","metadata":{"resourceVersion":"2345"},"items":[{"kind":"Carp","apiVersion":"v1","metadata":{"name":"pod","namespace":"default","creationTimestamp":null},"spec":{},"status":{}},{"kind":"Carp","apiVersion":"v1","metadata":{"name":"pod2","namespace":"default2","creationTimestamp":null},"spec":{},"status":{}}]}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList empty",
|
||||
in: &unstructured.UnstructuredList{},
|
||||
expect: "{\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList just kind",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"kind": "List"},
|
||||
},
|
||||
expect: "{\"items\":[],\"kind\":\"List\"}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList just apiVersion",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"apiVersion": "v1"},
|
||||
},
|
||||
expect: "{\"apiVersion\":\"v1\",\"items\":[]}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList no elements",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"kind": "List", "apiVersion": "v1", "metadata": map[string]interface{}{"resourceVersion": "2345"}},
|
||||
Items: []unstructured.Unstructured{},
|
||||
},
|
||||
expect: "{\"apiVersion\":\"v1\",\"items\":[],\"kind\":\"List\",\"metadata\":{\"resourceVersion\":\"2345\"}}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList one element with continue",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"kind": "List", "apiVersion": "v1", "metadata": map[string]interface{}{
|
||||
"resourceVersion": "2345",
|
||||
"continue": "abc",
|
||||
"remainingItemCount": "1",
|
||||
}},
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Carp",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
"namespace": "default",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Carp\",\"metadata\":{\"name\":\"pod\",\"namespace\":\"default\"}}],\"kind\":\"List\",\"metadata\":{\"continue\":\"abc\",\"remainingItemCount\":\"1\",\"resourceVersion\":\"2345\"}}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList two elements",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"kind": "List", "apiVersion": "v1", "metadata": map[string]interface{}{
|
||||
"resourceVersion": "2345",
|
||||
}},
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Carp",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod",
|
||||
"namespace": "default",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Carp",
|
||||
"metadata": map[string]interface{}{
|
||||
"name": "pod2",
|
||||
"namespace": "default",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Carp\",\"metadata\":{\"name\":\"pod\",\"namespace\":\"default\"}},{\"apiVersion\":\"v1\",\"kind\":\"Carp\",\"metadata\":{\"name\":\"pod2\",\"namespace\":\"default\"}}],\"kind\":\"List\",\"metadata\":{\"resourceVersion\":\"2345\"}}\n",
|
||||
},
|
||||
{
|
||||
name: "UnstructuredList conflict on items",
|
||||
in: &unstructured.UnstructuredList{
|
||||
Object: map[string]interface{}{"items": []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"name": "pod",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Items: []unstructured.Unstructured{
|
||||
{
|
||||
Object: map[string]interface{}{
|
||||
"name": "pod2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: "{\"items\":[{\"name\":\"pod2\"}]}\n",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
buf.Reset()
|
||||
if err := s.Encode(tc.in, &buf); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("normal: %s", buf.String())
|
||||
if diff := cmp.Diff(buf.String(), tc.expect); diff != "" {
|
||||
t.Errorf("not matching:\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type StructWithFloatsList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []StructWithFloats `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func (l *StructWithFloatsList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StructWithFloats struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
Int int
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
}
|
||||
|
||||
func (s *StructWithFloats) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StructWithDuplicatedTagsList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []StructWithDuplicatedTags `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func (l *StructWithDuplicatedTagsList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StructWithDuplicatedTags struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
|
||||
Key1 string `json:"key"`
|
||||
Key2 string `json:"key"` //nolint:govet
|
||||
}
|
||||
|
||||
func (s *StructWithDuplicatedTags) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListWithMarshalJSONList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []string `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func (l *ListWithMarshalJSONList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *ListWithMarshalJSONList) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"marshallJSON"`), nil
|
||||
}
|
||||
|
||||
type StructWithMarshalJSONList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []StructWithMarshalJSON `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func (s *StructWithMarshalJSONList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StructWithMarshalJSON struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
}
|
||||
|
||||
func (l *StructWithMarshalJSON) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *StructWithMarshalJSON) MarshalJSON() ([]byte, error) {
|
||||
return []byte(`"marshallJSON"`), nil
|
||||
}
|
||||
|
||||
type StructWithRawBytesList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Items []StructWithRawBytes `json:"items" protobuf:"bytes,2,rep,name=items"`
|
||||
}
|
||||
|
||||
func (s *StructWithRawBytesList) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
||||
|
||||
type StructWithRawBytes struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
|
||||
Slice []byte
|
||||
Array [3]byte
|
||||
}
|
||||
|
||||
func (s *StructWithRawBytes) DeepCopyObject() runtime.Object {
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user