github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/encoding/gob/gobencdec_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file contains tests of the GobEncoder/GobDecoder support.
     6  
     7  package gob
     8  
     9  import (
    10  	"bytes"
    11  	"errors"
    12  	"fmt"
    13  	"io"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  )
    18  
    19  // Types that implement the GobEncoder/Decoder interfaces.
    20  
    21  type ByteStruct struct {
    22  	a byte // not an exported field
    23  }
    24  
    25  type StringStruct struct {
    26  	s string // not an exported field
    27  }
    28  
    29  type ArrayStruct struct {
    30  	a [8192]byte // not an exported field
    31  }
    32  
    33  type Gobber int
    34  
    35  type ValueGobber string // encodes with a value, decodes with a pointer.
    36  
    37  // The relevant methods
    38  
    39  func (g *ByteStruct) GobEncode() ([]byte, error) {
    40  	b := make([]byte, 3)
    41  	b[0] = g.a
    42  	b[1] = g.a + 1
    43  	b[2] = g.a + 2
    44  	return b, nil
    45  }
    46  
    47  func (g *ByteStruct) GobDecode(data []byte) error {
    48  	if g == nil {
    49  		return errors.New("NIL RECEIVER")
    50  	}
    51  	// Expect N sequential-valued bytes.
    52  	if len(data) == 0 {
    53  		return io.EOF
    54  	}
    55  	g.a = data[0]
    56  	for i, c := range data {
    57  		if c != g.a+byte(i) {
    58  			return errors.New("invalid data sequence")
    59  		}
    60  	}
    61  	return nil
    62  }
    63  
    64  func (g *StringStruct) GobEncode() ([]byte, error) {
    65  	return []byte(g.s), nil
    66  }
    67  
    68  func (g *StringStruct) GobDecode(data []byte) error {
    69  	// Expect N sequential-valued bytes.
    70  	if len(data) == 0 {
    71  		return io.EOF
    72  	}
    73  	a := data[0]
    74  	for i, c := range data {
    75  		if c != a+byte(i) {
    76  			return errors.New("invalid data sequence")
    77  		}
    78  	}
    79  	g.s = string(data)
    80  	return nil
    81  }
    82  
    83  func (a *ArrayStruct) GobEncode() ([]byte, error) {
    84  	return a.a[:], nil
    85  }
    86  
    87  func (a *ArrayStruct) GobDecode(data []byte) error {
    88  	if len(data) != len(a.a) {
    89  		return errors.New("wrong length in array decode")
    90  	}
    91  	copy(a.a[:], data)
    92  	return nil
    93  }
    94  
    95  func (g *Gobber) GobEncode() ([]byte, error) {
    96  	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
    97  }
    98  
    99  func (g *Gobber) GobDecode(data []byte) error {
   100  	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
   101  	return err
   102  }
   103  
   104  func (v ValueGobber) GobEncode() ([]byte, error) {
   105  	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
   106  }
   107  
   108  func (v *ValueGobber) GobDecode(data []byte) error {
   109  	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
   110  	return err
   111  }
   112  
   113  // Structs that include GobEncodable fields.
   114  
   115  type GobTest0 struct {
   116  	X int // guarantee we have  something in common with GobTest*
   117  	G *ByteStruct
   118  }
   119  
   120  type GobTest1 struct {
   121  	X int // guarantee we have  something in common with GobTest*
   122  	G *StringStruct
   123  }
   124  
   125  type GobTest2 struct {
   126  	X int    // guarantee we have  something in common with GobTest*
   127  	G string // not a GobEncoder - should give us errors
   128  }
   129  
   130  type GobTest3 struct {
   131  	X int // guarantee we have  something in common with GobTest*
   132  	G *Gobber
   133  }
   134  
   135  type GobTest4 struct {
   136  	X int // guarantee we have  something in common with GobTest*
   137  	V ValueGobber
   138  }
   139  
   140  type GobTest5 struct {
   141  	X int // guarantee we have  something in common with GobTest*
   142  	V *ValueGobber
   143  }
   144  
   145  type GobTest6 struct {
   146  	X int // guarantee we have  something in common with GobTest*
   147  	V ValueGobber
   148  	W *ValueGobber
   149  }
   150  
   151  type GobTest7 struct {
   152  	X int // guarantee we have  something in common with GobTest*
   153  	V *ValueGobber
   154  	W ValueGobber
   155  }
   156  
   157  type GobTestIgnoreEncoder struct {
   158  	X int // guarantee we have  something in common with GobTest*
   159  }
   160  
   161  type GobTestValueEncDec struct {
   162  	X int          // guarantee we have  something in common with GobTest*
   163  	G StringStruct // not a pointer.
   164  }
   165  
   166  type GobTestIndirectEncDec struct {
   167  	X int             // guarantee we have  something in common with GobTest*
   168  	G ***StringStruct // indirections to the receiver.
   169  }
   170  
   171  type GobTestArrayEncDec struct {
   172  	X int         // guarantee we have  something in common with GobTest*
   173  	A ArrayStruct // not a pointer.
   174  }
   175  
   176  type GobTestIndirectArrayEncDec struct {
   177  	X int            // guarantee we have  something in common with GobTest*
   178  	A ***ArrayStruct // indirections to a large receiver.
   179  }
   180  
   181  func TestGobEncoderField(t *testing.T) {
   182  	b := new(bytes.Buffer)
   183  	// First a field that's a structure.
   184  	enc := NewEncoder(b)
   185  	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
   186  	if err != nil {
   187  		t.Fatal("encode error:", err)
   188  	}
   189  	dec := NewDecoder(b)
   190  	x := new(GobTest0)
   191  	err = dec.Decode(x)
   192  	if err != nil {
   193  		t.Fatal("decode error:", err)
   194  	}
   195  	if x.G.a != 'A' {
   196  		t.Errorf("expected 'A' got %c", x.G.a)
   197  	}
   198  	// Now a field that's not a structure.
   199  	b.Reset()
   200  	gobber := Gobber(23)
   201  	err = enc.Encode(GobTest3{17, &gobber})
   202  	if err != nil {
   203  		t.Fatal("encode error:", err)
   204  	}
   205  	y := new(GobTest3)
   206  	err = dec.Decode(y)
   207  	if err != nil {
   208  		t.Fatal("decode error:", err)
   209  	}
   210  	if *y.G != 23 {
   211  		t.Errorf("expected '23 got %d", *y.G)
   212  	}
   213  }
   214  
   215  // Even though the field is a value, we can still take its address
   216  // and should be able to call the methods.
   217  func TestGobEncoderValueField(t *testing.T) {
   218  	b := new(bytes.Buffer)
   219  	// First a field that's a structure.
   220  	enc := NewEncoder(b)
   221  	err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
   222  	if err != nil {
   223  		t.Fatal("encode error:", err)
   224  	}
   225  	dec := NewDecoder(b)
   226  	x := new(GobTestValueEncDec)
   227  	err = dec.Decode(x)
   228  	if err != nil {
   229  		t.Fatal("decode error:", err)
   230  	}
   231  	if x.G.s != "HIJKL" {
   232  		t.Errorf("expected `HIJKL` got %s", x.G.s)
   233  	}
   234  }
   235  
   236  // GobEncode/Decode should work even if the value is
   237  // more indirect than the receiver.
   238  func TestGobEncoderIndirectField(t *testing.T) {
   239  	b := new(bytes.Buffer)
   240  	// First a field that's a structure.
   241  	enc := NewEncoder(b)
   242  	s := &StringStruct{"HIJKL"}
   243  	sp := &s
   244  	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
   245  	if err != nil {
   246  		t.Fatal("encode error:", err)
   247  	}
   248  	dec := NewDecoder(b)
   249  	x := new(GobTestIndirectEncDec)
   250  	err = dec.Decode(x)
   251  	if err != nil {
   252  		t.Fatal("decode error:", err)
   253  	}
   254  	if (***x.G).s != "HIJKL" {
   255  		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
   256  	}
   257  }
   258  
   259  // Test with a large field with methods.
   260  func TestGobEncoderArrayField(t *testing.T) {
   261  	b := new(bytes.Buffer)
   262  	enc := NewEncoder(b)
   263  	var a GobTestArrayEncDec
   264  	a.X = 17
   265  	for i := range a.A.a {
   266  		a.A.a[i] = byte(i)
   267  	}
   268  	err := enc.Encode(a)
   269  	if err != nil {
   270  		t.Fatal("encode error:", err)
   271  	}
   272  	dec := NewDecoder(b)
   273  	x := new(GobTestArrayEncDec)
   274  	err = dec.Decode(x)
   275  	if err != nil {
   276  		t.Fatal("decode error:", err)
   277  	}
   278  	for i, v := range x.A.a {
   279  		if v != byte(i) {
   280  			t.Errorf("expected %x got %x", byte(i), v)
   281  			break
   282  		}
   283  	}
   284  }
   285  
   286  // Test an indirection to a large field with methods.
   287  func TestGobEncoderIndirectArrayField(t *testing.T) {
   288  	b := new(bytes.Buffer)
   289  	enc := NewEncoder(b)
   290  	var a GobTestIndirectArrayEncDec
   291  	a.X = 17
   292  	var array ArrayStruct
   293  	ap := &array
   294  	app := &ap
   295  	a.A = &app
   296  	for i := range array.a {
   297  		array.a[i] = byte(i)
   298  	}
   299  	err := enc.Encode(a)
   300  	if err != nil {
   301  		t.Fatal("encode error:", err)
   302  	}
   303  	dec := NewDecoder(b)
   304  	x := new(GobTestIndirectArrayEncDec)
   305  	err = dec.Decode(x)
   306  	if err != nil {
   307  		t.Fatal("decode error:", err)
   308  	}
   309  	for i, v := range (***x.A).a {
   310  		if v != byte(i) {
   311  			t.Errorf("expected %x got %x", byte(i), v)
   312  			break
   313  		}
   314  	}
   315  }
   316  
   317  // As long as the fields have the same name and implement the
   318  // interface, we can cross-connect them.  Not sure it's useful
   319  // and may even be bad but it works and it's hard to prevent
   320  // without exposing the contents of the object, which would
   321  // defeat the purpose.
   322  func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
   323  	// first, string in field to byte in field
   324  	b := new(bytes.Buffer)
   325  	enc := NewEncoder(b)
   326  	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
   327  	if err != nil {
   328  		t.Fatal("encode error:", err)
   329  	}
   330  	dec := NewDecoder(b)
   331  	x := new(GobTest0)
   332  	err = dec.Decode(x)
   333  	if err != nil {
   334  		t.Fatal("decode error:", err)
   335  	}
   336  	if x.G.a != 'A' {
   337  		t.Errorf("expected 'A' got %c", x.G.a)
   338  	}
   339  	// now the other direction, byte in field to string in field
   340  	b.Reset()
   341  	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
   342  	if err != nil {
   343  		t.Fatal("encode error:", err)
   344  	}
   345  	y := new(GobTest1)
   346  	err = dec.Decode(y)
   347  	if err != nil {
   348  		t.Fatal("decode error:", err)
   349  	}
   350  	if y.G.s != "XYZ" {
   351  		t.Fatalf("expected `XYZ` got %q", y.G.s)
   352  	}
   353  }
   354  
   355  // Test that we can encode a value and decode into a pointer.
   356  func TestGobEncoderValueEncoder(t *testing.T) {
   357  	// first, string in field to byte in field
   358  	b := new(bytes.Buffer)
   359  	enc := NewEncoder(b)
   360  	err := enc.Encode(GobTest4{17, ValueGobber("hello")})
   361  	if err != nil {
   362  		t.Fatal("encode error:", err)
   363  	}
   364  	dec := NewDecoder(b)
   365  	x := new(GobTest5)
   366  	err = dec.Decode(x)
   367  	if err != nil {
   368  		t.Fatal("decode error:", err)
   369  	}
   370  	if *x.V != "hello" {
   371  		t.Errorf("expected `hello` got %s", x.V)
   372  	}
   373  }
   374  
   375  // Test that we can use a value then a pointer type of a GobEncoder
   376  // in the same encoded value.  Bug 4647.
   377  func TestGobEncoderValueThenPointer(t *testing.T) {
   378  	v := ValueGobber("forty-two")
   379  	w := ValueGobber("six-by-nine")
   380  
   381  	// this was a bug: encoding a GobEncoder by value before a GobEncoder
   382  	// pointer would cause duplicate type definitions to be sent.
   383  
   384  	b := new(bytes.Buffer)
   385  	enc := NewEncoder(b)
   386  	if err := enc.Encode(GobTest6{42, v, &w}); err != nil {
   387  		t.Fatal("encode error:", err)
   388  	}
   389  	dec := NewDecoder(b)
   390  	x := new(GobTest6)
   391  	if err := dec.Decode(x); err != nil {
   392  		t.Fatal("decode error:", err)
   393  	}
   394  	if got, want := x.V, v; got != want {
   395  		t.Errorf("v = %q, want %q", got, want)
   396  	}
   397  	if got, want := x.W, w; got == nil {
   398  		t.Errorf("w = nil, want %q", want)
   399  	} else if *got != want {
   400  		t.Errorf("w = %q, want %q", *got, want)
   401  	}
   402  }
   403  
   404  // Test that we can use a pointer then a value type of a GobEncoder
   405  // in the same encoded value.
   406  func TestGobEncoderPointerThenValue(t *testing.T) {
   407  	v := ValueGobber("forty-two")
   408  	w := ValueGobber("six-by-nine")
   409  
   410  	b := new(bytes.Buffer)
   411  	enc := NewEncoder(b)
   412  	if err := enc.Encode(GobTest7{42, &v, w}); err != nil {
   413  		t.Fatal("encode error:", err)
   414  	}
   415  	dec := NewDecoder(b)
   416  	x := new(GobTest7)
   417  	if err := dec.Decode(x); err != nil {
   418  		t.Fatal("decode error:", err)
   419  	}
   420  	if got, want := x.V, v; got == nil {
   421  		t.Errorf("v = nil, want %q", want)
   422  	} else if *got != want {
   423  		t.Errorf("v = %q, want %q", got, want)
   424  	}
   425  	if got, want := x.W, w; got != want {
   426  		t.Errorf("w = %q, want %q", got, want)
   427  	}
   428  }
   429  
   430  func TestGobEncoderFieldTypeError(t *testing.T) {
   431  	// GobEncoder to non-decoder: error
   432  	b := new(bytes.Buffer)
   433  	enc := NewEncoder(b)
   434  	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
   435  	if err != nil {
   436  		t.Fatal("encode error:", err)
   437  	}
   438  	dec := NewDecoder(b)
   439  	x := &GobTest2{}
   440  	err = dec.Decode(x)
   441  	if err == nil {
   442  		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
   443  	}
   444  	if strings.Index(err.Error(), "type") < 0 {
   445  		t.Fatal("expected type error; got", err)
   446  	}
   447  	// Non-encoder to GobDecoder: error
   448  	b.Reset()
   449  	err = enc.Encode(GobTest2{17, "ABC"})
   450  	if err != nil {
   451  		t.Fatal("encode error:", err)
   452  	}
   453  	y := &GobTest1{}
   454  	err = dec.Decode(y)
   455  	if err == nil {
   456  		t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
   457  	}
   458  	if strings.Index(err.Error(), "type") < 0 {
   459  		t.Fatal("expected type error; got", err)
   460  	}
   461  }
   462  
   463  // Even though ByteStruct is a struct, it's treated as a singleton at the top level.
   464  func TestGobEncoderStructSingleton(t *testing.T) {
   465  	b := new(bytes.Buffer)
   466  	enc := NewEncoder(b)
   467  	err := enc.Encode(&ByteStruct{'A'})
   468  	if err != nil {
   469  		t.Fatal("encode error:", err)
   470  	}
   471  	dec := NewDecoder(b)
   472  	x := new(ByteStruct)
   473  	err = dec.Decode(x)
   474  	if err != nil {
   475  		t.Fatal("decode error:", err)
   476  	}
   477  	if x.a != 'A' {
   478  		t.Errorf("expected 'A' got %c", x.a)
   479  	}
   480  }
   481  
   482  func TestGobEncoderNonStructSingleton(t *testing.T) {
   483  	b := new(bytes.Buffer)
   484  	enc := NewEncoder(b)
   485  	err := enc.Encode(Gobber(1234))
   486  	if err != nil {
   487  		t.Fatal("encode error:", err)
   488  	}
   489  	dec := NewDecoder(b)
   490  	var x Gobber
   491  	err = dec.Decode(&x)
   492  	if err != nil {
   493  		t.Fatal("decode error:", err)
   494  	}
   495  	if x != 1234 {
   496  		t.Errorf("expected 1234 got %d", x)
   497  	}
   498  }
   499  
   500  func TestGobEncoderIgnoreStructField(t *testing.T) {
   501  	b := new(bytes.Buffer)
   502  	// First a field that's a structure.
   503  	enc := NewEncoder(b)
   504  	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
   505  	if err != nil {
   506  		t.Fatal("encode error:", err)
   507  	}
   508  	dec := NewDecoder(b)
   509  	x := new(GobTestIgnoreEncoder)
   510  	err = dec.Decode(x)
   511  	if err != nil {
   512  		t.Fatal("decode error:", err)
   513  	}
   514  	if x.X != 17 {
   515  		t.Errorf("expected 17 got %c", x.X)
   516  	}
   517  }
   518  
   519  func TestGobEncoderIgnoreNonStructField(t *testing.T) {
   520  	b := new(bytes.Buffer)
   521  	// First a field that's a structure.
   522  	enc := NewEncoder(b)
   523  	gobber := Gobber(23)
   524  	err := enc.Encode(GobTest3{17, &gobber})
   525  	if err != nil {
   526  		t.Fatal("encode error:", err)
   527  	}
   528  	dec := NewDecoder(b)
   529  	x := new(GobTestIgnoreEncoder)
   530  	err = dec.Decode(x)
   531  	if err != nil {
   532  		t.Fatal("decode error:", err)
   533  	}
   534  	if x.X != 17 {
   535  		t.Errorf("expected 17 got %c", x.X)
   536  	}
   537  }
   538  
   539  func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
   540  	b := new(bytes.Buffer)
   541  	// First a field that's a structure.
   542  	enc := NewEncoder(b)
   543  	err := enc.Encode(GobTest0{X: 18}) // G is nil
   544  	if err != nil {
   545  		t.Fatal("encode error:", err)
   546  	}
   547  	dec := NewDecoder(b)
   548  	x := new(GobTest0)
   549  	err = dec.Decode(x)
   550  	if err != nil {
   551  		t.Fatal("decode error:", err)
   552  	}
   553  	if x.X != 18 {
   554  		t.Errorf("expected x.X = 18, got %v", x.X)
   555  	}
   556  	if x.G != nil {
   557  		t.Errorf("expected x.G = nil, got %v", x.G)
   558  	}
   559  }
   560  
   561  type gobDecoderBug0 struct {
   562  	foo, bar string
   563  }
   564  
   565  func (br *gobDecoderBug0) String() string {
   566  	return br.foo + "-" + br.bar
   567  }
   568  
   569  func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
   570  	return []byte(br.String()), nil
   571  }
   572  
   573  func (br *gobDecoderBug0) GobDecode(b []byte) error {
   574  	br.foo = "foo"
   575  	br.bar = "bar"
   576  	return nil
   577  }
   578  
   579  // This was a bug: the receiver has a different indirection level
   580  // than the variable.
   581  func TestGobEncoderExtraIndirect(t *testing.T) {
   582  	gdb := &gobDecoderBug0{"foo", "bar"}
   583  	buf := new(bytes.Buffer)
   584  	e := NewEncoder(buf)
   585  	if err := e.Encode(gdb); err != nil {
   586  		t.Fatalf("encode: %v", err)
   587  	}
   588  	d := NewDecoder(buf)
   589  	var got *gobDecoderBug0
   590  	if err := d.Decode(&got); err != nil {
   591  		t.Fatalf("decode: %v", err)
   592  	}
   593  	if got.foo != gdb.foo || got.bar != gdb.bar {
   594  		t.Errorf("got = %q, want %q", got, gdb)
   595  	}
   596  }
   597  
   598  // Another bug: this caused a crash with the new Go1 Time type.
   599  // We throw in a gob-encoding array, to test another case of isZero
   600  
   601  type isZeroBug struct {
   602  	T time.Time
   603  	S string
   604  	I int
   605  	A isZeroBugArray
   606  }
   607  
   608  type isZeroBugArray [2]uint8
   609  
   610  // Receiver is value, not pointer, to test isZero of array.
   611  func (a isZeroBugArray) GobEncode() (b []byte, e error) {
   612  	b = append(b, a[:]...)
   613  	return b, nil
   614  }
   615  
   616  func (a *isZeroBugArray) GobDecode(data []byte) error {
   617  	if len(data) != len(a) {
   618  		return io.EOF
   619  	}
   620  	a[0] = data[0]
   621  	a[1] = data[1]
   622  	return nil
   623  }
   624  
   625  func TestGobEncodeIsZero(t *testing.T) {
   626  	x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}}
   627  	b := new(bytes.Buffer)
   628  	enc := NewEncoder(b)
   629  	err := enc.Encode(x)
   630  	if err != nil {
   631  		t.Fatal("encode:", err)
   632  	}
   633  	var y isZeroBug
   634  	dec := NewDecoder(b)
   635  	err = dec.Decode(&y)
   636  	if err != nil {
   637  		t.Fatal("decode:", err)
   638  	}
   639  	if x != y {
   640  		t.Fatalf("%v != %v", x, y)
   641  	}
   642  }
   643  
   644  func TestGobEncodePtrError(t *testing.T) {
   645  	var err error
   646  	b := new(bytes.Buffer)
   647  	enc := NewEncoder(b)
   648  	err = enc.Encode(&err)
   649  	if err != nil {
   650  		t.Fatal("encode:", err)
   651  	}
   652  	dec := NewDecoder(b)
   653  	err2 := fmt.Errorf("foo")
   654  	err = dec.Decode(&err2)
   655  	if err != nil {
   656  		t.Fatal("decode:", err)
   657  	}
   658  	if err2 != nil {
   659  		t.Fatalf("expected nil, got %v", err2)
   660  	}
   661  }