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  }