Skip to content

Commit b4db414

Browse files
haoruank8s-publishing-bot
authored andcommitted
Marshal MicroTime to json and proto at the same precision
Kubernetes-commit: 519e0d0a94b02ba32701afeaad5a388777836d62
1 parent cf171ba commit b4db414

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

pkg/apis/meta/v1/micro_time_proto.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ func (m *MicroTime) ProtoMicroTime() *Timestamp {
2727
if m == nil {
2828
return &Timestamp{}
2929
}
30+
31+
// truncate precision to microseconds to match JSON marshaling/unmarshaling
32+
truncatedNanoseconds := time.Duration(m.Time.Nanosecond()).Truncate(time.Microsecond)
3033
return &Timestamp{
3134
Seconds: m.Time.Unix(),
32-
Nanos: int32(m.Time.Nanosecond()),
35+
Nanos: int32(truncatedNanoseconds),
3336
}
3437
}
3538

@@ -51,7 +54,10 @@ func (m *MicroTime) Unmarshal(data []byte) error {
5154
if err := p.Unmarshal(data); err != nil {
5255
return err
5356
}
54-
m.Time = time.Unix(p.Seconds, int64(p.Nanos)).Local()
57+
58+
// truncate precision to microseconds to match JSON marshaling/unmarshaling
59+
truncatedNanoseconds := time.Duration(p.Nanos).Truncate(time.Microsecond)
60+
m.Time = time.Unix(p.Seconds, int64(truncatedNanoseconds)).Local()
5561
return nil
5662
}
5763

pkg/apis/meta/v1/micro_time_test.go

+66-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func TestMicroTimeProto(t *testing.T) {
118118
input MicroTime
119119
}{
120120
{MicroTime{}},
121-
{DateMicro(1998, time.May, 5, 1, 5, 5, 50, time.Local)},
121+
{DateMicro(1998, time.May, 5, 1, 5, 5, 1000, time.Local)},
122122
{DateMicro(1998, time.May, 5, 5, 5, 5, 0, time.Local)},
123123
}
124124

@@ -253,3 +253,68 @@ func TestMicroTimeIsZero(t *testing.T) {
253253
})
254254
}
255255
}
256+
257+
func TestMicroTimeUnmarshalJSONAndProtoEqual(t *testing.T) {
258+
cases := []struct {
259+
name string
260+
input MicroTime
261+
result bool
262+
}{
263+
{"nanosecond level precision", UnixMicro(123, 123123123), true},
264+
{"microsecond level precision", UnixMicro(123, 123123000), true},
265+
}
266+
267+
for _, c := range cases {
268+
t.Run(c.name, func(t *testing.T) {
269+
jsonData, err := c.input.MarshalJSON()
270+
if err != nil {
271+
t.Fatalf("Failed to marshal input to JSON: '%v': %v", c.input, err)
272+
}
273+
274+
protoData, err := c.input.Marshal()
275+
if err != nil {
276+
t.Fatalf("Failed to marshal input to proto: '%v': %v", c.input, err)
277+
}
278+
279+
var tJSON, tProto MicroTime
280+
if err = tJSON.UnmarshalJSON(jsonData); err != nil {
281+
t.Fatalf("Failed to unmarshal JSON: '%v': %v", jsonData, err)
282+
}
283+
if err = tProto.Unmarshal(protoData); err != nil {
284+
t.Fatalf("Failed to unmarshal proto: '%v': %v", protoData, err)
285+
}
286+
287+
result := tJSON.Equal(&tProto)
288+
if result != c.result {
289+
t.Errorf("Failed equality test for '%v': expected %+v, got %+v", c.input, c.result, result)
290+
}
291+
})
292+
}
293+
}
294+
295+
func TestMicroTimeProtoUnmarshalRaw(t *testing.T) {
296+
cases := []struct {
297+
name string
298+
input []byte
299+
expected MicroTime
300+
}{
301+
// input is generated by Timestamp{123, 123123123}.Marshal()
302+
{"nanosecond level precision", []byte{8, 123, 16, 179, 235, 218, 58}, UnixMicro(123, 123123000)},
303+
// input is generated by Timestamp{123, 123123000}.Marshal()
304+
{"microsecond level precision", []byte{8, 123, 16, 184, 234, 218, 58}, UnixMicro(123, 123123000)},
305+
}
306+
307+
for _, c := range cases {
308+
t.Run(c.name, func(t *testing.T) {
309+
var actual MicroTime
310+
if err := actual.Unmarshal(c.input); err != nil {
311+
t.Fatalf("Failed to unmarshal proto: '%v': %v", c.input, err)
312+
}
313+
314+
if !actual.Equal(&c.expected) {
315+
t.Errorf("Failed unmarshal from nanosecond-precise raw for '%v': expected %+v, got %+v", c.input, c.expected, actual)
316+
}
317+
})
318+
}
319+
320+
}

0 commit comments

Comments
 (0)