1// Copyright 2016 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package ptypes 6 7import ( 8 "math" 9 "testing" 10 "time" 11 12 "github.com/golang/protobuf/proto" 13 14 durpb "github.com/golang/protobuf/ptypes/duration" 15) 16 17const ( 18 minGoSeconds = math.MinInt64 / int64(1e9) 19 maxGoSeconds = math.MaxInt64 / int64(1e9) 20) 21 22var durationTests = []struct { 23 proto *durpb.Duration 24 isValid bool 25 inRange bool 26 dur time.Duration 27}{ 28 // The zero duration. 29 {&durpb.Duration{Seconds: 0, Nanos: 0}, true, true, 0}, 30 // Some ordinary non-zero durations. 31 {&durpb.Duration{Seconds: 100, Nanos: 0}, true, true, 100 * time.Second}, 32 {&durpb.Duration{Seconds: -100, Nanos: 0}, true, true, -100 * time.Second}, 33 {&durpb.Duration{Seconds: 100, Nanos: 987}, true, true, 100*time.Second + 987}, 34 {&durpb.Duration{Seconds: -100, Nanos: -987}, true, true, -(100*time.Second + 987)}, 35 // The largest duration representable in Go. 36 {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, true, math.MaxInt64}, 37 // The smallest duration representable in Go. 38 {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, true, math.MinInt64}, 39 {nil, false, false, 0}, 40 {&durpb.Duration{Seconds: -100, Nanos: 987}, false, false, 0}, 41 {&durpb.Duration{Seconds: 100, Nanos: -987}, false, false, 0}, 42 {&durpb.Duration{Seconds: math.MinInt64, Nanos: 0}, false, false, 0}, 43 {&durpb.Duration{Seconds: math.MaxInt64, Nanos: 0}, false, false, 0}, 44 // The largest valid duration. 45 {&durpb.Duration{Seconds: maxSeconds, Nanos: 1e9 - 1}, true, false, 0}, 46 // The smallest valid duration. 47 {&durpb.Duration{Seconds: minSeconds, Nanos: -(1e9 - 1)}, true, false, 0}, 48 // The smallest invalid duration above the valid range. 49 {&durpb.Duration{Seconds: maxSeconds + 1, Nanos: 0}, false, false, 0}, 50 // The largest invalid duration below the valid range. 51 {&durpb.Duration{Seconds: minSeconds - 1, Nanos: -(1e9 - 1)}, false, false, 0}, 52 // One nanosecond past the largest duration representable in Go. 53 {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, true, false, 0}, 54 // One nanosecond past the smallest duration representable in Go. 55 {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64-1e9*minGoSeconds) - 1}, true, false, 0}, 56 // One second past the largest duration representable in Go. 57 {&durpb.Duration{Seconds: maxGoSeconds + 1, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, false, 0}, 58 // One second past the smallest duration representable in Go. 59 {&durpb.Duration{Seconds: minGoSeconds - 1, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, false, 0}, 60} 61 62func TestValidateDuration(t *testing.T) { 63 for _, test := range durationTests { 64 err := validateDuration(test.proto) 65 gotValid := (err == nil) 66 if gotValid != test.isValid { 67 t.Errorf("validateDuration(%v) = %t, want %t", test.proto, gotValid, test.isValid) 68 } 69 } 70} 71 72func TestDuration(t *testing.T) { 73 for _, test := range durationTests { 74 got, err := Duration(test.proto) 75 gotOK := (err == nil) 76 wantOK := test.isValid && test.inRange 77 if gotOK != wantOK { 78 t.Errorf("Duration(%v) ok = %t, want %t", test.proto, gotOK, wantOK) 79 } 80 if err == nil && got != test.dur { 81 t.Errorf("Duration(%v) = %v, want %v", test.proto, got, test.dur) 82 } 83 } 84} 85 86func TestDurationProto(t *testing.T) { 87 for _, test := range durationTests { 88 if test.isValid && test.inRange { 89 got := DurationProto(test.dur) 90 if !proto.Equal(got, test.proto) { 91 t.Errorf("DurationProto(%v) = %v, want %v", test.dur, got, test.proto) 92 } 93 } 94 } 95} 96