4
4
"encoding/hex"
5
5
"fmt"
6
6
"log"
7
+ "math"
7
8
"os"
8
9
"reflect"
9
10
"testing"
@@ -73,6 +74,125 @@ func assertDatetimeIsEqual(t *testing.T, tuples []interface{}, tm time.Time) {
73
74
}
74
75
}
75
76
77
+ func TestTimezonesIndexMapping (t * testing.T ) {
78
+ for _ , index := range TimezoneToIndex {
79
+ if _ , ok := IndexToTimezone [index ]; ! ok {
80
+ t .Errorf ("index %d not found" , index )
81
+ }
82
+ }
83
+ }
84
+
85
+ func TestTimezonesZonesMapping (t * testing.T ) {
86
+ for _ , zone := range IndexToTimezone {
87
+ if _ , ok := TimezoneToIndex [zone ]; ! ok {
88
+ t .Errorf ("zone %s not found" , zone )
89
+ }
90
+ }
91
+ }
92
+
93
+ func TestInvalidTimezone (t * testing.T ) {
94
+ invalidLoc := time .FixedZone ("AnyInvalid" , 0 )
95
+ tm , err := time .Parse (time .RFC3339 , "2010-08-12T11:39:14Z" )
96
+ if err != nil {
97
+ t .Fatalf ("Time parse failed: %s" , err )
98
+ }
99
+ tm = tm .In (invalidLoc )
100
+ dt , err := NewDatetime (tm )
101
+ if err == nil {
102
+ t .Fatalf ("Unexpected success: %v" , dt )
103
+ }
104
+ }
105
+
106
+ func TestInvalidOffset (t * testing.T ) {
107
+ tests := []struct {
108
+ ok bool
109
+ offset int
110
+ }{
111
+ {ok : true , offset : math .MinInt16 * 60 },
112
+ {ok : true , offset : (math .MinInt16 + 1 ) * 60 },
113
+ {ok : true , offset : (math .MaxInt16 - 1 ) * 60 },
114
+ {ok : true , offset : math .MaxInt16 * 60 },
115
+ {ok : false , offset : (math .MinInt16 - 1 ) * 60 },
116
+ {ok : false , offset : (math .MaxInt16 + 1 ) * 60 },
117
+ }
118
+
119
+ for _ , testcase := range tests {
120
+ name := ""
121
+ if testcase .ok {
122
+ name = fmt .Sprintf ("in_boundary_%d" , testcase .offset )
123
+ } else {
124
+ name = fmt .Sprintf ("out_of_boundary_%d" , testcase .offset )
125
+ }
126
+ t .Run (name , func (t * testing.T ) {
127
+ loc := time .FixedZone ("MSK" , testcase .offset )
128
+ tm , err := time .Parse (time .RFC3339 , "2010-08-12T11:39:14Z" )
129
+ if err != nil {
130
+ t .Fatalf ("Time parse failed: %s" , err )
131
+ }
132
+ tm = tm .In (loc )
133
+ dt , err := NewDatetime (tm )
134
+ if testcase .ok && err != nil {
135
+ t .Fatalf ("Unexpected error: %s" , err .Error ())
136
+ }
137
+ if ! testcase .ok && err == nil {
138
+ t .Fatalf ("Unexpected success: %v" , dt )
139
+ }
140
+ if testcase .ok && isDatetimeSupported {
141
+ conn := test_helpers .ConnectWithValidation (t , server , opts )
142
+ defer conn .Close ()
143
+
144
+ tupleInsertSelectDelete (t , conn , tm )
145
+ }
146
+ })
147
+ }
148
+ }
149
+
150
+ func TestCustomTimezone (t * testing.T ) {
151
+ skipIfDatetimeUnsupported (t )
152
+
153
+ conn := test_helpers .ConnectWithValidation (t , server , opts )
154
+ defer conn .Close ()
155
+
156
+ customZone := "Europe/Moscow"
157
+ customOffset := 180 * 60
158
+
159
+ customLoc := time .FixedZone (customZone , customOffset )
160
+ tm , err := time .Parse (time .RFC3339 , "2010-08-12T11:44:14Z" )
161
+ if err != nil {
162
+ t .Fatalf ("Time parse failed: %s" , err )
163
+ }
164
+ tm = tm .In (customLoc )
165
+ dt , err := NewDatetime (tm )
166
+ if err != nil {
167
+ t .Fatalf ("Unable to create datetime: %s" , err .Error ())
168
+ }
169
+
170
+ resp , err := conn .Replace (spaceTuple1 , []interface {}{dt , "payload" })
171
+ if err != nil {
172
+ t .Fatalf ("Datetime replace failed %s" , err .Error ())
173
+ }
174
+ assertDatetimeIsEqual (t , resp .Data , tm )
175
+
176
+ tpl := resp .Data [0 ].([]interface {})
177
+ if respDt , ok := toDatetime (tpl [0 ]); ok {
178
+ zone , offset := respDt .ToTime ().Zone ()
179
+ if zone != customZone {
180
+ t .Fatalf ("Expected zone %s instead of %s" , customZone , zone )
181
+ }
182
+ if offset != customOffset {
183
+ t .Fatalf ("Expected offset %d instead of %d" , customOffset , offset )
184
+ }
185
+
186
+ _ , err = conn .Delete (spaceTuple1 , 0 , []interface {}{dt })
187
+ if err != nil {
188
+ t .Fatalf ("Datetime delete failed: %s" , err .Error ())
189
+ }
190
+ } else {
191
+ t .Fatalf ("datetime doesn't match" )
192
+ }
193
+
194
+ }
195
+
76
196
func tupleInsertSelectDelete (t * testing.T , conn * Connection , tm time.Time ) {
77
197
t .Helper ()
78
198
@@ -111,61 +231,65 @@ func tupleInsertSelectDelete(t *testing.T, conn *Connection, tm time.Time) {
111
231
}
112
232
113
233
var datetimeSample = []struct {
234
+ fmt string
114
235
dt string
115
236
mpBuf string // MessagePack buffer.
116
237
}{
117
- {"2012-01-31T23:59:59.000000010Z" , "d8047f80284f000000000a00000000000000" },
118
- {"1970-01-01T00:00:00.000000010Z" , "d80400000000000000000a00000000000000" },
119
- {"2010-08-12T11:39:14Z" , "d70462dd634c00000000" },
120
- {"1984-03-24T18:04:05Z" , "d7041530c31a00000000" },
121
- {"2010-01-12T00:00:00Z" , "d70480bb4b4b00000000" },
122
- {"1970-01-01T00:00:00Z" , "d7040000000000000000" },
123
- {"1970-01-01T00:00:00.123456789Z" , "d804000000000000000015cd5b0700000000" },
124
- {"1970-01-01T00:00:00.12345678Z" , "d80400000000000000000ccd5b0700000000" },
125
- {"1970-01-01T00:00:00.1234567Z" , "d8040000000000000000bccc5b0700000000" },
126
- {"1970-01-01T00:00:00.123456Z" , "d804000000000000000000ca5b0700000000" },
127
- {"1970-01-01T00:00:00.12345Z" , "d804000000000000000090b25b0700000000" },
128
- {"1970-01-01T00:00:00.1234Z" , "d804000000000000000040ef5a0700000000" },
129
- {"1970-01-01T00:00:00.123Z" , "d8040000000000000000c0d4540700000000" },
130
- {"1970-01-01T00:00:00.12Z" , "d8040000000000000000000e270700000000" },
131
- {"1970-01-01T00:00:00.1Z" , "d804000000000000000000e1f50500000000" },
132
- {"1970-01-01T00:00:00.01Z" , "d80400000000000000008096980000000000" },
133
- {"1970-01-01T00:00:00.001Z" , "d804000000000000000040420f0000000000" },
134
- {"1970-01-01T00:00:00.0001Z" , "d8040000000000000000a086010000000000" },
135
- {"1970-01-01T00:00:00.00001Z" , "d80400000000000000001027000000000000" },
136
- {"1970-01-01T00:00:00.000001Z" , "d8040000000000000000e803000000000000" },
137
- {"1970-01-01T00:00:00.0000001Z" , "d80400000000000000006400000000000000" },
138
- {"1970-01-01T00:00:00.00000001Z" , "d80400000000000000000a00000000000000" },
139
- {"1970-01-01T00:00:00.000000001Z" , "d80400000000000000000100000000000000" },
140
- {"1970-01-01T00:00:00.000000009Z" , "d80400000000000000000900000000000000" },
141
- {"1970-01-01T00:00:00.00000009Z" , "d80400000000000000005a00000000000000" },
142
- {"1970-01-01T00:00:00.0000009Z" , "d80400000000000000008403000000000000" },
143
- {"1970-01-01T00:00:00.000009Z" , "d80400000000000000002823000000000000" },
144
- {"1970-01-01T00:00:00.00009Z" , "d8040000000000000000905f010000000000" },
145
- {"1970-01-01T00:00:00.0009Z" , "d8040000000000000000a0bb0d0000000000" },
146
- {"1970-01-01T00:00:00.009Z" , "d80400000000000000004054890000000000" },
147
- {"1970-01-01T00:00:00.09Z" , "d8040000000000000000804a5d0500000000" },
148
- {"1970-01-01T00:00:00.9Z" , "d804000000000000000000e9a43500000000" },
149
- {"1970-01-01T00:00:00.99Z" , "d80400000000000000008033023b00000000" },
150
- {"1970-01-01T00:00:00.999Z" , "d8040000000000000000c0878b3b00000000" },
151
- {"1970-01-01T00:00:00.9999Z" , "d80400000000000000006043993b00000000" },
152
- {"1970-01-01T00:00:00.99999Z" , "d8040000000000000000f0a29a3b00000000" },
153
- {"1970-01-01T00:00:00.999999Z" , "d804000000000000000018c69a3b00000000" },
154
- {"1970-01-01T00:00:00.9999999Z" , "d80400000000000000009cc99a3b00000000" },
155
- {"1970-01-01T00:00:00.99999999Z" , "d8040000000000000000f6c99a3b00000000" },
156
- {"1970-01-01T00:00:00.999999999Z" , "d8040000000000000000ffc99a3b00000000" },
157
- {"1970-01-01T00:00:00.0Z" , "d7040000000000000000" },
158
- {"1970-01-01T00:00:00.00Z" , "d7040000000000000000" },
159
- {"1970-01-01T00:00:00.000Z" , "d7040000000000000000" },
160
- {"1970-01-01T00:00:00.0000Z" , "d7040000000000000000" },
161
- {"1970-01-01T00:00:00.00000Z" , "d7040000000000000000" },
162
- {"1970-01-01T00:00:00.000000Z" , "d7040000000000000000" },
163
- {"1970-01-01T00:00:00.0000000Z" , "d7040000000000000000" },
164
- {"1970-01-01T00:00:00.00000000Z" , "d7040000000000000000" },
165
- {"1970-01-01T00:00:00.000000000Z" , "d7040000000000000000" },
166
- {"1973-11-29T21:33:09Z" , "d70415cd5b0700000000" },
167
- {"2013-10-28T17:51:56Z" , "d7043ca46e5200000000" },
168
- {"9999-12-31T23:59:59Z" , "d7047f41f4ff3a000000" },
238
+ /* Cases for base encoding without a timezone. */
239
+ {time .RFC3339 , "2012-01-31T23:59:59.000000010Z" , "d8047f80284f000000000a00000000000000" },
240
+ {time .RFC3339 , "1970-01-01T00:00:00.000000010Z" , "d80400000000000000000a00000000000000" },
241
+ {time .RFC3339 , "2010-08-12T11:39:14Z" , "d70462dd634c00000000" },
242
+ {time .RFC3339 , "1984-03-24T18:04:05Z" , "d7041530c31a00000000" },
243
+ {time .RFC3339 , "2010-01-12T00:00:00Z" , "d70480bb4b4b00000000" },
244
+ {time .RFC3339 , "1970-01-01T00:00:00Z" , "d7040000000000000000" },
245
+ {time .RFC3339 , "1970-01-01T00:00:00.123456789Z" , "d804000000000000000015cd5b0700000000" },
246
+ {time .RFC3339 , "1970-01-01T00:00:00.12345678Z" , "d80400000000000000000ccd5b0700000000" },
247
+ {time .RFC3339 , "1970-01-01T00:00:00.1234567Z" , "d8040000000000000000bccc5b0700000000" },
248
+ {time .RFC3339 , "1970-01-01T00:00:00.123456Z" , "d804000000000000000000ca5b0700000000" },
249
+ {time .RFC3339 , "1970-01-01T00:00:00.12345Z" , "d804000000000000000090b25b0700000000" },
250
+ {time .RFC3339 , "1970-01-01T00:00:00.1234Z" , "d804000000000000000040ef5a0700000000" },
251
+ {time .RFC3339 , "1970-01-01T00:00:00.123Z" , "d8040000000000000000c0d4540700000000" },
252
+ {time .RFC3339 , "1970-01-01T00:00:00.12Z" , "d8040000000000000000000e270700000000" },
253
+ {time .RFC3339 , "1970-01-01T00:00:00.1Z" , "d804000000000000000000e1f50500000000" },
254
+ {time .RFC3339 , "1970-01-01T00:00:00.01Z" , "d80400000000000000008096980000000000" },
255
+ {time .RFC3339 , "1970-01-01T00:00:00.001Z" , "d804000000000000000040420f0000000000" },
256
+ {time .RFC3339 , "1970-01-01T00:00:00.0001Z" , "d8040000000000000000a086010000000000" },
257
+ {time .RFC3339 , "1970-01-01T00:00:00.00001Z" , "d80400000000000000001027000000000000" },
258
+ {time .RFC3339 , "1970-01-01T00:00:00.000001Z" , "d8040000000000000000e803000000000000" },
259
+ {time .RFC3339 , "1970-01-01T00:00:00.0000001Z" , "d80400000000000000006400000000000000" },
260
+ {time .RFC3339 , "1970-01-01T00:00:00.00000001Z" , "d80400000000000000000a00000000000000" },
261
+ {time .RFC3339 , "1970-01-01T00:00:00.000000001Z" , "d80400000000000000000100000000000000" },
262
+ {time .RFC3339 , "1970-01-01T00:00:00.000000009Z" , "d80400000000000000000900000000000000" },
263
+ {time .RFC3339 , "1970-01-01T00:00:00.00000009Z" , "d80400000000000000005a00000000000000" },
264
+ {time .RFC3339 , "1970-01-01T00:00:00.0000009Z" , "d80400000000000000008403000000000000" },
265
+ {time .RFC3339 , "1970-01-01T00:00:00.000009Z" , "d80400000000000000002823000000000000" },
266
+ {time .RFC3339 , "1970-01-01T00:00:00.00009Z" , "d8040000000000000000905f010000000000" },
267
+ {time .RFC3339 , "1970-01-01T00:00:00.0009Z" , "d8040000000000000000a0bb0d0000000000" },
268
+ {time .RFC3339 , "1970-01-01T00:00:00.009Z" , "d80400000000000000004054890000000000" },
269
+ {time .RFC3339 , "1970-01-01T00:00:00.09Z" , "d8040000000000000000804a5d0500000000" },
270
+ {time .RFC3339 , "1970-01-01T00:00:00.9Z" , "d804000000000000000000e9a43500000000" },
271
+ {time .RFC3339 , "1970-01-01T00:00:00.99Z" , "d80400000000000000008033023b00000000" },
272
+ {time .RFC3339 , "1970-01-01T00:00:00.999Z" , "d8040000000000000000c0878b3b00000000" },
273
+ {time .RFC3339 , "1970-01-01T00:00:00.9999Z" , "d80400000000000000006043993b00000000" },
274
+ {time .RFC3339 , "1970-01-01T00:00:00.99999Z" , "d8040000000000000000f0a29a3b00000000" },
275
+ {time .RFC3339 , "1970-01-01T00:00:00.999999Z" , "d804000000000000000018c69a3b00000000" },
276
+ {time .RFC3339 , "1970-01-01T00:00:00.9999999Z" , "d80400000000000000009cc99a3b00000000" },
277
+ {time .RFC3339 , "1970-01-01T00:00:00.99999999Z" , "d8040000000000000000f6c99a3b00000000" },
278
+ {time .RFC3339 , "1970-01-01T00:00:00.999999999Z" , "d8040000000000000000ffc99a3b00000000" },
279
+ {time .RFC3339 , "1970-01-01T00:00:00.0Z" , "d7040000000000000000" },
280
+ {time .RFC3339 , "1970-01-01T00:00:00.00Z" , "d7040000000000000000" },
281
+ {time .RFC3339 , "1970-01-01T00:00:00.000Z" , "d7040000000000000000" },
282
+ {time .RFC3339 , "1970-01-01T00:00:00.0000Z" , "d7040000000000000000" },
283
+ {time .RFC3339 , "1970-01-01T00:00:00.00000Z" , "d7040000000000000000" },
284
+ {time .RFC3339 , "1970-01-01T00:00:00.000000Z" , "d7040000000000000000" },
285
+ {time .RFC3339 , "1970-01-01T00:00:00.0000000Z" , "d7040000000000000000" },
286
+ {time .RFC3339 , "1970-01-01T00:00:00.00000000Z" , "d7040000000000000000" },
287
+ {time .RFC3339 , "1970-01-01T00:00:00.000000000Z" , "d7040000000000000000" },
288
+ {time .RFC3339 , "1973-11-29T21:33:09Z" , "d70415cd5b0700000000" },
289
+ {time .RFC3339 , "2013-10-28T17:51:56Z" , "d7043ca46e5200000000" },
290
+ {time .RFC3339 , "9999-12-31T23:59:59Z" , "d7047f41f4ff3a000000" },
291
+ /* Cases for encoding with a timezone. */
292
+ {time .RFC3339 + " MST" , "2006-01-02T15:04:00+03:00 MSK" , "d804b016b9430000000000000000b400ee00" },
169
293
}
170
294
171
295
func TestDatetimeInsertSelectDelete (t * testing.T ) {
@@ -176,7 +300,10 @@ func TestDatetimeInsertSelectDelete(t *testing.T) {
176
300
177
301
for _ , testcase := range datetimeSample {
178
302
t .Run (testcase .dt , func (t * testing.T ) {
179
- tm , err := time .Parse (time .RFC3339 , testcase .dt )
303
+ tm , err := time .Parse (testcase .fmt , testcase .dt )
304
+ if testcase .fmt == time .RFC3339 {
305
+ tm = tm .In (NoTimezone )
306
+ }
180
307
if err != nil {
181
308
t .Fatalf ("Time (%s) parse failed: %s" , testcase .dt , err )
182
309
}
@@ -519,7 +646,10 @@ func TestCustomEncodeDecodeTuple5(t *testing.T) {
519
646
func TestMPEncode (t * testing.T ) {
520
647
for _ , testcase := range datetimeSample {
521
648
t .Run (testcase .dt , func (t * testing.T ) {
522
- tm , err := time .Parse (time .RFC3339 , testcase .dt )
649
+ tm , err := time .Parse (testcase .fmt , testcase .dt )
650
+ if testcase .fmt == time .RFC3339 {
651
+ tm = tm .In (NoTimezone )
652
+ }
523
653
if err != nil {
524
654
t .Fatalf ("Time (%s) parse failed: %s" , testcase .dt , err )
525
655
}
@@ -533,7 +663,7 @@ func TestMPEncode(t *testing.T) {
533
663
}
534
664
refBuf , _ := hex .DecodeString (testcase .mpBuf )
535
665
if reflect .DeepEqual (buf , refBuf ) != true {
536
- t .Fatalf ("Failed to encode datetime '%s', actual %v , expected %v " ,
666
+ t .Fatalf ("Failed to encode datetime '%s', actual %x , expected %x " ,
537
667
testcase .dt ,
538
668
buf ,
539
669
refBuf )
@@ -545,7 +675,10 @@ func TestMPEncode(t *testing.T) {
545
675
func TestMPDecode (t * testing.T ) {
546
676
for _ , testcase := range datetimeSample {
547
677
t .Run (testcase .dt , func (t * testing.T ) {
548
- tm , err := time .Parse (time .RFC3339 , testcase .dt )
678
+ tm , err := time .Parse (testcase .fmt , testcase .dt )
679
+ if testcase .fmt == time .RFC3339 {
680
+ tm = tm .In (NoTimezone )
681
+ }
549
682
if err != nil {
550
683
t .Fatalf ("Time (%s) parse failed: %s" , testcase .dt , err )
551
684
}
@@ -565,6 +698,31 @@ func TestMPDecode(t *testing.T) {
565
698
}
566
699
}
567
700
701
+ func TestUnmarshalMsgpackInvalidLength (t * testing.T ) {
702
+ var v Datetime
703
+
704
+ err := v .UnmarshalMsgpack ([]byte {0x04 })
705
+ if err == nil {
706
+ t .Fatalf ("Unexpected success %v." , v )
707
+ }
708
+ if err .Error () != "Invalid data length: got 1, wanted 8 or 16" {
709
+ t .Fatalf ("Unexpected error: %s" , err .Error ())
710
+ }
711
+ }
712
+
713
+ func TestUnmarshalMsgpackInvalidZone (t * testing.T ) {
714
+ var v Datetime
715
+
716
+ buf , _ := hex .DecodeString ("b016b9430000000000000000b400ee01" )
717
+ err := v .UnmarshalMsgpack (buf )
718
+ if err == nil {
719
+ t .Fatalf ("Unexpected success %v." , v )
720
+ }
721
+ if err .Error () != "Unknown timezone index 494" {
722
+ t .Fatalf ("Unexpected error: %s" , err .Error ())
723
+ }
724
+ }
725
+
568
726
// runTestMain is a body of TestMain function
569
727
// (see https://pkg.go.dev/testing#hdr-Main).
570
728
// Using defer + os.Exit is not works so TestMain body
0 commit comments