github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/rlp/encode_test.go (about)

     1  // This file is part of the go-sberex library. The go-sberex library is 
     2  // free software: you can redistribute it and/or modify it under the terms 
     3  // of the GNU Lesser General Public License as published by the Free 
     4  // Software Foundation, either version 3 of the License, or (at your option)
     5  // any later version.
     6  //
     7  // The go-sberex library is distributed in the hope that it will be useful, 
     8  // but WITHOUT ANY WARRANTY; without even the implied warranty of
     9  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
    10  // General Public License <http://www.gnu.org/licenses/> for more details.
    11  
    12  package rlp
    13  
    14  import (
    15  	"bytes"
    16  	"errors"
    17  	"fmt"
    18  	"io"
    19  	"io/ioutil"
    20  	"math/big"
    21  	"sync"
    22  	"testing"
    23  )
    24  
    25  type testEncoder struct {
    26  	err error
    27  }
    28  
    29  func (e *testEncoder) EncodeRLP(w io.Writer) error {
    30  	if e == nil {
    31  		w.Write([]byte{0, 0, 0, 0})
    32  	} else if e.err != nil {
    33  		return e.err
    34  	} else {
    35  		w.Write([]byte{0, 1, 0, 1, 0, 1, 0, 1, 0, 1})
    36  	}
    37  	return nil
    38  }
    39  
    40  type byteEncoder byte
    41  
    42  func (e byteEncoder) EncodeRLP(w io.Writer) error {
    43  	w.Write(EmptyList)
    44  	return nil
    45  }
    46  
    47  type encodableReader struct {
    48  	A, B uint
    49  }
    50  
    51  func (e *encodableReader) Read(b []byte) (int, error) {
    52  	panic("called")
    53  }
    54  
    55  type namedByteType byte
    56  
    57  var (
    58  	_ = Encoder(&testEncoder{})
    59  	_ = Encoder(byteEncoder(0))
    60  
    61  	reader io.Reader = &encodableReader{1, 2}
    62  )
    63  
    64  type encTest struct {
    65  	val           interface{}
    66  	output, error string
    67  }
    68  
    69  var encTests = []encTest{
    70  	// booleans
    71  	{val: true, output: "01"},
    72  	{val: false, output: "80"},
    73  
    74  	// integers
    75  	{val: uint32(0), output: "80"},
    76  	{val: uint32(127), output: "7F"},
    77  	{val: uint32(128), output: "8180"},
    78  	{val: uint32(256), output: "820100"},
    79  	{val: uint32(1024), output: "820400"},
    80  	{val: uint32(0xFFFFFF), output: "83FFFFFF"},
    81  	{val: uint32(0xFFFFFFFF), output: "84FFFFFFFF"},
    82  	{val: uint64(0xFFFFFFFF), output: "84FFFFFFFF"},
    83  	{val: uint64(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
    84  	{val: uint64(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
    85  	{val: uint64(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
    86  	{val: uint64(0xFFFFFFFFFFFFFFFF), output: "88FFFFFFFFFFFFFFFF"},
    87  
    88  	// big integers (should match uint for small values)
    89  	{val: big.NewInt(0), output: "80"},
    90  	{val: big.NewInt(1), output: "01"},
    91  	{val: big.NewInt(127), output: "7F"},
    92  	{val: big.NewInt(128), output: "8180"},
    93  	{val: big.NewInt(256), output: "820100"},
    94  	{val: big.NewInt(1024), output: "820400"},
    95  	{val: big.NewInt(0xFFFFFF), output: "83FFFFFF"},
    96  	{val: big.NewInt(0xFFFFFFFF), output: "84FFFFFFFF"},
    97  	{val: big.NewInt(0xFFFFFFFFFF), output: "85FFFFFFFFFF"},
    98  	{val: big.NewInt(0xFFFFFFFFFFFF), output: "86FFFFFFFFFFFF"},
    99  	{val: big.NewInt(0xFFFFFFFFFFFFFF), output: "87FFFFFFFFFFFFFF"},
   100  	{
   101  		val:    big.NewInt(0).SetBytes(unhex("102030405060708090A0B0C0D0E0F2")),
   102  		output: "8F102030405060708090A0B0C0D0E0F2",
   103  	},
   104  	{
   105  		val:    big.NewInt(0).SetBytes(unhex("0100020003000400050006000700080009000A000B000C000D000E01")),
   106  		output: "9C0100020003000400050006000700080009000A000B000C000D000E01",
   107  	},
   108  	{
   109  		val:    big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")),
   110  		output: "A1010000000000000000000000000000000000000000000000000000000000000000",
   111  	},
   112  
   113  	// non-pointer big.Int
   114  	{val: *big.NewInt(0), output: "80"},
   115  	{val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"},
   116  
   117  	// negative ints are not supported
   118  	{val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"},
   119  
   120  	// byte slices, strings
   121  	{val: []byte{}, output: "80"},
   122  	{val: []byte{0x7E}, output: "7E"},
   123  	{val: []byte{0x7F}, output: "7F"},
   124  	{val: []byte{0x80}, output: "8180"},
   125  	{val: []byte{1, 2, 3}, output: "83010203"},
   126  
   127  	{val: []namedByteType{1, 2, 3}, output: "83010203"},
   128  	{val: [...]namedByteType{1, 2, 3}, output: "83010203"},
   129  
   130  	{val: "", output: "80"},
   131  	{val: "\x7E", output: "7E"},
   132  	{val: "\x7F", output: "7F"},
   133  	{val: "\x80", output: "8180"},
   134  	{val: "dog", output: "83646F67"},
   135  	{
   136  		val:    "Lorem ipsum dolor sit amet, consectetur adipisicing eli",
   137  		output: "B74C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C69",
   138  	},
   139  	{
   140  		val:    "Lorem ipsum dolor sit amet, consectetur adipisicing elit",
   141  		output: "B8384C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E7365637465747572206164697069736963696E6720656C6974",
   142  	},
   143  	{
   144  		val:    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat",
   145  		output: "B904004C6F72656D20697073756D20646F6C6F722073697420616D65742C20636F6E73656374657475722061646970697363696E6720656C69742E20437572616269747572206D6175726973206D61676E612C20737573636970697420736564207665686963756C61206E6F6E2C20696163756C697320666175636962757320746F72746F722E2050726F696E20737573636970697420756C74726963696573206D616C6573756164612E204475697320746F72746F7220656C69742C2064696374756D2071756973207472697374697175652065752C20756C7472696365732061742072697375732E204D6F72626920612065737420696D70657264696574206D6920756C6C616D636F7270657220616C6971756574207375736369706974206E6563206C6F72656D2E2041656E65616E2071756973206C656F206D6F6C6C69732C2076756C70757461746520656C6974207661726975732C20636F6E73657175617420656E696D2E204E756C6C6120756C74726963657320747572706973206A7573746F2C20657420706F73756572652075726E6120636F6E7365637465747572206E65632E2050726F696E206E6F6E20636F6E76616C6C6973206D657475732E20446F6E65632074656D706F7220697073756D20696E206D617572697320636F6E67756520736F6C6C696369747564696E2E20566573746962756C756D20616E746520697073756D207072696D697320696E206661756369627573206F726369206C756374757320657420756C74726963657320706F737565726520637562696C69612043757261653B2053757370656E646973736520636F6E76616C6C69732073656D2076656C206D617373612066617563696275732C2065676574206C6163696E6961206C616375732074656D706F722E204E756C6C61207175697320756C747269636965732070757275732E2050726F696E20617563746F722072686F6E637573206E69626820636F6E64696D656E74756D206D6F6C6C69732E20416C697175616D20636F6E73657175617420656E696D206174206D65747573206C75637475732C206120656C656966656E6420707572757320656765737461732E20437572616269747572206174206E696268206D657475732E204E616D20626962656E64756D2C206E6571756520617420617563746F72207472697374697175652C206C6F72656D206C696265726F20616C697175657420617263752C206E6F6E20696E74657264756D2074656C6C7573206C65637475732073697420616D65742065726F732E20437261732072686F6E6375732C206D65747573206163206F726E617265206375727375732C20646F6C6F72206A7573746F20756C747269636573206D657475732C20617420756C6C616D636F7270657220766F6C7574706174",
   146  	},
   147  
   148  	// slices
   149  	{val: []uint{}, output: "C0"},
   150  	{val: []uint{1, 2, 3}, output: "C3010203"},
   151  	{
   152  		// [ [], [[]], [ [], [[]] ] ]
   153  		val:    []interface{}{[]interface{}{}, [][]interface{}{{}}, []interface{}{[]interface{}{}, [][]interface{}{{}}}},
   154  		output: "C7C0C1C0C3C0C1C0",
   155  	},
   156  	{
   157  		val:    []string{"aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk", "lll", "mmm", "nnn", "ooo"},
   158  		output: "F83C836161618362626283636363836464648365656583666666836767678368686883696969836A6A6A836B6B6B836C6C6C836D6D6D836E6E6E836F6F6F",
   159  	},
   160  	{
   161  		val:    []interface{}{uint(1), uint(0xFFFFFF), []interface{}{[]uint{4, 5, 5}}, "abc"},
   162  		output: "CE0183FFFFFFC4C304050583616263",
   163  	},
   164  	{
   165  		val: [][]string{
   166  			{"asdf", "qwer", "zxcv"},
   167  			{"asdf", "qwer", "zxcv"},
   168  			{"asdf", "qwer", "zxcv"},
   169  			{"asdf", "qwer", "zxcv"},
   170  			{"asdf", "qwer", "zxcv"},
   171  			{"asdf", "qwer", "zxcv"},
   172  			{"asdf", "qwer", "zxcv"},
   173  			{"asdf", "qwer", "zxcv"},
   174  			{"asdf", "qwer", "zxcv"},
   175  			{"asdf", "qwer", "zxcv"},
   176  			{"asdf", "qwer", "zxcv"},
   177  			{"asdf", "qwer", "zxcv"},
   178  			{"asdf", "qwer", "zxcv"},
   179  			{"asdf", "qwer", "zxcv"},
   180  			{"asdf", "qwer", "zxcv"},
   181  			{"asdf", "qwer", "zxcv"},
   182  			{"asdf", "qwer", "zxcv"},
   183  			{"asdf", "qwer", "zxcv"},
   184  			{"asdf", "qwer", "zxcv"},
   185  			{"asdf", "qwer", "zxcv"},
   186  			{"asdf", "qwer", "zxcv"},
   187  			{"asdf", "qwer", "zxcv"},
   188  			{"asdf", "qwer", "zxcv"},
   189  			{"asdf", "qwer", "zxcv"},
   190  			{"asdf", "qwer", "zxcv"},
   191  			{"asdf", "qwer", "zxcv"},
   192  			{"asdf", "qwer", "zxcv"},
   193  			{"asdf", "qwer", "zxcv"},
   194  			{"asdf", "qwer", "zxcv"},
   195  			{"asdf", "qwer", "zxcv"},
   196  			{"asdf", "qwer", "zxcv"},
   197  			{"asdf", "qwer", "zxcv"},
   198  		},
   199  		output: "F90200CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376CF84617364668471776572847A786376",
   200  	},
   201  
   202  	// RawValue
   203  	{val: RawValue(unhex("01")), output: "01"},
   204  	{val: RawValue(unhex("82FFFF")), output: "82FFFF"},
   205  	{val: []RawValue{unhex("01"), unhex("02")}, output: "C20102"},
   206  
   207  	// structs
   208  	{val: simplestruct{}, output: "C28080"},
   209  	{val: simplestruct{A: 3, B: "foo"}, output: "C50383666F6F"},
   210  	{val: &recstruct{5, nil}, output: "C205C0"},
   211  	{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
   212  	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02"), unhex("03")}}, output: "C3010203"},
   213  	{val: &tailRaw{A: 1, Tail: []RawValue{unhex("02")}}, output: "C20102"},
   214  	{val: &tailRaw{A: 1, Tail: []RawValue{}}, output: "C101"},
   215  	{val: &tailRaw{A: 1, Tail: nil}, output: "C101"},
   216  	{val: &hasIgnoredField{A: 1, B: 2, C: 3}, output: "C20103"},
   217  
   218  	// nil
   219  	{val: (*uint)(nil), output: "80"},
   220  	{val: (*string)(nil), output: "80"},
   221  	{val: (*[]byte)(nil), output: "80"},
   222  	{val: (*[10]byte)(nil), output: "80"},
   223  	{val: (*big.Int)(nil), output: "80"},
   224  	{val: (*[]string)(nil), output: "C0"},
   225  	{val: (*[10]string)(nil), output: "C0"},
   226  	{val: (*[]interface{})(nil), output: "C0"},
   227  	{val: (*[]struct{ uint })(nil), output: "C0"},
   228  	{val: (*interface{})(nil), output: "C0"},
   229  
   230  	// interfaces
   231  	{val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct
   232  
   233  	// Encoder
   234  	{val: (*testEncoder)(nil), output: "00000000"},
   235  	{val: &testEncoder{}, output: "00010001000100010001"},
   236  	{val: &testEncoder{errors.New("test error")}, error: "test error"},
   237  	// verify that pointer method testEncoder.EncodeRLP is called for
   238  	// addressable non-pointer values.
   239  	{val: &struct{ TE testEncoder }{testEncoder{}}, output: "CA00010001000100010001"},
   240  	{val: &struct{ TE testEncoder }{testEncoder{errors.New("test error")}}, error: "test error"},
   241  	// verify the error for non-addressable non-pointer Encoder
   242  	{val: testEncoder{}, error: "rlp: game over: unadressable value of type rlp.testEncoder, EncodeRLP is pointer method"},
   243  	// verify the special case for []byte
   244  	{val: []byteEncoder{0, 1, 2, 3, 4}, output: "C5C0C0C0C0C0"},
   245  }
   246  
   247  func runEncTests(t *testing.T, f func(val interface{}) ([]byte, error)) {
   248  	for i, test := range encTests {
   249  		output, err := f(test.val)
   250  		if err != nil && test.error == "" {
   251  			t.Errorf("test %d: unexpected error: %v\nvalue %#v\ntype %T",
   252  				i, err, test.val, test.val)
   253  			continue
   254  		}
   255  		if test.error != "" && fmt.Sprint(err) != test.error {
   256  			t.Errorf("test %d: error mismatch\ngot   %v\nwant  %v\nvalue %#v\ntype  %T",
   257  				i, err, test.error, test.val, test.val)
   258  			continue
   259  		}
   260  		if err == nil && !bytes.Equal(output, unhex(test.output)) {
   261  			t.Errorf("test %d: output mismatch:\ngot   %X\nwant  %s\nvalue %#v\ntype  %T",
   262  				i, output, test.output, test.val, test.val)
   263  		}
   264  	}
   265  }
   266  
   267  func TestEncode(t *testing.T) {
   268  	runEncTests(t, func(val interface{}) ([]byte, error) {
   269  		b := new(bytes.Buffer)
   270  		err := Encode(b, val)
   271  		return b.Bytes(), err
   272  	})
   273  }
   274  
   275  func TestEncodeToBytes(t *testing.T) {
   276  	runEncTests(t, EncodeToBytes)
   277  }
   278  
   279  func TestEncodeToReader(t *testing.T) {
   280  	runEncTests(t, func(val interface{}) ([]byte, error) {
   281  		_, r, err := EncodeToReader(val)
   282  		if err != nil {
   283  			return nil, err
   284  		}
   285  		return ioutil.ReadAll(r)
   286  	})
   287  }
   288  
   289  func TestEncodeToReaderPiecewise(t *testing.T) {
   290  	runEncTests(t, func(val interface{}) ([]byte, error) {
   291  		size, r, err := EncodeToReader(val)
   292  		if err != nil {
   293  			return nil, err
   294  		}
   295  
   296  		// read output piecewise
   297  		output := make([]byte, size)
   298  		for start, end := 0, 0; start < size; start = end {
   299  			if remaining := size - start; remaining < 3 {
   300  				end += remaining
   301  			} else {
   302  				end = start + 3
   303  			}
   304  			n, err := r.Read(output[start:end])
   305  			end = start + n
   306  			if err == io.EOF {
   307  				break
   308  			} else if err != nil {
   309  				return nil, err
   310  			}
   311  		}
   312  		return output, nil
   313  	})
   314  }
   315  
   316  // This is a regression test verifying that encReader
   317  // returns its encbuf to the pool only once.
   318  func TestEncodeToReaderReturnToPool(t *testing.T) {
   319  	buf := make([]byte, 50)
   320  	wg := new(sync.WaitGroup)
   321  	for i := 0; i < 5; i++ {
   322  		wg.Add(1)
   323  		go func() {
   324  			for i := 0; i < 1000; i++ {
   325  				_, r, _ := EncodeToReader("foo")
   326  				ioutil.ReadAll(r)
   327  				r.Read(buf)
   328  				r.Read(buf)
   329  				r.Read(buf)
   330  				r.Read(buf)
   331  			}
   332  			wg.Done()
   333  		}()
   334  	}
   335  	wg.Wait()
   336  }