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.
5 // This file contains tests of the GobEncoder/GobDecoder support.
19 // Types that implement the GobEncoder/Decoder interfaces.
21 type ByteStruct struct {
22 a byte // not an exported field
25 type StringStruct struct {
26 s string // not an exported field
29 type ArrayStruct struct {
30 a [8192]byte // not an exported field
35 type ValueGobber string // encodes with a value, decodes with a pointer.
37 // The relevant methods
39 func (g *ByteStruct) GobEncode() ([]byte, error) {
47 func (g *ByteStruct) GobDecode(data []byte) error {
49 return errors.New("NIL RECEIVER")
51 // Expect N sequential-valued bytes.
56 for i, c := range data {
58 return errors.New("invalid data sequence")
64 func (g *StringStruct) GobEncode() ([]byte, error) {
65 return []byte(g.s), nil
68 func (g *StringStruct) GobDecode(data []byte) error {
69 // Expect N sequential-valued bytes.
74 for i, c := range data {
76 return errors.New("invalid data sequence")
83 func (a *ArrayStruct) GobEncode() ([]byte, error) {
87 func (a *ArrayStruct) GobDecode(data []byte) error {
88 if len(data) != len(a.a) {
89 return errors.New("wrong length in array decode")
95 func (g *Gobber) GobEncode() ([]byte, error) {
96 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
99 func (g *Gobber) GobDecode(data []byte) error {
100 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
104 func (v ValueGobber) GobEncode() ([]byte, error) {
105 return []byte(fmt.Sprintf("VALUE=%s", v)), nil
108 func (v *ValueGobber) GobDecode(data []byte) error {
109 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
113 // Structs that include GobEncodable fields.
115 type GobTest0 struct {
116 X int // guarantee we have something in common with GobTest*
120 type GobTest1 struct {
121 X int // guarantee we have something in common with GobTest*
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
130 type GobTest3 struct {
131 X int // guarantee we have something in common with GobTest*
135 type GobTest4 struct {
136 X int // guarantee we have something in common with GobTest*
140 type GobTest5 struct {
141 X int // guarantee we have something in common with GobTest*
145 type GobTest6 struct {
146 X int // guarantee we have something in common with GobTest*
151 type GobTest7 struct {
152 X int // guarantee we have something in common with GobTest*
157 type GobTestIgnoreEncoder struct {
158 X int // guarantee we have something in common with GobTest*
161 type GobTestValueEncDec struct {
162 X int // guarantee we have something in common with GobTest*
163 G StringStruct // not a pointer.
166 type GobTestIndirectEncDec struct {
167 X int // guarantee we have something in common with GobTest*
168 G ***StringStruct // indirections to the receiver.
171 type GobTestArrayEncDec struct {
172 X int // guarantee we have something in common with GobTest*
173 A ArrayStruct // not a pointer.
176 type GobTestIndirectArrayEncDec struct {
177 X int // guarantee we have something in common with GobTest*
178 A ***ArrayStruct // indirections to a large receiver.
181 func TestGobEncoderField(t *testing.T) {
182 b := new(bytes.Buffer)
183 // First a field that's a structure.
185 err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
187 t.Fatal("encode error:", err)
193 t.Fatal("decode error:", err)
196 t.Errorf("expected 'A' got %c", x.G.a)
198 // Now a field that's not a structure.
201 err = enc.Encode(GobTest3{17, &gobber})
203 t.Fatal("encode error:", err)
208 t.Fatal("decode error:", err)
211 t.Errorf("expected '23 got %d", *y.G)
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.
221 err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
223 t.Fatal("encode error:", err)
226 x := new(GobTestValueEncDec)
229 t.Fatal("decode error:", err)
231 if x.G.s != "HIJKL" {
232 t.Errorf("expected `HIJKL` got %s", x.G.s)
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.
242 s := &StringStruct{"HIJKL"}
244 err := enc.Encode(GobTestIndirectEncDec{17, &sp})
246 t.Fatal("encode error:", err)
249 x := new(GobTestIndirectEncDec)
252 t.Fatal("decode error:", err)
254 if (***x.G).s != "HIJKL" {
255 t.Errorf("expected `HIJKL` got %s", (***x.G).s)
259 // Test with a large field with methods.
260 func TestGobEncoderArrayField(t *testing.T) {
261 b := new(bytes.Buffer)
263 var a GobTestArrayEncDec
265 for i := range a.A.a {
270 t.Fatal("encode error:", err)
273 x := new(GobTestArrayEncDec)
276 t.Fatal("decode error:", err)
278 for i, v := range x.A.a {
280 t.Errorf("expected %x got %x", byte(i), v)
286 // Test an indirection to a large field with methods.
287 func TestGobEncoderIndirectArrayField(t *testing.T) {
288 b := new(bytes.Buffer)
290 var a GobTestIndirectArrayEncDec
292 var array ArrayStruct
296 for i := range array.a {
301 t.Fatal("encode error:", err)
304 x := new(GobTestIndirectArrayEncDec)
307 t.Fatal("decode error:", err)
309 for i, v := range (***x.A).a {
311 t.Errorf("expected %x got %x", byte(i), v)
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)
326 err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
328 t.Fatal("encode error:", err)
334 t.Fatal("decode error:", err)
337 t.Errorf("expected 'A' got %c", x.G.a)
339 // now the other direction, byte in field to string in field
341 err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
343 t.Fatal("encode error:", err)
348 t.Fatal("decode error:", err)
351 t.Fatalf("expected `XYZ` got %q", y.G.s)
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)
360 err := enc.Encode(GobTest4{17, ValueGobber("hello")})
362 t.Fatal("encode error:", err)
368 t.Fatal("decode error:", err)
371 t.Errorf("expected `hello` got %s", x.V)
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")
381 // this was a bug: encoding a GobEncoder by value before a GobEncoder
382 // pointer would cause duplicate type definitions to be sent.
384 b := new(bytes.Buffer)
386 if err := enc.Encode(GobTest6{42, v, &w}); err != nil {
387 t.Fatal("encode error:", err)
391 if err := dec.Decode(x); err != nil {
392 t.Fatal("decode error:", err)
394 if got, want := x.V, v; got != want {
395 t.Errorf("v = %q, want %q", got, want)
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)
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")
410 b := new(bytes.Buffer)
412 if err := enc.Encode(GobTest7{42, &v, w}); err != nil {
413 t.Fatal("encode error:", err)
417 if err := dec.Decode(x); err != nil {
418 t.Fatal("decode error:", err)
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)
425 if got, want := x.W, w; got != want {
426 t.Errorf("w = %q, want %q", got, want)
430 func TestGobEncoderFieldTypeError(t *testing.T) {
431 // GobEncoder to non-decoder: error
432 b := new(bytes.Buffer)
434 err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
436 t.Fatal("encode error:", err)
442 t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
444 if strings.Index(err.Error(), "type") < 0 {
445 t.Fatal("expected type error; got", err)
447 // Non-encoder to GobDecoder: error
449 err = enc.Encode(GobTest2{17, "ABC"})
451 t.Fatal("encode error:", err)
456 t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
458 if strings.Index(err.Error(), "type") < 0 {
459 t.Fatal("expected type error; got", err)
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)
467 err := enc.Encode(&ByteStruct{'A'})
469 t.Fatal("encode error:", err)
475 t.Fatal("decode error:", err)
478 t.Errorf("expected 'A' got %c", x.a)
482 func TestGobEncoderNonStructSingleton(t *testing.T) {
483 b := new(bytes.Buffer)
485 err := enc.Encode(Gobber(1234))
487 t.Fatal("encode error:", err)
493 t.Fatal("decode error:", err)
496 t.Errorf("expected 1234 got %d", x)
500 func TestGobEncoderIgnoreStructField(t *testing.T) {
501 b := new(bytes.Buffer)
502 // First a field that's a structure.
504 err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
506 t.Fatal("encode error:", err)
509 x := new(GobTestIgnoreEncoder)
512 t.Fatal("decode error:", err)
515 t.Errorf("expected 17 got %c", x.X)
519 func TestGobEncoderIgnoreNonStructField(t *testing.T) {
520 b := new(bytes.Buffer)
521 // First a field that's a structure.
524 err := enc.Encode(GobTest3{17, &gobber})
526 t.Fatal("encode error:", err)
529 x := new(GobTestIgnoreEncoder)
532 t.Fatal("decode error:", err)
535 t.Errorf("expected 17 got %c", x.X)
539 func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
540 b := new(bytes.Buffer)
541 // First a field that's a structure.
543 err := enc.Encode(GobTest0{X: 18}) // G is nil
545 t.Fatal("encode error:", err)
551 t.Fatal("decode error:", err)
554 t.Errorf("expected x.X = 18, got %v", x.X)
557 t.Errorf("expected x.G = nil, got %v", x.G)
561 type gobDecoderBug0 struct {
565 func (br *gobDecoderBug0) String() string {
566 return br.foo + "-" + br.bar
569 func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
570 return []byte(br.String()), nil
573 func (br *gobDecoderBug0) GobDecode(b []byte) error {
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)
585 if err := e.Encode(gdb); err != nil {
586 t.Fatalf("encode: %v", err)
589 var got *gobDecoderBug0
590 if err := d.Decode(&got); err != nil {
591 t.Fatalf("decode: %v", err)
593 if got.foo != gdb.foo || got.bar != gdb.bar {
594 t.Errorf("got = %q, want %q", got, gdb)
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
601 type isZeroBug struct {
608 type isZeroBugArray [2]uint8
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[:]...)
616 func (a *isZeroBugArray) GobDecode(data []byte) error {
617 if len(data) != len(a) {
625 func TestGobEncodeIsZero(t *testing.T) {
626 x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}}
627 b := new(bytes.Buffer)
631 t.Fatal("encode:", err)
637 t.Fatal("decode:", err)
640 t.Fatalf("%v != %v", x, y)
644 func TestGobEncodePtrError(t *testing.T) {
646 b := new(bytes.Buffer)
648 err = enc.Encode(&err)
650 t.Fatal("encode:", err)
653 err2 := fmt.Errorf("foo")
654 err = dec.Decode(&err2)
656 t.Fatal("decode:", err)
659 t.Fatalf("expected nil, got %v", err2)