@@ -18,11 +18,16 @@ package v1
18
18
19
19
import (
20
20
"encoding/json"
21
+ "fmt"
21
22
"reflect"
22
23
"testing"
23
24
"time"
24
25
26
+ cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
25
27
"sigs.k8s.io/yaml"
28
+
29
+ "github.com/google/go-cmp/cmp"
30
+ fuzz "github.com/google/gofuzz"
26
31
)
27
32
28
33
type MicroTimeHolder struct {
@@ -113,6 +118,59 @@ func TestMicroTimeUnmarshalJSON(t *testing.T) {
113
118
}
114
119
}
115
120
121
+ func TestMicroTimeMarshalCBOR (t * testing.T ) {
122
+ for _ , tc := range []struct {
123
+ name string
124
+ in MicroTime
125
+ out []byte
126
+ }{
127
+ {name : "zero value" , in : MicroTime {}, out : []byte {0xf6 }}, // null
128
+ {name : "no fractional seconds" , in : DateMicro (1998 , time .May , 5 , 5 , 5 , 5 , 0 , time .UTC ), out : []byte ("\x58 \x1b 1998-05-05T05:05:05.000000Z" )}, // '1998-05-05T05:05:05.000000Z'
129
+ {name : "nanoseconds truncated" , in : DateMicro (1998 , time .May , 5 , 5 , 5 , 5 , 5050 , time .UTC ), out : []byte ("\x58 \x1b 1998-05-05T05:05:05.000005Z" )}, // '1998-05-05T05:05:05.000005Z'
130
+ } {
131
+ t .Run (fmt .Sprintf ("%+v" , tc .in ), func (t * testing.T ) {
132
+ got , err := tc .in .MarshalCBOR ()
133
+ if err != nil {
134
+ t .Fatal (err )
135
+ }
136
+ if diff := cmp .Diff (tc .out , got ); diff != "" {
137
+ t .Errorf ("unexpected output:\n %s" , diff )
138
+ }
139
+ })
140
+ }
141
+ }
142
+
143
+ func TestMicroTimeUnmarshalCBOR (t * testing.T ) {
144
+ for _ , tc := range []struct {
145
+ name string
146
+ in []byte
147
+ out MicroTime
148
+ errMessage string
149
+ }{
150
+ {name : "null" , in : []byte {0xf6 }, out : MicroTime {}}, // null
151
+ {name : "valid" , in : []byte ("\x58 \x1b 1998-05-05T05:05:05.000000Z" ), out : MicroTime {Time : Date (1998 , time .May , 5 , 5 , 5 , 5 , 0 , time .UTC ).Local ()}}, // '1998-05-05T05:05:05.000000Z'
152
+ {name : "invalid cbor type" , in : []byte {0x07 }, out : MicroTime {}, errMessage : "cbor: cannot unmarshal positive integer into Go value of type string" }, // 7
153
+ {name : "malformed timestamp" , in : []byte ("\x45 hello" ), out : MicroTime {}, errMessage : `parsing time "hello" as "2006-01-02T15:04:05.000000Z07:00": cannot parse "hello" as "2006"` }, // 'hello'
154
+ } {
155
+ t .Run (tc .name , func (t * testing.T ) {
156
+ var got MicroTime
157
+ err := got .UnmarshalCBOR (tc .in )
158
+ if err != nil {
159
+ if tc .errMessage == "" {
160
+ t .Fatalf ("want nil error, got: %v" , err )
161
+ } else if gotMessage := err .Error (); tc .errMessage != gotMessage {
162
+ t .Fatalf ("want error: %q, got: %q" , tc .errMessage , gotMessage )
163
+ }
164
+ } else if tc .errMessage != "" {
165
+ t .Fatalf ("got nil error, want: %s" , tc .errMessage )
166
+ }
167
+ if diff := cmp .Diff (tc .out , got ); diff != "" {
168
+ t .Errorf ("unexpected output:\n %s" , diff )
169
+ }
170
+ })
171
+ }
172
+ }
173
+
116
174
func TestMicroTimeProto (t * testing.T ) {
117
175
cases := []struct {
118
176
input MicroTime
@@ -318,3 +376,27 @@ func TestMicroTimeProtoUnmarshalRaw(t *testing.T) {
318
376
}
319
377
320
378
}
379
+
380
+ func TestMicroTimeRoundtripCBOR (t * testing.T ) {
381
+ fuzzer := fuzz .New ()
382
+ for i := 0 ; i < 500 ; i ++ {
383
+ var initial , final MicroTime
384
+ fuzzer .Fuzz (& initial )
385
+ b , err := cbor .Marshal (initial )
386
+ if err != nil {
387
+ t .Errorf ("error encoding %v: %v" , initial , err )
388
+ continue
389
+ }
390
+ err = cbor .Unmarshal (b , & final )
391
+ if err != nil {
392
+ t .Errorf ("%v: error decoding %v: %v" , initial , string (b ), err )
393
+ }
394
+ if ! final .Equal (& initial ) {
395
+ diag , err := cbor .Diagnose (b )
396
+ if err != nil {
397
+ t .Logf ("failed to produce diagnostic encoding of 0x%x: %v" , b , err )
398
+ }
399
+ t .Errorf ("expected equal: %v, %v (cbor was '%s')" , initial , final , diag )
400
+ }
401
+ }
402
+ }
0 commit comments