| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package helper | |
| 6 | |
| 7 import ( | |
| 8 "bytes" | |
| 9 "io" | |
| 10 "testing" | |
| 11 "time" | |
| 12 | |
| 13 "github.com/luci/gae" | |
| 14 "github.com/luci/luci-go/common/cmpbin" | |
| 15 . "github.com/smartystreets/goconvey/convey" | |
| 16 ) | |
| 17 | |
| 18 func init() { | |
| 19 WriteDSPropertyMapDeterministic = true | |
| 20 } | |
| 21 | |
| 22 type dspmapTC struct { | |
| 23 name string | |
| 24 props gae.DSPropertyMap | |
| 25 } | |
| 26 | |
| 27 func TestDSPropertyMapSerialization(t *testing.T) { | |
| 28 t.Parallel() | |
| 29 | |
| 30 tests := []dspmapTC{ | |
| 31 { | |
| 32 "basic", | |
| 33 gae.DSPropertyMap{ | |
| 34 "R": {mp(false), mp(2.1), mpNI(3)}, | |
| 35 "S": {mp("hello"), mp("world")}, | |
| 36 }, | |
| 37 }, | |
| 38 { | |
| 39 "keys", | |
| 40 gae.DSPropertyMap{ | |
| 41 "DS": {mp(mkKey("appy", "ns", "Foo", 7)), mp(mkK
ey("other", "", "Yot", "wheeep"))}, | |
| 42 "BS": {mp(gae.BSKey("sup")), mp(gae.BSKey("nerds
"))}, | |
| 43 }, | |
| 44 }, | |
| 45 { | |
| 46 "geo", | |
| 47 gae.DSPropertyMap{ | |
| 48 "G": {mp(gae.DSGeoPoint{Lat: 1, Lng: 2})}, | |
| 49 }, | |
| 50 }, | |
| 51 { | |
| 52 "data", | |
| 53 gae.DSPropertyMap{ | |
| 54 "S": {mp("sup"), mp("fool"), mp("nerd")
}, | |
| 55 "D.Foo.Nerd": {mp([]byte("sup")), mp([]byte("foo
l"))}, | |
| 56 "B": {mp(gae.DSByteString("sup")), mp(g
ae.DSByteString("fool"))}, | |
| 57 }, | |
| 58 }, | |
| 59 { | |
| 60 "time", | |
| 61 gae.DSPropertyMap{ | |
| 62 "T": { | |
| 63 mp(time.Now().UTC()), | |
| 64 mp(time.Now().Add(time.Second).UTC())}, | |
| 65 }, | |
| 66 }, | |
| 67 { | |
| 68 "empty vals", | |
| 69 gae.DSPropertyMap{ | |
| 70 "T": {mp(true), mp(true)}, | |
| 71 "F": {mp(false), mp(false)}, | |
| 72 "N": {mp(nil), mp(nil)}, | |
| 73 "E": {}, | |
| 74 }, | |
| 75 }, | |
| 76 } | |
| 77 | |
| 78 Convey("DSPropertyMap serialization", t, func() { | |
| 79 Convey("round trip", func() { | |
| 80 for _, tc := range tests { | |
| 81 tc := tc | |
| 82 Convey(tc.name, func() { | |
| 83 buf := &bytes.Buffer{} | |
| 84 WriteDSPropertyMap(buf, tc.props, WithCo
ntext) | |
| 85 dec, err := ReadDSPropertyMap(buf, WithC
ontext, "", "") | |
| 86 So(err, ShouldBeNil) | |
| 87 So(dec, ShouldResemble, tc.props) | |
| 88 }) | |
| 89 } | |
| 90 }) | |
| 91 }) | |
| 92 } | |
| 93 | |
| 94 func TestSerializationReadMisc(t *testing.T) { | |
| 95 t.Parallel() | |
| 96 | |
| 97 Convey("Misc Serialization tests", t, func() { | |
| 98 Convey("ReadDSKey", func() { | |
| 99 Convey("good cases", func() { | |
| 100 Convey("w/ ctx decodes normally w/ ctx", func()
{ | |
| 101 k := mkKey("aid", "ns", "knd", "yo", "ot
her", 10) | |
| 102 buf := &bytes.Buffer{} | |
| 103 WriteDSKey(buf, WithContext, k) | |
| 104 dk, err := ReadDSKey(buf, WithContext, "
", "") | |
| 105 So(err, ShouldBeNil) | |
| 106 So(dk, ShouldEqualKey, k) | |
| 107 }) | |
| 108 Convey("w/ ctx decodes normally w/o ctx", func()
{ | |
| 109 k := mkKey("aid", "ns", "knd", "yo", "ot
her", 10) | |
| 110 buf := &bytes.Buffer{} | |
| 111 WriteDSKey(buf, WithContext, k) | |
| 112 dk, err := ReadDSKey(buf, WithoutContext
, "spam", "nerd") | |
| 113 So(err, ShouldBeNil) | |
| 114 So(dk, ShouldEqualKey, mkKey("spam", "ne
rd", "knd", "yo", "other", 10)) | |
| 115 }) | |
| 116 Convey("w/o ctx decodes normally w/ ctx", func()
{ | |
| 117 k := mkKey("aid", "ns", "knd", "yo", "ot
her", 10) | |
| 118 buf := &bytes.Buffer{} | |
| 119 WriteDSKey(buf, WithoutContext, k) | |
| 120 dk, err := ReadDSKey(buf, WithContext, "
spam", "nerd") | |
| 121 So(err, ShouldBeNil) | |
| 122 So(dk, ShouldEqualKey, mkKey("", "", "kn
d", "yo", "other", 10)) | |
| 123 }) | |
| 124 Convey("w/o ctx decodes normally w/o ctx", func(
) { | |
| 125 k := mkKey("aid", "ns", "knd", "yo", "ot
her", 10) | |
| 126 buf := &bytes.Buffer{} | |
| 127 WriteDSKey(buf, WithoutContext, k) | |
| 128 dk, err := ReadDSKey(buf, WithoutContext
, "spam", "nerd") | |
| 129 So(err, ShouldBeNil) | |
| 130 So(dk, ShouldEqualKey, mkKey("spam", "ne
rd", "knd", "yo", "other", 10)) | |
| 131 }) | |
| 132 Convey("IntIDs always sort before StringIDs", fu
nc() { | |
| 133 // -1 writes as almost all 1's in the fi
rst byte under cmpbin, even | |
| 134 // though it's technically not a valid k
ey. | |
| 135 k := mkKey("aid", "ns", "knd", -1) | |
| 136 buf := &bytes.Buffer{} | |
| 137 WriteDSKey(buf, WithoutContext, k) | |
| 138 | |
| 139 k = mkKey("aid", "ns", "knd", "hat") | |
| 140 buf2 := &bytes.Buffer{} | |
| 141 WriteDSKey(buf2, WithoutContext, k) | |
| 142 | |
| 143 So(bytes.Compare(buf.Bytes(), buf2.Bytes
()), ShouldBeLessThan, 0) | |
| 144 }) | |
| 145 }) | |
| 146 | |
| 147 Convey("err cases", func() { | |
| 148 Convey("nil", func() { | |
| 149 buf := &bytes.Buffer{} | |
| 150 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 151 So(err, ShouldEqual, io.EOF) | |
| 152 }) | |
| 153 Convey("str", func() { | |
| 154 buf := &bytes.Buffer{} | |
| 155 buf.WriteString("sup") | |
| 156 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 157 So(err, ShouldErrLike, "expected actualC
tx") | |
| 158 }) | |
| 159 Convey("truncated 1", func() { | |
| 160 buf := &bytes.Buffer{} | |
| 161 buf.WriteByte(1) // actualCtx == 1 | |
| 162 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 163 So(err, ShouldEqual, io.EOF) | |
| 164 }) | |
| 165 Convey("truncated 2", func() { | |
| 166 buf := &bytes.Buffer{} | |
| 167 buf.WriteByte(1) // actualCtx == 1 | |
| 168 cmpbin.WriteString(buf, "aid") | |
| 169 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 170 So(err, ShouldEqual, io.EOF) | |
| 171 }) | |
| 172 Convey("truncated 3", func() { | |
| 173 buf := &bytes.Buffer{} | |
| 174 buf.WriteByte(1) // actualCtx == 1 | |
| 175 cmpbin.WriteString(buf, "aid") | |
| 176 cmpbin.WriteString(buf, "ns") | |
| 177 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 178 So(err, ShouldEqual, io.EOF) | |
| 179 }) | |
| 180 Convey("huge key", func() { | |
| 181 buf := &bytes.Buffer{} | |
| 182 buf.WriteByte(1) // actualCtx == 1 | |
| 183 cmpbin.WriteString(buf, "aid") | |
| 184 cmpbin.WriteString(buf, "ns") | |
| 185 cmpbin.WriteUint(buf, 1000) | |
| 186 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 187 So(err, ShouldErrLike, "huge key") | |
| 188 }) | |
| 189 Convey("insufficient tokens", func() { | |
| 190 buf := &bytes.Buffer{} | |
| 191 buf.WriteByte(1) // actualCtx == 1 | |
| 192 cmpbin.WriteString(buf, "aid") | |
| 193 cmpbin.WriteString(buf, "ns") | |
| 194 cmpbin.WriteUint(buf, 2) | |
| 195 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 196 So(err, ShouldEqual, io.EOF) | |
| 197 }) | |
| 198 Convey("partial token 1", func() { | |
| 199 buf := &bytes.Buffer{} | |
| 200 buf.WriteByte(1) // actualCtx == 1 | |
| 201 cmpbin.WriteString(buf, "aid") | |
| 202 cmpbin.WriteString(buf, "ns") | |
| 203 cmpbin.WriteUint(buf, 2) | |
| 204 cmpbin.WriteString(buf, "hi") | |
| 205 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 206 So(err, ShouldEqual, io.EOF) | |
| 207 }) | |
| 208 Convey("partial token 2", func() { | |
| 209 buf := &bytes.Buffer{} | |
| 210 buf.WriteByte(1) // actualCtx == 1 | |
| 211 cmpbin.WriteString(buf, "aid") | |
| 212 cmpbin.WriteString(buf, "ns") | |
| 213 cmpbin.WriteUint(buf, 2) | |
| 214 cmpbin.WriteString(buf, "hi") | |
| 215 buf.WriteByte(byte(gae.DSPTString)) | |
| 216 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 217 So(err, ShouldEqual, io.EOF) | |
| 218 }) | |
| 219 Convey("bad token (invalid type)", func() { | |
| 220 buf := &bytes.Buffer{} | |
| 221 buf.WriteByte(1) // actualCtx == 1 | |
| 222 cmpbin.WriteString(buf, "aid") | |
| 223 cmpbin.WriteString(buf, "ns") | |
| 224 cmpbin.WriteUint(buf, 2) | |
| 225 cmpbin.WriteString(buf, "hi") | |
| 226 buf.WriteByte(byte(gae.DSPTBlobKey)) | |
| 227 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 228 So(err, ShouldErrLike, "invalid type DSP
TBlobKey") | |
| 229 }) | |
| 230 Convey("bad token (invalid IntID)", func() { | |
| 231 buf := &bytes.Buffer{} | |
| 232 buf.WriteByte(1) // actualCtx == 1 | |
| 233 cmpbin.WriteString(buf, "aid") | |
| 234 cmpbin.WriteString(buf, "ns") | |
| 235 cmpbin.WriteUint(buf, 2) | |
| 236 cmpbin.WriteString(buf, "hi") | |
| 237 buf.WriteByte(byte(gae.DSPTInt)) | |
| 238 cmpbin.WriteInt(buf, -2) | |
| 239 _, err := ReadDSKey(buf, WithContext, ""
, "") | |
| 240 So(err, ShouldErrLike, "zero/negative") | |
| 241 }) | |
| 242 }) | |
| 243 }) | |
| 244 | |
| 245 Convey("ReadDSGeoPoint", func() { | |
| 246 Convey("trunc 1", func() { | |
| 247 buf := &bytes.Buffer{} | |
| 248 _, err := ReadDSGeoPoint(buf) | |
| 249 So(err, ShouldEqual, io.EOF) | |
| 250 }) | |
| 251 Convey("trunc 2", func() { | |
| 252 buf := &bytes.Buffer{} | |
| 253 cmpbin.WriteFloat64(buf, 100) | |
| 254 _, err := ReadDSGeoPoint(buf) | |
| 255 So(err, ShouldEqual, io.EOF) | |
| 256 }) | |
| 257 Convey("invalid", func() { | |
| 258 buf := &bytes.Buffer{} | |
| 259 cmpbin.WriteFloat64(buf, 100) | |
| 260 cmpbin.WriteFloat64(buf, 1000) | |
| 261 _, err := ReadDSGeoPoint(buf) | |
| 262 So(err, ShouldErrLike, "invalid DSGeoPoint") | |
| 263 }) | |
| 264 }) | |
| 265 | |
| 266 Convey("WriteTime", func() { | |
| 267 Convey("in non-UTC!", func() { | |
| 268 buf := &bytes.Buffer{} | |
| 269 pst, err := time.LoadLocation("America/Los_Angel
es") | |
| 270 So(err, ShouldBeNil) | |
| 271 So(func() { | |
| 272 WriteTime(buf, time.Now().In(pst)) | |
| 273 }, ShouldPanic) | |
| 274 }) | |
| 275 }) | |
| 276 | |
| 277 Convey("ReadTime", func() { | |
| 278 Convey("trunc 1", func() { | |
| 279 buf := &bytes.Buffer{} | |
| 280 _, err := ReadTime(buf) | |
| 281 So(err, ShouldEqual, io.EOF) | |
| 282 }) | |
| 283 }) | |
| 284 | |
| 285 Convey("ReadDSProperty", func() { | |
| 286 Convey("trunc 1", func() { | |
| 287 buf := &bytes.Buffer{} | |
| 288 _, err := ReadDSProperty(buf, WithContext, "", "
") | |
| 289 So(err, ShouldEqual, io.EOF) | |
| 290 }) | |
| 291 Convey("trunc (DSPTBytes)", func() { | |
| 292 buf := &bytes.Buffer{} | |
| 293 buf.WriteByte(byte(gae.DSPTBytes)) | |
| 294 _, err := ReadDSProperty(buf, WithContext, "", "
") | |
| 295 So(err, ShouldEqual, io.EOF) | |
| 296 }) | |
| 297 Convey("trunc (DSPTBlobKey)", func() { | |
| 298 buf := &bytes.Buffer{} | |
| 299 buf.WriteByte(byte(gae.DSPTBlobKey)) | |
| 300 _, err := ReadDSProperty(buf, WithContext, "", "
") | |
| 301 So(err, ShouldEqual, io.EOF) | |
| 302 }) | |
| 303 Convey("invalid type", func() { | |
| 304 buf := &bytes.Buffer{} | |
| 305 buf.WriteByte(byte(gae.DSPTUnknown + 1)) | |
| 306 _, err := ReadDSProperty(buf, WithContext, "", "
") | |
| 307 So(err, ShouldErrLike, "unknown type!") | |
| 308 }) | |
| 309 }) | |
| 310 | |
| 311 Convey("ReadDSPropertyMap", func() { | |
| 312 Convey("trunc 1", func() { | |
| 313 buf := &bytes.Buffer{} | |
| 314 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 315 So(err, ShouldEqual, io.EOF) | |
| 316 }) | |
| 317 Convey("too many rows", func() { | |
| 318 buf := &bytes.Buffer{} | |
| 319 cmpbin.WriteUint(buf, 1000000) | |
| 320 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 321 So(err, ShouldErrLike, "huge number of rows") | |
| 322 }) | |
| 323 Convey("trunc 2", func() { | |
| 324 buf := &bytes.Buffer{} | |
| 325 cmpbin.WriteUint(buf, 10) | |
| 326 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 327 So(err, ShouldEqual, io.EOF) | |
| 328 }) | |
| 329 Convey("trunc 3", func() { | |
| 330 buf := &bytes.Buffer{} | |
| 331 cmpbin.WriteUint(buf, 10) | |
| 332 cmpbin.WriteString(buf, "ohai") | |
| 333 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 334 So(err, ShouldEqual, io.EOF) | |
| 335 }) | |
| 336 Convey("too many values", func() { | |
| 337 buf := &bytes.Buffer{} | |
| 338 cmpbin.WriteUint(buf, 10) | |
| 339 cmpbin.WriteString(buf, "ohai") | |
| 340 cmpbin.WriteUint(buf, 100000) | |
| 341 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 342 So(err, ShouldErrLike, "huge number of propertie
s") | |
| 343 }) | |
| 344 Convey("trunc 4", func() { | |
| 345 buf := &bytes.Buffer{} | |
| 346 cmpbin.WriteUint(buf, 10) | |
| 347 cmpbin.WriteString(buf, "ohai") | |
| 348 cmpbin.WriteUint(buf, 10) | |
| 349 _, err := ReadDSPropertyMap(buf, WithContext, ""
, "") | |
| 350 So(err, ShouldEqual, io.EOF) | |
| 351 }) | |
| 352 }) | |
| 353 }) | |
| 354 } | |
| OLD | NEW |