2018-11-11 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / encoding / gob / gobencdec_test.go
blob41a06b26c876ee65d1dd07dcbe5221e3e8d53789
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.
7 package gob
9 import (
10 "bytes"
11 "errors"
12 "fmt"
13 "io"
14 "net"
15 "strings"
16 "testing"
17 "time"
20 // Types that implement the GobEncoder/Decoder interfaces.
22 type ByteStruct struct {
23 a byte // not an exported field
26 type StringStruct struct {
27 s string // not an exported field
30 type ArrayStruct struct {
31 a [8192]byte // not an exported field
34 type Gobber int
36 type ValueGobber string // encodes with a value, decodes with a pointer.
38 type BinaryGobber int
40 type BinaryValueGobber string
42 type TextGobber int
44 type TextValueGobber string
46 // The relevant methods
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
56 func (g *ByteStruct) GobDecode(data []byte) error {
57 if g == nil {
58 return errors.New("NIL RECEIVER")
60 // Expect N sequential-valued bytes.
61 if len(data) == 0 {
62 return io.EOF
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")
70 return nil
73 func (g *StringStruct) GobEncode() ([]byte, error) {
74 return []byte(g.s), nil
77 func (g *StringStruct) GobDecode(data []byte) error {
78 // Expect N sequential-valued bytes.
79 if len(data) == 0 {
80 return io.EOF
82 a := data[0]
83 for i, c := range data {
84 if c != a+byte(i) {
85 return errors.New("invalid data sequence")
88 g.s = string(data)
89 return nil
92 func (a *ArrayStruct) GobEncode() ([]byte, error) {
93 return a.a[:], nil
96 func (a *ArrayStruct) GobDecode(data []byte) error {
97 if len(data) != len(a.a) {
98 return errors.New("wrong length in array decode")
100 copy(a.a[:], data)
101 return nil
104 func (g *Gobber) GobEncode() ([]byte, error) {
105 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
108 func (g *Gobber) GobDecode(data []byte) error {
109 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
110 return err
113 func (g *BinaryGobber) MarshalBinary() ([]byte, error) {
114 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
117 func (g *BinaryGobber) UnmarshalBinary(data []byte) error {
118 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
119 return err
122 func (g *TextGobber) MarshalText() ([]byte, error) {
123 return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
126 func (g *TextGobber) UnmarshalText(data []byte) error {
127 _, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
128 return err
131 func (v ValueGobber) GobEncode() ([]byte, error) {
132 return []byte(fmt.Sprintf("VALUE=%s", v)), nil
135 func (v *ValueGobber) GobDecode(data []byte) error {
136 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
137 return err
140 func (v BinaryValueGobber) MarshalBinary() ([]byte, error) {
141 return []byte(fmt.Sprintf("VALUE=%s", v)), nil
144 func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error {
145 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
146 return err
149 func (v TextValueGobber) MarshalText() ([]byte, error) {
150 return []byte(fmt.Sprintf("VALUE=%s", v)), nil
153 func (v *TextValueGobber) UnmarshalText(data []byte) error {
154 _, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
155 return err
158 // Structs that include GobEncodable fields.
160 type GobTest0 struct {
161 X int // guarantee we have something in common with GobTest*
162 G *ByteStruct
165 type GobTest1 struct {
166 X int // guarantee we have something in common with GobTest*
167 G *StringStruct
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
175 type GobTest3 struct {
176 X int // guarantee we have something in common with GobTest*
177 G *Gobber
178 B *BinaryGobber
179 T *TextGobber
182 type GobTest4 struct {
183 X int // guarantee we have something in common with GobTest*
184 V ValueGobber
185 BV BinaryValueGobber
186 TV TextValueGobber
189 type GobTest5 struct {
190 X int // guarantee we have something in common with GobTest*
191 V *ValueGobber
192 BV *BinaryValueGobber
193 TV *TextValueGobber
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
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
216 type GobTestIgnoreEncoder struct {
217 X int // guarantee we have something in common with GobTest*
220 type GobTestValueEncDec struct {
221 X int // guarantee we have something in common with GobTest*
222 G StringStruct // not a pointer.
225 type GobTestIndirectEncDec struct {
226 X int // guarantee we have something in common with GobTest*
227 G ***StringStruct // indirections to the receiver.
230 type GobTestArrayEncDec struct {
231 X int // guarantee we have something in common with GobTest*
232 A ArrayStruct // not a pointer.
235 type GobTestIndirectArrayEncDec struct {
236 X int // guarantee we have something in common with GobTest*
237 A ***ArrayStruct // indirections to a large receiver.
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)
248 dec := NewDecoder(b)
249 x := new(GobTest0)
250 err = dec.Decode(x)
251 if err != nil {
252 t.Fatal("decode error:", err)
254 if x.G.a != 'A' {
255 t.Errorf("expected 'A' got %c", x.G.a)
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)
266 y := new(GobTest3)
267 err = dec.Decode(y)
268 if err != nil {
269 t.Fatal("decode error:", err)
271 if *y.G != 23 || *y.B != 24 || *y.T != 25 {
272 t.Errorf("expected '23 got %d", *y.G)
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)
286 dec := NewDecoder(b)
287 x := new(GobTestValueEncDec)
288 err = dec.Decode(x)
289 if err != nil {
290 t.Fatal("decode error:", err)
292 if x.G.s != "HIJKL" {
293 t.Errorf("expected `HIJKL` got %s", x.G.s)
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)
309 dec := NewDecoder(b)
310 x := new(GobTestIndirectEncDec)
311 err = dec.Decode(x)
312 if err != nil {
313 t.Fatal("decode error:", err)
315 if (***x.G).s != "HIJKL" {
316 t.Errorf("expected `HIJKL` got %s", (***x.G).s)
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)
329 err := enc.Encode(&a)
330 if err != nil {
331 t.Fatal("encode error:", err)
333 dec := NewDecoder(b)
334 x := new(GobTestArrayEncDec)
335 err = dec.Decode(x)
336 if err != nil {
337 t.Fatal("decode error:", err)
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
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)
360 err := enc.Encode(a)
361 if err != nil {
362 t.Fatal("encode error:", err)
364 dec := NewDecoder(b)
365 x := new(GobTestIndirectArrayEncDec)
366 err = dec.Decode(x)
367 if err != nil {
368 t.Fatal("decode error:", err)
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
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)
391 dec := NewDecoder(b)
392 x := new(GobTest0)
393 err = dec.Decode(x)
394 if err != nil {
395 t.Fatal("decode error:", err)
397 if x.G.a != 'A' {
398 t.Errorf("expected 'A' got %c", x.G.a)
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)
406 y := new(GobTest1)
407 err = dec.Decode(y)
408 if err != nil {
409 t.Fatal("decode error:", err)
411 if y.G.s != "XYZ" {
412 t.Fatalf("expected `XYZ` got %q", y.G.s)
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)
425 dec := NewDecoder(b)
426 x := new(GobTest5)
427 err = dec.Decode(x)
428 if err != nil {
429 t.Fatal("decode error:", err)
431 if *x.V != "hello" || *x.BV != "Καλημέρα" || *x.TV != "こんにちは" {
432 t.Errorf("expected `hello` got %s", *x.V)
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²")
446 // this was a bug: encoding a GobEncoder by value before a GobEncoder
447 // pointer would cause duplicate type definitions to be sent.
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)
454 dec := NewDecoder(b)
455 x := new(GobTest6)
456 if err := dec.Decode(x); err != nil {
457 t.Fatal("decode error:", err)
460 if got, want := x.V, v; got != want {
461 t.Errorf("v = %q, want %q", got, want)
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)
469 if got, want := x.BV, bv; got != want {
470 t.Errorf("bv = %q, want %q", got, want)
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)
478 if got, want := x.TV, tv; got != want {
479 t.Errorf("tv = %q, want %q", got, want)
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)
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²")
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)
503 dec := NewDecoder(b)
504 x := new(GobTest7)
505 if err := dec.Decode(x); err != nil {
506 t.Fatal("decode error:", err)
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)
514 if got, want := x.W, w; got != want {
515 t.Errorf("w = %q, want %q", got, want)
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)
523 if got, want := x.BW, bw; got != want {
524 t.Errorf("bw = %q, want %q", got, want)
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)
532 if got, want := x.TW, tw; got != want {
533 t.Errorf("tw = %q, want %q", got, want)
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)
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)")
551 if !strings.Contains(err.Error(), "type") {
552 t.Fatal("expected type error; got", err)
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)
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)")
565 if !strings.Contains(err.Error(), "type") {
566 t.Fatal("expected type error; got", err)
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)
578 dec := NewDecoder(b)
579 x := new(ByteStruct)
580 err = dec.Decode(x)
581 if err != nil {
582 t.Fatal("decode error:", err)
584 if x.a != 'A' {
585 t.Errorf("expected 'A' got %c", x.a)
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)
597 dec := NewDecoder(b)
598 var x Gobber
599 err = dec.Decode(&x)
600 if err != nil {
601 t.Fatal("decode error:", err)
603 if x != 1234 {
604 t.Errorf("expected 1234 got %d", x)
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)
616 dec := NewDecoder(b)
617 x := new(GobTestIgnoreEncoder)
618 err = dec.Decode(x)
619 if err != nil {
620 t.Fatal("decode error:", err)
622 if x.X != 17 {
623 t.Errorf("expected 17 got %c", x.X)
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)
638 dec := NewDecoder(b)
639 x := new(GobTestIgnoreEncoder)
640 err = dec.Decode(x)
641 if err != nil {
642 t.Fatal("decode error:", err)
644 if x.X != 17 {
645 t.Errorf("expected 17 got %c", x.X)
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)
657 dec := NewDecoder(b)
658 x := new(GobTest0)
659 err = dec.Decode(x)
660 if err != nil {
661 t.Fatal("decode error:", err)
663 if x.X != 18 {
664 t.Errorf("expected x.X = 18, got %v", x.X)
666 if x.G != nil {
667 t.Errorf("expected x.G = nil, got %v", x.G)
671 type gobDecoderBug0 struct {
672 foo, bar string
675 func (br *gobDecoderBug0) String() string {
676 return br.foo + "-" + br.bar
679 func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
680 return []byte(br.String()), nil
683 func (br *gobDecoderBug0) GobDecode(b []byte) error {
684 br.foo = "foo"
685 br.bar = "bar"
686 return nil
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)
698 d := NewDecoder(buf)
699 var got *gobDecoderBug0
700 if err := d.Decode(&got); err != nil {
701 t.Fatalf("decode: %v", err)
703 if got.foo != gdb.foo || got.bar != gdb.bar {
704 t.Errorf("got = %q, want %q", got, gdb)
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
719 type isZeroBugArray [2]uint8
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
727 func (a *isZeroBugArray) GobDecode(data []byte) error {
728 if len(data) != len(a) {
729 return io.EOF
731 a[0] = data[0]
732 a[1] = data[1]
733 return nil
736 type isZeroBugInterface struct {
737 I interface{}
740 func (i isZeroBugInterface) GobEncode() (b []byte, e error) {
741 return []byte{}, nil
744 func (i *isZeroBugInterface) GobDecode(data []byte) error {
745 return nil
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)
756 var y isZeroBug
757 dec := NewDecoder(b)
758 err = dec.Decode(&y)
759 if err != nil {
760 t.Fatal("decode:", err)
762 if x != y {
763 t.Fatalf("%v != %v", x, y)
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)
775 dec := NewDecoder(b)
776 err2 := fmt.Errorf("foo")
777 err = dec.Decode(&err2)
778 if err != nil {
779 t.Fatal("decode:", err)
781 if err2 != nil {
782 t.Fatalf("expected nil, got %v", err2)
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}
790 var ip net.IP
791 err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
792 if err != nil {
793 t.Fatalf("decode: %v", err)
795 if ip.String() != "1.2.3.4" {
796 t.Errorf("decoded to %v, want 1.2.3.4", ip.String())