github.com/chrislusf/greenpack@v3.7.1-0.20170911073826-ad5bd10b7c47+incompatible/msgp/write_test.go (about) 1 package msgp 2 3 import ( 4 "bytes" 5 "math" 6 "math/rand" 7 "testing" 8 "time" 9 ) 10 11 var ( 12 tint8 int8 = 126 // cannot be most fix* types 13 tint16 int16 = 150 // cannot be int8 14 tint32 int32 = math.MaxInt16 + 100 // cannot be int16 15 tint64 int64 = math.MaxInt32 + 100 // cannot be int32 16 tuint16 uint32 = 300 // cannot be uint8 17 tuint32 uint32 = math.MaxUint16 + 100 // cannot be uint16 18 tuint64 uint64 = math.MaxUint32 + 100 // cannot be uint32 19 ) 20 21 func RandBytes(sz int) []byte { 22 out := make([]byte, sz) 23 for i := range out { 24 out[i] = byte(rand.Int63n(math.MaxInt64) % 256) 25 } 26 return out 27 } 28 29 func TestWriteMapHeader(t *testing.T) { 30 tests := []struct { 31 Sz uint32 32 Outbytes []byte 33 }{ 34 {0, []byte{mfixmap}}, 35 {1, []byte{mfixmap | byte(1)}}, 36 {100, []byte{mmap16, byte(uint16(100) >> 8), byte(uint16(100))}}, 37 {tuint32, 38 []byte{mmap32, 39 byte(tuint32 >> 24), 40 byte(tuint32 >> 16), 41 byte(tuint32 >> 8), 42 byte(tuint32), 43 }, 44 }, 45 } 46 47 var buf bytes.Buffer 48 var err error 49 wr := NewWriter(&buf) 50 for _, test := range tests { 51 buf.Reset() 52 err = wr.WriteMapHeader(test.Sz) 53 if err != nil { 54 t.Error(err) 55 } 56 err = wr.Flush() 57 if err != nil { 58 t.Fatal(err) 59 } 60 if !bytes.Equal(buf.Bytes(), test.Outbytes) { 61 t.Errorf("Expected bytes %x; got %x", test.Outbytes, buf.Bytes()) 62 } 63 } 64 } 65 66 func BenchmarkWriteMapHeader(b *testing.B) { 67 wr := NewWriter(Nowhere) 68 N := b.N / 4 69 b.ReportAllocs() 70 b.ResetTimer() 71 for i := 0; i < N; i++ { 72 wr.WriteMapHeader(0) 73 wr.WriteMapHeader(8) 74 wr.WriteMapHeader(tuint16) 75 wr.WriteMapHeader(tuint32) 76 } 77 } 78 79 func TestWriteArrayHeader(t *testing.T) { 80 tests := []struct { 81 Sz uint32 82 Outbytes []byte 83 }{ 84 {0, []byte{mfixarray}}, 85 {1, []byte{mfixarray | byte(1)}}, 86 {tuint16, []byte{marray16, byte(tuint16 >> 8), byte(tuint16)}}, 87 {tuint32, []byte{marray32, byte(tuint32 >> 24), byte(tuint32 >> 16), byte(tuint32 >> 8), byte(tuint32)}}, 88 } 89 90 var buf bytes.Buffer 91 var err error 92 wr := NewWriter(&buf) 93 for _, test := range tests { 94 buf.Reset() 95 err = wr.WriteArrayHeader(test.Sz) 96 if err != nil { 97 t.Error(err) 98 } 99 err = wr.Flush() 100 if err != nil { 101 t.Fatal(err) 102 } 103 if !bytes.Equal(buf.Bytes(), test.Outbytes) { 104 t.Errorf("Expected bytes %x; got %x", test.Outbytes, buf.Bytes()) 105 } 106 } 107 } 108 109 func TestReadWriteStringHeader(t *testing.T) { 110 sizes := []uint32{0, 5, 8, 19, 150, tuint16, tuint32} 111 var buf bytes.Buffer 112 var err error 113 wr := NewWriter(&buf) 114 for _, sz := range sizes { 115 buf.Reset() 116 err = wr.WriteStringHeader(sz) 117 if err != nil { 118 t.Fatal(err) 119 } 120 err = wr.Flush() 121 if err != nil { 122 t.Fatal(err) 123 } 124 var nsz uint32 125 nsz, err = NewReader(&buf).ReadStringHeader() 126 if err != nil { 127 t.Fatal(err) 128 } 129 if nsz != sz { 130 t.Errorf("put in size %d but got out size %d", sz, nsz) 131 } 132 } 133 } 134 135 func TestReadWriteBytesHeader(t *testing.T) { 136 sizes := []uint32{0, 5, 8, 19, 150, tuint16, tuint32} 137 var buf bytes.Buffer 138 var err error 139 wr := NewWriter(&buf) 140 for _, sz := range sizes { 141 buf.Reset() 142 err = wr.WriteBytesHeader(sz) 143 if err != nil { 144 t.Fatal(err) 145 } 146 err = wr.Flush() 147 if err != nil { 148 t.Fatal(err) 149 } 150 var nsz uint32 151 nsz, err = NewReader(&buf).ReadBytesHeader() 152 if err != nil { 153 t.Fatal(err) 154 } 155 if nsz != sz { 156 t.Errorf("put in size %d but got out size %d", sz, nsz) 157 } 158 } 159 } 160 161 func BenchmarkWriteArrayHeader(b *testing.B) { 162 wr := NewWriter(Nowhere) 163 N := b.N / 4 164 b.ReportAllocs() 165 b.ResetTimer() 166 for i := 0; i < N; i++ { 167 wr.WriteArrayHeader(0) 168 wr.WriteArrayHeader(16) 169 wr.WriteArrayHeader(tuint16) 170 wr.WriteArrayHeader(tuint32) 171 } 172 } 173 174 func TestWriteNil(t *testing.T) { 175 var buf bytes.Buffer 176 wr := NewWriter(&buf) 177 178 err := wr.WriteNil() 179 if err != nil { 180 t.Fatal(err) 181 } 182 err = wr.Flush() 183 if err != nil { 184 t.Fatal(err) 185 } 186 187 bts := buf.Bytes() 188 if bts[0] != mnil { 189 t.Errorf("Expected %x; wrote %x", mnil, bts[0]) 190 } 191 } 192 193 func TestWriteFloat64(t *testing.T) { 194 var buf bytes.Buffer 195 wr := NewWriter(&buf) 196 197 for i := 0; i < 10000; i++ { 198 buf.Reset() 199 flt := (rand.Float64() - 0.5) * math.MaxFloat64 200 err := wr.WriteFloat64(flt) 201 if err != nil { 202 t.Errorf("Error with %f: %s", flt, err) 203 } 204 err = wr.Flush() 205 if err != nil { 206 t.Fatal(err) 207 } 208 209 bts := buf.Bytes() 210 211 if bts[0] != mfloat64 { 212 t.Errorf("Leading byte was %x and not %x", bts[0], mfloat64) 213 } 214 } 215 } 216 217 func BenchmarkWriteFloat64(b *testing.B) { 218 f := rand.Float64() 219 wr := NewWriter(Nowhere) 220 b.SetBytes(9) 221 b.ReportAllocs() 222 b.ResetTimer() 223 for i := 0; i < b.N; i++ { 224 wr.WriteFloat64(f) 225 } 226 } 227 228 func TestWriteFloat32(t *testing.T) { 229 var buf bytes.Buffer 230 wr := NewWriter(&buf) 231 232 for i := 0; i < 10000; i++ { 233 buf.Reset() 234 flt := (rand.Float32() - 0.5) * math.MaxFloat32 235 err := wr.WriteFloat32(flt) 236 if err != nil { 237 t.Errorf("Error with %f: %s", flt, err) 238 } 239 err = wr.Flush() 240 if err != nil { 241 t.Fatal(err) 242 } 243 244 bts := buf.Bytes() 245 246 if bts[0] != mfloat32 { 247 t.Errorf("Leading byte was %x and not %x", bts[0], mfloat64) 248 } 249 } 250 } 251 252 func BenchmarkWriteFloat32(b *testing.B) { 253 f := rand.Float32() 254 wr := NewWriter(Nowhere) 255 b.SetBytes(5) 256 b.ReportAllocs() 257 b.ResetTimer() 258 for i := 0; i < b.N; i++ { 259 wr.WriteFloat32(f) 260 } 261 } 262 263 func TestWriteInt64(t *testing.T) { 264 var buf bytes.Buffer 265 wr := NewWriter(&buf) 266 267 for i := 0; i < 10000; i++ { 268 buf.Reset() 269 270 num := (rand.Int63n(math.MaxInt64)) - (math.MaxInt64 / 2) 271 272 err := wr.WriteInt64(num) 273 if err != nil { 274 t.Fatal(err) 275 } 276 err = wr.Flush() 277 if err != nil { 278 t.Fatal(err) 279 } 280 281 if buf.Len() > 9 { 282 t.Errorf("buffer length should be <= 9; it's %d", buf.Len()) 283 } 284 } 285 } 286 287 func BenchmarkWriteInt64(b *testing.B) { 288 wr := NewWriter(Nowhere) 289 b.SetBytes(9) 290 b.ReportAllocs() 291 b.ResetTimer() 292 for i := 0; i < b.N; i++ { 293 wr.WriteInt64(int64(tint64)) 294 } 295 } 296 297 func TestWriteUint64(t *testing.T) { 298 var buf bytes.Buffer 299 wr := NewWriter(&buf) 300 301 for i := 0; i < 10000; i++ { 302 buf.Reset() 303 304 num := uint64(rand.Int63n(math.MaxInt64)) 305 306 err := wr.WriteUint64(num) 307 if err != nil { 308 t.Fatal(err) 309 } 310 err = wr.Flush() 311 if err != nil { 312 t.Fatal(err) 313 } 314 if buf.Len() > 9 { 315 t.Errorf("buffer length should be <= 9; it's %d", buf.Len()) 316 } 317 } 318 } 319 320 func BenchmarkWriteUint64(b *testing.B) { 321 wr := NewWriter(Nowhere) 322 b.SetBytes(9) 323 b.ReportAllocs() 324 b.ResetTimer() 325 for i := 0; i < b.N; i++ { 326 wr.WriteUint64(uint64(tuint64)) 327 } 328 } 329 330 func TestWriteBytes(t *testing.T) { 331 var buf bytes.Buffer 332 wr := NewWriter(&buf) 333 sizes := []int{0, 1, 225, int(tuint32)} 334 335 for _, size := range sizes { 336 buf.Reset() 337 bts := RandBytes(size) 338 339 err := wr.WriteBytes(bts) 340 if err != nil { 341 t.Fatal(err) 342 } 343 344 err = wr.Flush() 345 if err != nil { 346 t.Fatal(err) 347 } 348 349 if buf.Len() < len(bts) { 350 t.Errorf("somehow, %d bytes were encoded in %d bytes", len(bts), buf.Len()) 351 } 352 } 353 } 354 355 func benchwrBytes(size uint32, b *testing.B) { 356 bts := RandBytes(int(size)) 357 wr := NewWriter(Nowhere) 358 b.ReportAllocs() 359 b.ResetTimer() 360 for i := 0; i < b.N; i++ { 361 wr.WriteBytes(bts) 362 } 363 } 364 365 func BenchmarkWrite16Bytes(b *testing.B) { benchwrBytes(16, b) } 366 367 func BenchmarkWrite256Bytes(b *testing.B) { benchwrBytes(256, b) } 368 369 func BenchmarkWrite2048Bytes(b *testing.B) { benchwrBytes(2048, b) } 370 371 func TestWriteTime(t *testing.T) { 372 var buf bytes.Buffer 373 wr := NewWriter(&buf) 374 tm := time.Now() 375 err := wr.WriteTime(tm) 376 if err != nil { 377 t.Fatal(err) 378 } 379 err = wr.Flush() 380 if err != nil { 381 t.Fatal(err) 382 } 383 if buf.Len() != 15 { 384 t.Errorf("expected time.Time to be %d bytes; got %d", 15, buf.Len()) 385 } 386 387 newt, err := NewReader(&buf).ReadTime() 388 if err != nil { 389 t.Fatal(err) 390 } 391 if !newt.Equal(tm) { 392 t.Errorf("in/out not equal; %s in and %s out", tm, newt) 393 } 394 } 395 396 func BenchmarkWriteTime(b *testing.B) { 397 t := time.Now() 398 wr := NewWriter(Nowhere) 399 b.SetBytes(15) 400 b.ReportAllocs() 401 b.ResetTimer() 402 for i := 0; i < b.N; i++ { 403 wr.WriteTime(t) 404 } 405 }