...
Run Format

Source file src/encoding/gob/gobencdec_test.go

Documentation: encoding/gob

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

View as plain text