From 0fe4911744890fab77e82664816fc55a72f5b383 Mon Sep 17 00:00:00 2001 From: Mikhail Mazurskiy Date: Wed, 30 Aug 2017 16:17:16 +1000 Subject: [PATCH] Pointer receiver support for MarshalQueryParameter() --- .../meta/v1/unstructured/unstructured_test.go | 18 ++++++++ .../pkg/conversion/queryparams/convert.go | 9 +++- .../conversion/queryparams/convert_test.go | 41 ++++++++++--------- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_test.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_test.go index 4869e7c0cf..75f285db14 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured/unstructured_test.go @@ -34,3 +34,21 @@ func TestUnstructuredList(t *testing.T) { t.Fatalf("unexpected fields: %#v", items[0]) } } + +func TestNilDeletionTimestamp(t *testing.T) { + var u Unstructured + del := u.GetDeletionTimestamp() + if del != nil { + t.Errorf("unexpected non-nil deletion timestamp: %v", del) + } + u.SetDeletionTimestamp(u.GetDeletionTimestamp()) + del = u.GetDeletionTimestamp() + if del != nil { + t.Errorf("unexpected non-nil deletion timestamp: %v", del) + } + metadata := u.Object["metadata"].(map[string]interface{}) + deletionTimestamp := metadata["deletionTimestamp"] + if deletionTimestamp != nil { + t.Errorf("unexpected deletion timestamp field: %q", deletionTimestamp) + } +} diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go b/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go index 30f717b2ce..17b3666170 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go +++ b/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert.go @@ -90,7 +90,14 @@ func customMarshalValue(value reflect.Value) (reflect.Value, bool) { marshaler, ok := value.Interface().(Marshaler) if !ok { - return reflect.Value{}, false + if !isPointerKind(value.Kind()) && value.CanAddr() { + marshaler, ok = value.Addr().Interface().(Marshaler) + if !ok { + return reflect.Value{}, false + } + } else { + return reflect.Value{}, false + } } // Don't invoke functions on nil pointers diff --git a/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go b/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go index 21dc0000ef..b075debf1e 100644 --- a/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go +++ b/staging/src/k8s.io/apimachinery/pkg/conversion/queryparams/convert_test.go @@ -66,12 +66,13 @@ func (obj *baz) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKin // childStructs tests some of the types we serialize to query params for log API calls // notably, the nested time struct type childStructs struct { - Container string `json:"container,omitempty"` - Follow bool `json:"follow,omitempty"` - Previous bool `json:"previous,omitempty"` - SinceSeconds *int64 `json:"sinceSeconds,omitempty"` - SinceTime *metav1.Time `json:"sinceTime,omitempty"` - EmptyTime *metav1.Time `json:"emptyTime"` + Container string `json:"container,omitempty"` + Follow bool `json:"follow,omitempty"` + Previous bool `json:"previous,omitempty"` + SinceSeconds *int64 `json:"sinceSeconds,omitempty"` + SinceTime *metav1.Time `json:"sinceTime,omitempty"` + EmptyTime *metav1.Time `json:"emptyTime"` + NonPointerTime metav1.Time `json:"nonPointerTime"` } func (obj *childStructs) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind } @@ -177,24 +178,26 @@ func TestConvert(t *testing.T) { }, { input: &childStructs{ - Container: "mycontainer", - Follow: true, - Previous: true, - SinceSeconds: &sinceSeconds, - SinceTime: &sinceTime, // test a custom marshaller - EmptyTime: nil, // test a nil custom marshaller without omitempty + Container: "mycontainer", + Follow: true, + Previous: true, + SinceSeconds: &sinceSeconds, + SinceTime: &sinceTime, // test a custom marshaller + EmptyTime: nil, // test a nil custom marshaller without omitempty + NonPointerTime: sinceTime, }, - expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "sinceTime": {"2000-01-01T12:34:56Z"}, "emptyTime": {""}}, + expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "sinceTime": {"2000-01-01T12:34:56Z"}, "emptyTime": {""}, "nonPointerTime": {"2000-01-01T12:34:56Z"}}, }, { input: &childStructs{ - Container: "mycontainer", - Follow: true, - Previous: true, - SinceSeconds: &sinceSeconds, - SinceTime: nil, // test a nil custom marshaller with omitempty + Container: "mycontainer", + Follow: true, + Previous: true, + SinceSeconds: &sinceSeconds, + SinceTime: nil, // test a nil custom marshaller with omitempty + NonPointerTime: sinceTime, }, - expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "emptyTime": {""}}, + expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "emptyTime": {""}, "nonPointerTime": {"2000-01-01T12:34:56Z"}}, }, }