diff --git a/hack/.golint_failures b/hack/.golint_failures index dab25848dd0..6c8bd346931 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -505,7 +505,6 @@ staging/src/k8s.io/apimachinery/pkg/apis/meta/v1alpha1 staging/src/k8s.io/apimachinery/pkg/apis/testapigroup staging/src/k8s.io/apimachinery/pkg/apis/testapigroup/v1 staging/src/k8s.io/apimachinery/pkg/conversion -staging/src/k8s.io/apimachinery/pkg/conversion/unstructured staging/src/k8s.io/apimachinery/pkg/labels staging/src/k8s.io/apimachinery/pkg/runtime/schema staging/src/k8s.io/apimachinery/pkg/runtime/serializer diff --git a/pkg/api/testing/BUILD b/pkg/api/testing/BUILD index 149b71937be..9c04ee34584 100644 --- a/pkg/api/testing/BUILD +++ b/pkg/api/testing/BUILD @@ -97,7 +97,6 @@ go_test( "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/protobuf:go_default_library", diff --git a/pkg/api/testing/unstructured_test.go b/pkg/api/testing/unstructured_test.go index c3cc41424a9..005b5d4a9ae 100644 --- a/pkg/api/testing/unstructured_test.go +++ b/pkg/api/testing/unstructured_test.go @@ -29,7 +29,6 @@ import ( "k8s.io/apimachinery/pkg/api/testing/fuzzer" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metaunstruct "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/json" @@ -99,14 +98,14 @@ func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) { return } - newUnstr, err := unstructured.DefaultConverter.ToUnstructured(item) + newUnstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(item) if err != nil { t.Errorf("ToUnstructured failed: %v", err) return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = unstructured.DefaultConverter.FromUnstructured(newUnstr, newObj) + err = runtime.DefaultUnstructuredConverter.FromUnstructured(newUnstr, newObj) if err != nil { t.Errorf("FromUnstructured failed: %v", err) return @@ -146,7 +145,7 @@ func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) { } t.Logf("Testing: %v in %v", kind, groupKey) - unstrBody, err := unstructured.DefaultConverter.ToUnstructured(item) + unstrBody, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item) if err != nil { t.Fatalf("ToUnstructured failed: %v", err) } @@ -163,7 +162,7 @@ func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) { // attempt to re-convert unstructured object - conversion should not fail // based on empty metadata fields, such as creationTimestamp newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) - err = unstructured.DefaultConverter.FromUnstructured(unstructObj.Object, newObj) + err = runtime.NewTestUnstructuredConverter(apiequality.Semantic).FromUnstructured(unstructObj.Object, newObj) if err != nil { t.Fatalf("FromUnstructured failed: %v", err) } @@ -176,12 +175,12 @@ func BenchmarkToFromUnstructured(b *testing.B) { size := len(items) b.ResetTimer() for i := 0; i < b.N; i++ { - unstr, err := unstructured.DefaultConverter.ToUnstructured(&items[i%size]) + unstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(&items[i%size]) if err != nil { b.Fatalf("unexpected error: %v", err) } obj := v1.Pod{} - if err := unstructured.DefaultConverter.FromUnstructured(unstr, &obj); err != nil { + if err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).FromUnstructured(unstr, &obj); err != nil { b.Fatalf("unexpected error: %v", err) } } diff --git a/staging/src/k8s.io/api/Godeps/Godeps.json b/staging/src/k8s.io/api/Godeps/Godeps.json index 83b361acac5..ffa35e2d980 100644 --- a/staging/src/k8s.io/api/Godeps/Godeps.json +++ b/staging/src/k8s.io/api/Godeps/Godeps.json @@ -182,6 +182,10 @@ "ImportPath": "k8s.io/apimachinery/pkg/util/intstr", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, + { + "ImportPath": "k8s.io/apimachinery/pkg/util/json", + "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + }, { "ImportPath": "k8s.io/apimachinery/pkg/util/net", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 7f61204935c..bd34b09887e 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -702,10 +702,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD index 870ef7b906c..7ae9cb0f9d8 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/BUILD @@ -32,7 +32,6 @@ go_library( importpath = "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured", deps = [ "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library", diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go index ac4355bf577..5c9f1a55509 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/helpers.go @@ -24,7 +24,6 @@ import ( "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -39,7 +38,7 @@ func NestedFieldCopy(obj map[string]interface{}, fields ...string) (interface{}, if !ok { return nil, false } - return unstructured.DeepCopyJSONValue(val), true + return runtime.DeepCopyJSONValue(val), true } func nestedFieldNoCopy(obj map[string]interface{}, fields ...string) (interface{}, bool) { @@ -131,7 +130,7 @@ func NestedSlice(obj map[string]interface{}, fields ...string) ([]interface{}, b return nil, false } if _, ok := val.([]interface{}); ok { - return unstructured.DeepCopyJSONValue(val).([]interface{}), true + return runtime.DeepCopyJSONValue(val).([]interface{}), true } return nil, false } @@ -165,7 +164,7 @@ func NestedMap(obj map[string]interface{}, fields ...string) (map[string]interfa return nil, false } if m, ok := val.(map[string]interface{}); ok { - return unstructured.DeepCopyJSON(m), true + return runtime.DeepCopyJSON(m), true } return nil, false } @@ -173,7 +172,7 @@ func NestedMap(obj map[string]interface{}, fields ...string) (map[string]interfa // SetNestedField sets the value of a nested field to a deep copy of the value provided. // Returns false if value cannot be set because one of the nesting levels is not a map[string]interface{}. func SetNestedField(obj map[string]interface{}, value interface{}, fields ...string) bool { - return setNestedFieldNoCopy(obj, unstructured.DeepCopyJSONValue(value), fields...) + return setNestedFieldNoCopy(obj, runtime.DeepCopyJSONValue(value), fields...) } func setNestedFieldNoCopy(obj map[string]interface{}, value interface{}, fields ...string) bool { @@ -288,8 +287,6 @@ func setOwnerReference(src metav1.OwnerReference) map[string]interface{} { return ret } -var converter = unstructured.NewConverter(false) - // UnstructuredJSONScheme is capable of converting JSON data into the Unstructured // type, which can be used for generic access to objects without a predefined scheme. // TODO: move into serializer/json. diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go index 56d18a32e85..c635f34409b 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured.go @@ -21,7 +21,6 @@ import ( "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -112,7 +111,7 @@ func (in *Unstructured) DeepCopy() *Unstructured { } out := new(Unstructured) *out = *in - out.Object = unstructured.DeepCopyJSON(in.Object) + out.Object = runtime.DeepCopyJSON(in.Object) return out } @@ -348,7 +347,7 @@ func (u *Unstructured) GetInitializers() *metav1.Initializers { return nil } out := &metav1.Initializers{} - if err := converter.FromUnstructured(obj, out); err != nil { + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj, out); err != nil { utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err)) } return out @@ -359,7 +358,7 @@ func (u *Unstructured) SetInitializers(initializers *metav1.Initializers) { RemoveNestedField(u.Object, "metadata", "initializers") return } - out, err := converter.ToUnstructured(initializers) + out, err := runtime.DefaultUnstructuredConverter.ToUnstructured(initializers) if err != nil { utilruntime.HandleError(fmt.Errorf("unable to retrieve initializers for object: %v", err)) } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go index 11270a6bf83..4db4162ac29 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_list.go @@ -20,7 +20,6 @@ import ( "bytes" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" ) @@ -80,7 +79,7 @@ func (u *UnstructuredList) DeepCopy() *UnstructuredList { } out := new(UnstructuredList) *out = *u - out.Object = unstructured.DeepCopyJSON(u.Object) + out.Object = runtime.DeepCopyJSON(u.Object) out.Items = make([]Unstructured, len(u.Items)) for i := range u.Items { u.Items[i].DeepCopyInto(&out.Items[i]) diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/BUILD b/staging/src/k8s.io/apimachinery/pkg/conversion/BUILD index 72add7598f6..184dafbff1d 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/conversion/BUILD @@ -45,7 +45,6 @@ filegroup( srcs = [ ":package-srcs", "//staging/src/k8s.io/apimachinery/pkg/conversion/queryparams:all-srcs", - "//staging/src/k8s.io/apimachinery/pkg/conversion/unstructured:all-srcs", ], tags = ["automanaged"], ) diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/BUILD b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/BUILD deleted file mode 100644 index 91c1bb00bdf..00000000000 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/BUILD +++ /dev/null @@ -1,39 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -load( - "@io_bazel_rules_go//go:def.bzl", - "go_library", -) - -go_library( - name = "go_default_library", - srcs = [ - "converter.go", - "doc.go", - ], - importpath = "k8s.io/apimachinery/pkg/conversion/unstructured", - deps = [ - "//vendor/github.com/golang/glog:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [ - ":package-srcs", - "//staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing:all-srcs", - ], - tags = ["automanaged"], -) diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go deleted file mode 100644 index cd40e74bed3..00000000000 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2017 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 unstructured provides conversion from runtime objects -// to map[string]interface{} representation. -package unstructured // import "k8s.io/apimachinery/pkg/conversion/unstructured" diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/BUILD b/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/BUILD deleted file mode 100644 index eaeca02a7ed..00000000000 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/BUILD +++ /dev/null @@ -1,29 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_test") - -go_test( - name = "go_default_test", - srcs = ["converter_test.go"], - importpath = "k8s.io/apimachinery/pkg/conversion/unstructured/testing", - deps = [ - "//vendor/github.com/stretchr/testify/assert:go_default_library", - "//vendor/github.com/stretchr/testify/require:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library", - ], -) - -filegroup( - name = "package-srcs", - srcs = glob(["**"]), - tags = ["automanaged"], - visibility = ["//visibility:private"], -) - -filegroup( - name = "all-srcs", - srcs = [":package-srcs"], - tags = ["automanaged"], - visibility = ["//visibility:public"], -) diff --git a/staging/src/k8s.io/apimachinery/pkg/runtime/BUILD b/staging/src/k8s.io/apimachinery/pkg/runtime/BUILD index 2085e643fd6..93c6dcbfc77 100644 --- a/staging/src/k8s.io/apimachinery/pkg/runtime/BUILD +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/BUILD @@ -19,6 +19,7 @@ go_library( "codec.go", "codec_check.go", "conversion.go", + "converter.go", "doc.go", "embedded.go", "error.go", @@ -37,10 +38,13 @@ go_library( importpath = "k8s.io/apimachinery/pkg/runtime", deps = [ "//vendor/github.com/gogo/protobuf/proto:go_default_library", + "//vendor/github.com/golang/glog:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion/queryparams:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library", ], ) @@ -48,6 +52,7 @@ go_test( name = "go_default_xtest", srcs = [ "conversion_test.go", + "converter_test.go", "embedded_test.go", "extension_test.go", "scheme_test.go", @@ -56,13 +61,17 @@ go_test( deps = [ "//vendor/github.com/google/gofuzz:go_default_library", "//vendor/github.com/spf13/pflag:go_default_library", + "//vendor/github.com/stretchr/testify/assert:go_default_library", + "//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/testing:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library", + "//vendor/k8s.io/apimachinery/pkg/util/json:go_default_library", ], ) diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go b/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go similarity index 92% rename from staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go rename to staging/src/k8s.io/apimachinery/pkg/runtime/converter.go index 077d173d8c1..b10fe4858bf 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/converter.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package unstructured +package runtime import ( "bytes" @@ -27,19 +27,18 @@ import ( "strings" "sync" "sync/atomic" + "time" - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/diff" + "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/util/json" utilruntime "k8s.io/apimachinery/pkg/util/runtime" "github.com/golang/glog" ) -// Converter is an interface for converting between interface{} +// UnstructuredConverter is an interface for converting between interface{} // and map[string]interface representation. -type Converter interface { +type UnstructuredConverter interface { ToUnstructured(obj interface{}) (map[string]interface{}, error) FromUnstructured(u map[string]interface{}, obj interface{}) error } @@ -78,7 +77,16 @@ var ( float64Type = reflect.TypeOf(float64(0)) boolType = reflect.TypeOf(bool(false)) fieldCache = newFieldsCache() - DefaultConverter = NewConverter(parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR"))) + + // DefaultUnstructuredConverter performs unstructured to Go typed object conversions. + DefaultUnstructuredConverter = &unstructuredConverter{ + mismatchDetection: parseBool(os.Getenv("KUBE_PATCH_CONVERSION_DETECTOR")), + comparison: conversion.EqualitiesOrDie( + func(a, b time.Time) bool { + return a.UTC() == b.UTC() + }, + ), + } ) func parseBool(key string) bool { @@ -92,24 +100,30 @@ func parseBool(key string) bool { return value } -// ConverterImpl knows how to convert between interface{} and +// unstructuredConverter knows how to convert between interface{} and // Unstructured in both ways. -type converterImpl struct { +type unstructuredConverter struct { // If true, we will be additionally running conversion via json // to ensure that the result is true. // This is supposed to be set only in tests. mismatchDetection bool + // comparison is the default test logic used to compare + comparison conversion.Equalities } -func NewConverter(mismatchDetection bool) Converter { - return &converterImpl{ - mismatchDetection: mismatchDetection, +// NewTestUnstructuredConverter creates an UnstructuredConverter that accepts JSON typed maps and translates them +// to Go types via reflection. It performs mismatch detection automatically and is intended for use by external +// test tools. Use DefaultUnstructuredConverter if you do not explicitly need mismatch detection. +func NewTestUnstructuredConverter(comparison conversion.Equalities) UnstructuredConverter { + return &unstructuredConverter{ + mismatchDetection: true, + comparison: comparison, } } // FromUnstructured converts an object from map[string]interface{} representation into a concrete type. // It uses encoding/json/Unmarshaler if object implements it or reflection if not. -func (c *converterImpl) FromUnstructured(u map[string]interface{}, obj interface{}) error { +func (c *unstructuredConverter) FromUnstructured(u map[string]interface{}, obj interface{}) error { t := reflect.TypeOf(obj) value := reflect.ValueOf(obj) if t.Kind() != reflect.Ptr || value.IsNil() { @@ -122,8 +136,8 @@ func (c *converterImpl) FromUnstructured(u map[string]interface{}, obj interface if (err != nil) != (newErr != nil) { glog.Fatalf("FromUnstructured unexpected error for %v: error: %v", u, err) } - if err == nil && !apiequality.Semantic.DeepEqual(obj, newObj) { - glog.Fatalf("FromUnstructured mismatch for %#v, diff: %v", obj, diff.ObjectReflectDiff(obj, newObj)) + if err == nil && !c.comparison.DeepEqual(obj, newObj) { + glog.Fatalf("FromUnstructured mismatch\nobj1: %#v\nobj2: %#v", obj, newObj) } } return err @@ -393,10 +407,10 @@ func interfaceFromUnstructured(sv, dv reflect.Value) error { // ToUnstructured converts an object into map[string]interface{} representation. // It uses encoding/json/Marshaler if object implements it or reflection if not. -func (c *converterImpl) ToUnstructured(obj interface{}) (map[string]interface{}, error) { +func (c *unstructuredConverter) ToUnstructured(obj interface{}) (map[string]interface{}, error) { var u map[string]interface{} var err error - if unstr, ok := obj.(runtime.Unstructured); ok { + if unstr, ok := obj.(Unstructured); ok { u = DeepCopyJSON(unstr.UnstructuredContent()) } else { t := reflect.TypeOf(obj) @@ -413,8 +427,8 @@ func (c *converterImpl) ToUnstructured(obj interface{}) (map[string]interface{}, if (err != nil) != (newErr != nil) { glog.Fatalf("ToUnstructured unexpected error for %v: error: %v; newErr: %v", obj, err, newErr) } - if err == nil && !apiequality.Semantic.DeepEqual(u, newUnstr) { - glog.Fatalf("ToUnstructured mismatch for %#v, diff: %v", u, diff.ObjectReflectDiff(u, newUnstr)) + if err == nil && !c.comparison.DeepEqual(u, newUnstr) { + glog.Fatalf("ToUnstructured mismatch\nobj1: %#v\nobj2: %#v", u, newUnstr) } } if err != nil { diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/converter_test.go b/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go similarity index 93% rename from staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/converter_test.go rename to staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go index f367c6310b6..1e9515102cf 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/unstructured/testing/converter_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/runtime/converter_test.go @@ -18,7 +18,7 @@ limitations under the License. // Unstructured type depends on unstructured converter package but we want to test how the converter handles // the Unstructured type so we need to import both. -package testing +package runtime_test import ( encodingjson "encoding/json" @@ -26,9 +26,11 @@ import ( "reflect" "strconv" "testing" + "time" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - conversionunstructured "k8s.io/apimachinery/pkg/conversion/unstructured" + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/json" @@ -36,6 +38,12 @@ import ( "github.com/stretchr/testify/require" ) +var simpleEquality = conversion.EqualitiesOrDie( + func(a, b time.Time) bool { + return a.UTC() == b.UTC() + }, +) + // Definte a number of test types. type A struct { A int `json:"aa,omitempty"` @@ -137,14 +145,15 @@ func doRoundTrip(t *testing.T, item interface{}) { return } - newUnstr, err := conversionunstructured.DefaultConverter.ToUnstructured(item) + // TODO: should be using mismatch detection but fails due to another error + newUnstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item) if err != nil { t.Errorf("ToUnstructured failed: %v", err) return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface() - err = conversionunstructured.DefaultConverter.FromUnstructured(newUnstr, newObj) + err = runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(newUnstr, newObj) if err != nil { t.Errorf("FromUnstructured failed: %v", err) return @@ -239,10 +248,9 @@ func TestRoundTrip(t *testing.T) { } for i := range testCases { - doRoundTrip(t, testCases[i].obj) - if t.Failed() { - break - } + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + doRoundTrip(t, testCases[i].obj) + }) } } @@ -265,7 +273,7 @@ func doUnrecognized(t *testing.T, jsonData string, item interface{}, expectedErr return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface() - err = conversionunstructured.DefaultConverter.FromUnstructured(unstr, newObj) + err = runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(unstr, newObj) if (err != nil) != (expectedErr != nil) { t.Errorf("Unexpected error in FromUnstructured: %v, expected: %v", err, expectedErr) } @@ -479,7 +487,7 @@ func TestDeepCopyJSON(t *testing.T) { "f": true, "g": encodingjson.Number("123"), } - deepCopy := conversionunstructured.DeepCopyJSON(src) + deepCopy := runtime.DeepCopyJSON(src) assert.Equal(t, src, deepCopy) } @@ -487,7 +495,7 @@ func TestFloatIntConversion(t *testing.T) { unstr := map[string]interface{}{"fd": float64(3)} var obj F - if err := conversionunstructured.DefaultConverter.FromUnstructured(unstr, &obj); err != nil { + if err := runtime.NewTestUnstructuredConverter(simpleEquality).FromUnstructured(unstr, &obj); err != nil { t.Errorf("Unexpected error in FromUnstructured: %v", err) } @@ -525,7 +533,7 @@ func TestCustomToUnstructured(t *testing.T) { tc := tc t.Run(tc.Data, func(t *testing.T) { t.Parallel() - result, err := conversionunstructured.DefaultConverter.ToUnstructured(&G{ + result, err := runtime.NewTestUnstructuredConverter(simpleEquality).ToUnstructured(&G{ CustomValue1: CustomValue{data: []byte(tc.Data)}, CustomValue2: &CustomValue{data: []byte(tc.Data)}, CustomPointer1: CustomPointer{data: []byte(tc.Data)}, @@ -550,7 +558,7 @@ func TestCustomToUnstructuredTopLevel(t *testing.T) { obj := obj t.Run(strconv.Itoa(i), func(t *testing.T) { t.Parallel() - result, err := conversionunstructured.DefaultConverter.ToUnstructured(obj) + result, err := runtime.NewTestUnstructuredConverter(simpleEquality).ToUnstructured(obj) require.NoError(t, err) assert.Equal(t, expected, result) }) diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index 1e0d2090888..717b1127f6f 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -954,10 +954,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/BUILD index 92b7b282322..7e2cdcc1b19 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/BUILD @@ -60,7 +60,6 @@ go_library( "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library", - "//vendor/k8s.io/apimachinery/pkg/conversion/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go index 8db9f40c93a..1ac736d09dd 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go @@ -27,7 +27,6 @@ import ( "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/meta" - "k8s.io/apimachinery/pkg/conversion/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -232,7 +231,7 @@ func patchResource( return nil, err } // Capture the original object map and patch for possible retries. - originalMap, err := unstructured.DefaultConverter.ToUnstructured(currentVersionedObject) + originalMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(currentVersionedObject) if err != nil { return nil, err } @@ -278,7 +277,7 @@ func patchResource( if err != nil { return nil, err } - currentObjMap, err := unstructured.DefaultConverter.ToUnstructured(currentVersionedObject) + currentObjMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(currentVersionedObject) if err != nil { return nil, err } @@ -425,7 +424,7 @@ func strategicPatchObject( objToUpdate runtime.Object, versionedObj runtime.Object, ) error { - originalObjMap, err := unstructured.DefaultConverter.ToUnstructured(originalObject) + originalObjMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(originalObject) if err != nil { return err } @@ -458,7 +457,7 @@ func applyPatchToObject( } // Rather than serialize the patched map to JSON, then decode it to an object, we go directly from a map to an object - if err := unstructured.DefaultConverter.FromUnstructured(patchedObjMap, objToUpdate); err != nil { + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(patchedObjMap, objToUpdate); err != nil { return err } // Decoding from JSON to a versioned object would apply defaults, so we do the same here diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index 917b30d09e7..32a753405b9 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -546,10 +546,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index 77163536018..80920dbf316 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -666,10 +666,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/metrics/Godeps/Godeps.json b/staging/src/k8s.io/metrics/Godeps/Godeps.json index f04be36963f..155f834ab7d 100644 --- a/staging/src/k8s.io/metrics/Godeps/Godeps.json +++ b/staging/src/k8s.io/metrics/Godeps/Godeps.json @@ -14,10 +14,6 @@ "ImportPath": "github.com/PuerkitoBio/urlesc", "Rev": "5bd2802263f21d8788851d5305584c82a5c75d7e" }, - { - "ImportPath": "github.com/davecgh/go-spew/spew", - "Rev": "782f4967f2dc4564575ca782fe2d04090b5faca8" - }, { "ImportPath": "github.com/emicklei/go-restful", "Rev": "ff4f55a206334ef123e4f79bbf348980da81ca46" @@ -306,10 +302,6 @@ "ImportPath": "k8s.io/api/storage/v1beta1", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/api/equality", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -354,10 +346,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -410,10 +398,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/util/clock", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/util/diff", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/util/errors", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index d08413cd72d..41c1836a982 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -666,10 +666,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" diff --git a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json index b6412341fc7..4368edf042c 100644 --- a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json @@ -342,10 +342,6 @@ "ImportPath": "k8s.io/api/storage/v1beta1", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/api/equality", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/api/errors", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -382,10 +378,6 @@ "ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }, - { - "ImportPath": "k8s.io/apimachinery/pkg/conversion/unstructured", - "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - }, { "ImportPath": "k8s.io/apimachinery/pkg/fields", "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"