github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/parse_time_test.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "testing" 22 ) 23 24 var parseDurationTests = []struct { 25 in string 26 ok bool 27 want Duration 28 }{ 29 // simple 30 {"0", true, 0}, 31 {"5s", true, 5 * Second}, 32 {"30s", true, 30 * Second}, 33 {"1478s", true, 1478 * Second}, 34 // sign 35 {"-5s", true, -5 * Second}, 36 {"+5s", true, 5 * Second}, 37 {"-0", true, 0}, 38 {"+0", true, 0}, 39 // decimal 40 {"5.0s", true, 5 * Second}, 41 {"5.6s", true, 5*Second + 600*Millisecond}, 42 {"5.s", true, 5 * Second}, 43 {".5s", true, 500 * Millisecond}, 44 {"1.0s", true, 1 * Second}, 45 {"1.00s", true, 1 * Second}, 46 {"1.004s", true, 1*Second + 4*Millisecond}, 47 {"1.0040s", true, 1*Second + 4*Millisecond}, 48 {"100.00100s", true, 100*Second + 1*Millisecond}, 49 // different units 50 {"10ns", true, 10 * Nanosecond}, 51 {"11us", true, 11 * Microsecond}, 52 {"12µs", true, 12 * Microsecond}, // U+00B5 53 {"12μs", true, 12 * Microsecond}, // U+03BC 54 {"13ms", true, 13 * Millisecond}, 55 {"14s", true, 14 * Second}, 56 {"15m", true, 15 * Minute}, 57 {"16h", true, 16 * Hour}, 58 {"12d", true, 12 * Day}, 59 {"3w", true, 3 * Week}, 60 // composite durations 61 {"3h30m", true, 3*Hour + 30*Minute}, 62 {"10.5s4m", true, 4*Minute + 10*Second + 500*Millisecond}, 63 {"-2m3.4s", true, -(2*Minute + 3*Second + 400*Millisecond)}, 64 {"1h2m3s4ms5us6ns", true, 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond}, 65 {"39h9m14.425s", true, 39*Hour + 9*Minute + 14*Second + 425*Millisecond}, 66 {"2w3d12h", true, 2*Week + 3*Day + 12*Hour}, 67 // large value 68 {"52763797000ns", true, 52763797000 * Nanosecond}, 69 // more than 9 digits after decimal point, see https://golang.org/issue/6617 70 {"0.3333333333333333333h", true, 20 * Minute}, 71 // 9007199254740993 = 1<<53+1 cannot be stored precisely in a float64 72 {"9007199254740993ns", true, (1<<53 + 1) * Nanosecond}, 73 // largest duration that can be represented by int64 in nanoseconds 74 {"9223372036854775807ns", true, (1<<63 - 1) * Nanosecond}, 75 {"9223372036854775.807us", true, (1<<63 - 1) * Nanosecond}, 76 {"9223372036s854ms775us807ns", true, (1<<63 - 1) * Nanosecond}, 77 // large negative value 78 {"-9223372036854775807ns", true, -1<<63 + 1*Nanosecond}, 79 80 // errors 81 {"", false, 0}, 82 {"3", false, 0}, 83 {"-", false, 0}, 84 {"s", false, 0}, 85 {".", false, 0}, 86 {"-.", false, 0}, 87 {".s", false, 0}, 88 {"+.s", false, 0}, 89 {"3000000h", false, 0}, // overflow 90 {"9223372036854775808ns", false, 0}, // overflow 91 {"9223372036854775.808us", false, 0}, // overflow 92 {"9223372036854ms775us808ns", false, 0}, // overflow 93 // largest negative value of type int64 in nanoseconds should fail 94 // see https://go-review.googlesource.com/#/c/2461/ 95 {"-9223372036854775808ns", false, 0}, 96 } 97 98 func TestParseDuration(t *testing.T) { 99 for _, tc := range parseDurationTests { 100 t.Run(tc.in, func(t *testing.T) { 101 d, err := ParseDuration(tc.in) 102 if tc.ok && (err != nil || d != tc.want) { 103 t.Errorf("ParseDuration(%q) = %v, %v, want %v, nil", tc.in, d, err, tc.want) 104 } else if !tc.ok && err == nil { 105 t.Errorf("ParseDuration(%q) = _, nil, want _, non-nil", tc.in) 106 } 107 }) 108 } 109 } 110 111 // Test for ParseDurationTime. Validates the returned value 112 // for given time value in days, hours and minute format. 113 func TestParseDurationTime(t *testing.T) { 114 testCases := []struct { 115 timeValue string 116 expected Duration 117 err string 118 }{ 119 // Test 1: empty string as input 120 {"", 0, "invalid empty duration"}, 121 // Test 2: Input string contains 4 day, 10 hour and 3 minutes 122 {"4d10h3m", 381780000000000, ""}, 123 // Test 3: Input string contains 10 day and 3 hours 124 {"10d3h", 874800000000000, ""}, 125 // Test 4: Input string contains minutes and days 126 {"3m7d", 604980000000000, ""}, 127 // Test 5: Input string contains unknown unit 128 {"4a3d", 0, "unknown unit a in duration 4a3d"}, 129 // Test 6: Input string contains fractional day 130 {"1.5d", 129600000000000, ""}, 131 // Test 6: Input string contains fractional day and hour 132 {"2.5d1.5h", 221400000000000, ""}, 133 // Test 7: Input string contains fractional day , hour and minute 134 {"2.5d1.5h3.5m", 221610000000000, ""}, 135 } 136 137 for _, testCase := range testCases { 138 testCase := testCase 139 t.Run("", func(t *testing.T) { 140 myVal, err := ParseDuration(testCase.timeValue) 141 if err != nil && err.Error() != testCase.err { 142 t.Error() 143 } 144 if myVal != testCase.expected { 145 t.Errorf("Expected %v, got %v", testCase.expected, myVal) 146 } 147 }) 148 } 149 }