mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Fix sinceTime pod log options
This commit is contained in:
		@@ -41,6 +41,7 @@ func init() {
 | 
				
			|||||||
		Convert_unversioned_ListMeta_To_unversioned_ListMeta,
 | 
							Convert_unversioned_ListMeta_To_unversioned_ListMeta,
 | 
				
			||||||
		Convert_intstr_IntOrString_To_intstr_IntOrString,
 | 
							Convert_intstr_IntOrString_To_intstr_IntOrString,
 | 
				
			||||||
		Convert_unversioned_Time_To_unversioned_Time,
 | 
							Convert_unversioned_Time_To_unversioned_Time,
 | 
				
			||||||
 | 
							Convert_string_slice_To_unversioned_Time,
 | 
				
			||||||
		Convert_string_To_labels_Selector,
 | 
							Convert_string_To_labels_Selector,
 | 
				
			||||||
		Convert_string_To_fields_Selector,
 | 
							Convert_string_To_fields_Selector,
 | 
				
			||||||
		Convert_bool_ref_To_bool,
 | 
							Convert_bool_ref_To_bool,
 | 
				
			||||||
@@ -116,6 +117,16 @@ func Convert_unversioned_Time_To_unversioned_Time(in *unversioned.Time, out *unv
 | 
				
			|||||||
	*out = *in
 | 
						*out = *in
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convert_string_slice_To_unversioned_Time allows converting a URL query parameter value
 | 
				
			||||||
 | 
					func Convert_string_slice_To_unversioned_Time(input *[]string, out *unversioned.Time, s conversion.Scope) error {
 | 
				
			||||||
 | 
						str := ""
 | 
				
			||||||
 | 
						if len(*input) > 0 {
 | 
				
			||||||
 | 
							str = (*input)[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out.UnmarshalQueryParameter(str)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Convert_string_To_labels_Selector(in *string, out *labels.Selector, s conversion.Scope) error {
 | 
					func Convert_string_To_labels_Selector(in *string, out *labels.Selector, s conversion.Scope) error {
 | 
				
			||||||
	selector, err := labels.Parse(*in)
 | 
						selector, err := labels.Parse(*in)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,6 +97,27 @@ func (t *Time) UnmarshalJSON(b []byte) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UnmarshalQueryParameter converts from a URL query parameter value to an object
 | 
				
			||||||
 | 
					func (t *Time) UnmarshalQueryParameter(str string) error {
 | 
				
			||||||
 | 
						if len(str) == 0 {
 | 
				
			||||||
 | 
							t.Time = time.Time{}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Tolerate requests from older clients that used JSON serialization to build query params
 | 
				
			||||||
 | 
						if len(str) == 4 && str == "null" {
 | 
				
			||||||
 | 
							t.Time = time.Time{}
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pt, err := time.Parse(time.RFC3339, str)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Time = pt.Local()
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MarshalJSON implements the json.Marshaler interface.
 | 
					// MarshalJSON implements the json.Marshaler interface.
 | 
				
			||||||
func (t Time) MarshalJSON() ([]byte, error) {
 | 
					func (t Time) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
	if t.IsZero() {
 | 
						if t.IsZero() {
 | 
				
			||||||
@@ -107,6 +128,16 @@ func (t Time) MarshalJSON() ([]byte, error) {
 | 
				
			|||||||
	return json.Marshal(t.UTC().Format(time.RFC3339))
 | 
						return json.Marshal(t.UTC().Format(time.RFC3339))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MarshalQueryParameter converts to a URL query parameter value
 | 
				
			||||||
 | 
					func (t Time) MarshalQueryParameter() (string, error) {
 | 
				
			||||||
 | 
						if t.IsZero() {
 | 
				
			||||||
 | 
							// Encode unset/nil objects as an empty string
 | 
				
			||||||
 | 
							return "", nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return t.UTC().Format(time.RFC3339), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Fuzz satisfies fuzz.Interface.
 | 
					// Fuzz satisfies fuzz.Interface.
 | 
				
			||||||
func (t *Time) Fuzz(c fuzz.Continue) {
 | 
					func (t *Time) Fuzz(c fuzz.Continue) {
 | 
				
			||||||
	if t == nil {
 | 
						if t == nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,13 +17,105 @@ limitations under the License.
 | 
				
			|||||||
package v1_test
 | 
					package v1_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/resource"
 | 
						"k8s.io/kubernetes/pkg/api/resource"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/api/unversioned"
 | 
				
			||||||
	versioned "k8s.io/kubernetes/pkg/api/v1"
 | 
						versioned "k8s.io/kubernetes/pkg/api/v1"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/runtime"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/util"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestPodLogOptions(t *testing.T) {
 | 
				
			||||||
 | 
						sinceSeconds := int64(1)
 | 
				
			||||||
 | 
						sinceTime := unversioned.NewTime(time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC).Local())
 | 
				
			||||||
 | 
						tailLines := int64(2)
 | 
				
			||||||
 | 
						limitBytes := int64(3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						versionedLogOptions := &versioned.PodLogOptions{
 | 
				
			||||||
 | 
							Container:    "mycontainer",
 | 
				
			||||||
 | 
							Follow:       true,
 | 
				
			||||||
 | 
							Previous:     true,
 | 
				
			||||||
 | 
							SinceSeconds: &sinceSeconds,
 | 
				
			||||||
 | 
							SinceTime:    &sinceTime,
 | 
				
			||||||
 | 
							Timestamps:   true,
 | 
				
			||||||
 | 
							TailLines:    &tailLines,
 | 
				
			||||||
 | 
							LimitBytes:   &limitBytes,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						unversionedLogOptions := &api.PodLogOptions{
 | 
				
			||||||
 | 
							Container:    "mycontainer",
 | 
				
			||||||
 | 
							Follow:       true,
 | 
				
			||||||
 | 
							Previous:     true,
 | 
				
			||||||
 | 
							SinceSeconds: &sinceSeconds,
 | 
				
			||||||
 | 
							SinceTime:    &sinceTime,
 | 
				
			||||||
 | 
							Timestamps:   true,
 | 
				
			||||||
 | 
							TailLines:    &tailLines,
 | 
				
			||||||
 | 
							LimitBytes:   &limitBytes,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						expectedParameters := url.Values{
 | 
				
			||||||
 | 
							"container":    {"mycontainer"},
 | 
				
			||||||
 | 
							"follow":       {"true"},
 | 
				
			||||||
 | 
							"previous":     {"true"},
 | 
				
			||||||
 | 
							"sinceSeconds": {"1"},
 | 
				
			||||||
 | 
							"sinceTime":    {"2000-01-01T12:34:56Z"},
 | 
				
			||||||
 | 
							"timestamps":   {"true"},
 | 
				
			||||||
 | 
							"tailLines":    {"2"},
 | 
				
			||||||
 | 
							"limitBytes":   {"3"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codec := runtime.NewParameterCodec(api.Scheme)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// unversioned -> query params
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							actualParameters, err := codec.EncodeParameters(unversionedLogOptions, versioned.SchemeGroupVersion)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(actualParameters, expectedParameters) {
 | 
				
			||||||
 | 
								t.Fatalf("Expected\n%#v\ngot\n%#v", expectedParameters, actualParameters)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// versioned -> query params
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							actualParameters, err := codec.EncodeParameters(versionedLogOptions, versioned.SchemeGroupVersion)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(actualParameters, expectedParameters) {
 | 
				
			||||||
 | 
								t.Fatalf("Expected\n%#v\ngot\n%#v", expectedParameters, actualParameters)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// query params -> versioned
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							convertedLogOptions := &versioned.PodLogOptions{}
 | 
				
			||||||
 | 
							err := codec.DecodeParameters(expectedParameters, versioned.SchemeGroupVersion, convertedLogOptions)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(convertedLogOptions, versionedLogOptions) {
 | 
				
			||||||
 | 
								t.Fatalf("Unexpected deserialization:\n%s", util.ObjectGoPrintSideBySide(versionedLogOptions, convertedLogOptions))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// query params -> unversioned
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							convertedLogOptions := &api.PodLogOptions{}
 | 
				
			||||||
 | 
							err := codec.DecodeParameters(expectedParameters, versioned.SchemeGroupVersion, convertedLogOptions)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								t.Fatal(err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !reflect.DeepEqual(convertedLogOptions, unversionedLogOptions) {
 | 
				
			||||||
 | 
								t.Fatalf("Unexpected deserialization:\n%s", util.ObjectGoPrintSideBySide(unversionedLogOptions, convertedLogOptions))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TestPodSpecConversion tests that ServiceAccount is an alias for
 | 
					// TestPodSpecConversion tests that ServiceAccount is an alias for
 | 
				
			||||||
// ServiceAccountName.
 | 
					// ServiceAccountName.
 | 
				
			||||||
func TestPodSpecConversion(t *testing.T) {
 | 
					func TestPodSpecConversion(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,6 +23,16 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Marshaler converts an object to a query parameter string representation
 | 
				
			||||||
 | 
					type Marshaler interface {
 | 
				
			||||||
 | 
						MarshalQueryParameter() (string, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Unmarshaler converts a string representation to an object
 | 
				
			||||||
 | 
					type Unmarshaler interface {
 | 
				
			||||||
 | 
						UnmarshalQueryParameter(string) error
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func jsonTag(field reflect.StructField) (string, bool) {
 | 
					func jsonTag(field reflect.StructField) (string, bool) {
 | 
				
			||||||
	structTag := field.Tag.Get("json")
 | 
						structTag := field.Tag.Get("json")
 | 
				
			||||||
	if len(structTag) == 0 {
 | 
						if len(structTag) == 0 {
 | 
				
			||||||
@@ -72,6 +82,31 @@ func zeroValue(value reflect.Value) bool {
 | 
				
			|||||||
	return reflect.DeepEqual(reflect.Zero(value.Type()).Interface(), value.Interface())
 | 
						return reflect.DeepEqual(reflect.Zero(value.Type()).Interface(), value.Interface())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func customMarshalValue(value reflect.Value) (reflect.Value, bool) {
 | 
				
			||||||
 | 
						// Return unless we implement a custom query marshaler
 | 
				
			||||||
 | 
						if !value.CanInterface() {
 | 
				
			||||||
 | 
							return reflect.Value{}, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						marshaler, ok := value.Interface().(Marshaler)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return reflect.Value{}, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Don't invoke functions on nil pointers
 | 
				
			||||||
 | 
						// If the type implements MarshalQueryParameter, AND the tag is not omitempty, AND the value is a nil pointer, "" seems like a reasonable response
 | 
				
			||||||
 | 
						if isPointerKind(value.Kind()) && zeroValue(value) {
 | 
				
			||||||
 | 
							return reflect.ValueOf(""), true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get the custom marshalled value
 | 
				
			||||||
 | 
						v, err := marshaler.MarshalQueryParameter()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return reflect.Value{}, false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return reflect.ValueOf(v), true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addParam(values url.Values, tag string, omitempty bool, value reflect.Value) {
 | 
					func addParam(values url.Values, tag string, omitempty bool, value reflect.Value) {
 | 
				
			||||||
	if omitempty && zeroValue(value) {
 | 
						if omitempty && zeroValue(value) {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -128,7 +163,8 @@ func convertStruct(result url.Values, st reflect.Type, sv reflect.Value) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		kind := ft.Kind()
 | 
							kind := ft.Kind()
 | 
				
			||||||
		if isPointerKind(kind) {
 | 
							if isPointerKind(kind) {
 | 
				
			||||||
			kind = ft.Elem().Kind()
 | 
								ft = ft.Elem()
 | 
				
			||||||
 | 
								kind = ft.Kind()
 | 
				
			||||||
			if !field.IsNil() {
 | 
								if !field.IsNil() {
 | 
				
			||||||
				field = reflect.Indirect(field)
 | 
									field = reflect.Indirect(field)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -142,7 +178,11 @@ func convertStruct(result url.Values, st reflect.Type, sv reflect.Value) {
 | 
				
			|||||||
				addListOfParams(result, tag, omitempty, field)
 | 
									addListOfParams(result, tag, omitempty, field)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		case isStructKind(kind) && !(zeroValue(field) && omitempty):
 | 
							case isStructKind(kind) && !(zeroValue(field) && omitempty):
 | 
				
			||||||
 | 
								if marshalValue, ok := customMarshalValue(field); ok {
 | 
				
			||||||
 | 
									addParam(result, tag, omitempty, marshalValue)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
				convertStruct(result, ft, field)
 | 
									convertStruct(result, ft, field)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ import (
 | 
				
			|||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/unversioned"
 | 
						"k8s.io/kubernetes/pkg/api/unversioned"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/conversion/queryparams"
 | 
						"k8s.io/kubernetes/pkg/conversion/queryparams"
 | 
				
			||||||
@@ -61,6 +62,19 @@ type baz struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (obj *baz) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
 | 
					func (obj *baz) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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    *unversioned.Time `json:"sinceTime,omitempty"`
 | 
				
			||||||
 | 
						EmptyTime    *unversioned.Time `json:"emptyTime"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (obj *childStructs) GetObjectKind() unversioned.ObjectKind { return unversioned.EmptyObjectKind }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func validateResult(t *testing.T, input interface{}, actual, expected url.Values) {
 | 
					func validateResult(t *testing.T, input interface{}, actual, expected url.Values) {
 | 
				
			||||||
	local := url.Values{}
 | 
						local := url.Values{}
 | 
				
			||||||
	for k, v := range expected {
 | 
						for k, v := range expected {
 | 
				
			||||||
@@ -73,7 +87,6 @@ func validateResult(t *testing.T, input interface{}, actual, expected url.Values
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				t.Errorf("%#v: values don't match: actual: %#v, expected: %#v", input, v, ev)
 | 
									t.Errorf("%#v: values don't match: actual: %#v, expected: %#v", input, v, ev)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		delete(local, k)
 | 
							delete(local, k)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -83,6 +96,9 @@ func validateResult(t *testing.T, input interface{}, actual, expected url.Values
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestConvert(t *testing.T) {
 | 
					func TestConvert(t *testing.T) {
 | 
				
			||||||
 | 
						sinceSeconds := int64(123)
 | 
				
			||||||
 | 
						sinceTime := unversioned.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		input    interface{}
 | 
							input    interface{}
 | 
				
			||||||
		expected url.Values
 | 
							expected url.Values
 | 
				
			||||||
@@ -158,6 +174,27 @@ func TestConvert(t *testing.T) {
 | 
				
			|||||||
			},
 | 
								},
 | 
				
			||||||
			expected: url.Values{"ptr": {"5"}},
 | 
								expected: url.Values{"ptr": {"5"}},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								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
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "sinceTime": {"2000-01-01T12:34:56Z"}, "emptyTime": {""}},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								input: &childStructs{
 | 
				
			||||||
 | 
									Container:    "mycontainer",
 | 
				
			||||||
 | 
									Follow:       true,
 | 
				
			||||||
 | 
									Previous:     true,
 | 
				
			||||||
 | 
									SinceSeconds: &sinceSeconds,
 | 
				
			||||||
 | 
									SinceTime:    nil, // test a nil custom marshaller with omitempty
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: url.Values{"container": {"mycontainer"}, "follow": {"true"}, "previous": {"true"}, "sinceSeconds": {"123"}, "emptyTime": {""}},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, test := range tests {
 | 
						for _, test := range tests {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,6 +26,7 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/api/unversioned"
 | 
				
			||||||
	client "k8s.io/kubernetes/pkg/client/unversioned"
 | 
						client "k8s.io/kubernetes/pkg/client/unversioned"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/stats"
 | 
						"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/stats"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,7 +70,8 @@ var _ = Describe("Kubelet", func() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			It("it should print the output to logs", func() {
 | 
								It("it should print the output to logs", func() {
 | 
				
			||||||
				Eventually(func() string {
 | 
									Eventually(func() string {
 | 
				
			||||||
					rc, err := cl.Pods(api.NamespaceDefault).GetLogs("busybox", &api.PodLogOptions{}).Stream()
 | 
										sinceTime := unversioned.NewTime(time.Now().Add(time.Duration(-1 * time.Hour)))
 | 
				
			||||||
 | 
										rc, err := cl.Pods(api.NamespaceDefault).GetLogs("busybox", &api.PodLogOptions{SinceTime: &sinceTime}).Stream()
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						return ""
 | 
											return ""
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user