Imported Upstream version 4.7.2
[platform/upstream/gcc48.git] / libgo / go / encoding / gob / gobencdec_test.go
1 // Copyright 20011 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 GobTestIgnoreEncoder struct {
146         X int // guarantee we have  something in common with GobTest*
147 }
148
149 type GobTestValueEncDec struct {
150         X int          // guarantee we have  something in common with GobTest*
151         G StringStruct // not a pointer.
152 }
153
154 type GobTestIndirectEncDec struct {
155         X int             // guarantee we have  something in common with GobTest*
156         G ***StringStruct // indirections to the receiver.
157 }
158
159 type GobTestArrayEncDec struct {
160         X int         // guarantee we have  something in common with GobTest*
161         A ArrayStruct // not a pointer.
162 }
163
164 type GobTestIndirectArrayEncDec struct {
165         X int            // guarantee we have  something in common with GobTest*
166         A ***ArrayStruct // indirections to a large receiver.
167 }
168
169 func TestGobEncoderField(t *testing.T) {
170         b := new(bytes.Buffer)
171         // First a field that's a structure.
172         enc := NewEncoder(b)
173         err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
174         if err != nil {
175                 t.Fatal("encode error:", err)
176         }
177         dec := NewDecoder(b)
178         x := new(GobTest0)
179         err = dec.Decode(x)
180         if err != nil {
181                 t.Fatal("decode error:", err)
182         }
183         if x.G.a != 'A' {
184                 t.Errorf("expected 'A' got %c", x.G.a)
185         }
186         // Now a field that's not a structure.
187         b.Reset()
188         gobber := Gobber(23)
189         err = enc.Encode(GobTest3{17, &gobber})
190         if err != nil {
191                 t.Fatal("encode error:", err)
192         }
193         y := new(GobTest3)
194         err = dec.Decode(y)
195         if err != nil {
196                 t.Fatal("decode error:", err)
197         }
198         if *y.G != 23 {
199                 t.Errorf("expected '23 got %d", *y.G)
200         }
201 }
202
203 // Even though the field is a value, we can still take its address
204 // and should be able to call the methods.
205 func TestGobEncoderValueField(t *testing.T) {
206         b := new(bytes.Buffer)
207         // First a field that's a structure.
208         enc := NewEncoder(b)
209         err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
210         if err != nil {
211                 t.Fatal("encode error:", err)
212         }
213         dec := NewDecoder(b)
214         x := new(GobTestValueEncDec)
215         err = dec.Decode(x)
216         if err != nil {
217                 t.Fatal("decode error:", err)
218         }
219         if x.G.s != "HIJKL" {
220                 t.Errorf("expected `HIJKL` got %s", x.G.s)
221         }
222 }
223
224 // GobEncode/Decode should work even if the value is
225 // more indirect than the receiver.
226 func TestGobEncoderIndirectField(t *testing.T) {
227         b := new(bytes.Buffer)
228         // First a field that's a structure.
229         enc := NewEncoder(b)
230         s := &StringStruct{"HIJKL"}
231         sp := &s
232         err := enc.Encode(GobTestIndirectEncDec{17, &sp})
233         if err != nil {
234                 t.Fatal("encode error:", err)
235         }
236         dec := NewDecoder(b)
237         x := new(GobTestIndirectEncDec)
238         err = dec.Decode(x)
239         if err != nil {
240                 t.Fatal("decode error:", err)
241         }
242         if (***x.G).s != "HIJKL" {
243                 t.Errorf("expected `HIJKL` got %s", (***x.G).s)
244         }
245 }
246
247 // Test with a large field with methods.
248 func TestGobEncoderArrayField(t *testing.T) {
249         b := new(bytes.Buffer)
250         enc := NewEncoder(b)
251         var a GobTestArrayEncDec
252         a.X = 17
253         for i := range a.A.a {
254                 a.A.a[i] = byte(i)
255         }
256         err := enc.Encode(a)
257         if err != nil {
258                 t.Fatal("encode error:", err)
259         }
260         dec := NewDecoder(b)
261         x := new(GobTestArrayEncDec)
262         err = dec.Decode(x)
263         if err != nil {
264                 t.Fatal("decode error:", err)
265         }
266         for i, v := range x.A.a {
267                 if v != byte(i) {
268                         t.Errorf("expected %x got %x", byte(i), v)
269                         break
270                 }
271         }
272 }
273
274 // Test an indirection to a large field with methods.
275 func TestGobEncoderIndirectArrayField(t *testing.T) {
276         b := new(bytes.Buffer)
277         enc := NewEncoder(b)
278         var a GobTestIndirectArrayEncDec
279         a.X = 17
280         var array ArrayStruct
281         ap := &array
282         app := &ap
283         a.A = &app
284         for i := range array.a {
285                 array.a[i] = byte(i)
286         }
287         err := enc.Encode(a)
288         if err != nil {
289                 t.Fatal("encode error:", err)
290         }
291         dec := NewDecoder(b)
292         x := new(GobTestIndirectArrayEncDec)
293         err = dec.Decode(x)
294         if err != nil {
295                 t.Fatal("decode error:", err)
296         }
297         for i, v := range (***x.A).a {
298                 if v != byte(i) {
299                         t.Errorf("expected %x got %x", byte(i), v)
300                         break
301                 }
302         }
303 }
304
305 // As long as the fields have the same name and implement the
306 // interface, we can cross-connect them.  Not sure it's useful
307 // and may even be bad but it works and it's hard to prevent
308 // without exposing the contents of the object, which would
309 // defeat the purpose.
310 func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
311         // first, string in field to byte in field
312         b := new(bytes.Buffer)
313         enc := NewEncoder(b)
314         err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
315         if err != nil {
316                 t.Fatal("encode error:", err)
317         }
318         dec := NewDecoder(b)
319         x := new(GobTest0)
320         err = dec.Decode(x)
321         if err != nil {
322                 t.Fatal("decode error:", err)
323         }
324         if x.G.a != 'A' {
325                 t.Errorf("expected 'A' got %c", x.G.a)
326         }
327         // now the other direction, byte in field to string in field
328         b.Reset()
329         err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
330         if err != nil {
331                 t.Fatal("encode error:", err)
332         }
333         y := new(GobTest1)
334         err = dec.Decode(y)
335         if err != nil {
336                 t.Fatal("decode error:", err)
337         }
338         if y.G.s != "XYZ" {
339                 t.Fatalf("expected `XYZ` got %c", y.G.s)
340         }
341 }
342
343 // Test that we can encode a value and decode into a pointer.
344 func TestGobEncoderValueEncoder(t *testing.T) {
345         // first, string in field to byte in field
346         b := new(bytes.Buffer)
347         enc := NewEncoder(b)
348         err := enc.Encode(GobTest4{17, ValueGobber("hello")})
349         if err != nil {
350                 t.Fatal("encode error:", err)
351         }
352         dec := NewDecoder(b)
353         x := new(GobTest5)
354         err = dec.Decode(x)
355         if err != nil {
356                 t.Fatal("decode error:", err)
357         }
358         if *x.V != "hello" {
359                 t.Errorf("expected `hello` got %s", x.V)
360         }
361 }
362
363 func TestGobEncoderFieldTypeError(t *testing.T) {
364         // GobEncoder to non-decoder: error
365         b := new(bytes.Buffer)
366         enc := NewEncoder(b)
367         err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
368         if err != nil {
369                 t.Fatal("encode error:", err)
370         }
371         dec := NewDecoder(b)
372         x := &GobTest2{}
373         err = dec.Decode(x)
374         if err == nil {
375                 t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
376         }
377         if strings.Index(err.Error(), "type") < 0 {
378                 t.Fatal("expected type error; got", err)
379         }
380         // Non-encoder to GobDecoder: error
381         b.Reset()
382         err = enc.Encode(GobTest2{17, "ABC"})
383         if err != nil {
384                 t.Fatal("encode error:", err)
385         }
386         y := &GobTest1{}
387         err = dec.Decode(y)
388         if err == nil {
389                 t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
390         }
391         if strings.Index(err.Error(), "type") < 0 {
392                 t.Fatal("expected type error; got", err)
393         }
394 }
395
396 // Even though ByteStruct is a struct, it's treated as a singleton at the top level.
397 func TestGobEncoderStructSingleton(t *testing.T) {
398         b := new(bytes.Buffer)
399         enc := NewEncoder(b)
400         err := enc.Encode(&ByteStruct{'A'})
401         if err != nil {
402                 t.Fatal("encode error:", err)
403         }
404         dec := NewDecoder(b)
405         x := new(ByteStruct)
406         err = dec.Decode(x)
407         if err != nil {
408                 t.Fatal("decode error:", err)
409         }
410         if x.a != 'A' {
411                 t.Errorf("expected 'A' got %c", x.a)
412         }
413 }
414
415 func TestGobEncoderNonStructSingleton(t *testing.T) {
416         b := new(bytes.Buffer)
417         enc := NewEncoder(b)
418         err := enc.Encode(Gobber(1234))
419         if err != nil {
420                 t.Fatal("encode error:", err)
421         }
422         dec := NewDecoder(b)
423         var x Gobber
424         err = dec.Decode(&x)
425         if err != nil {
426                 t.Fatal("decode error:", err)
427         }
428         if x != 1234 {
429                 t.Errorf("expected 1234 got %d", x)
430         }
431 }
432
433 func TestGobEncoderIgnoreStructField(t *testing.T) {
434         b := new(bytes.Buffer)
435         // First a field that's a structure.
436         enc := NewEncoder(b)
437         err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
438         if err != nil {
439                 t.Fatal("encode error:", err)
440         }
441         dec := NewDecoder(b)
442         x := new(GobTestIgnoreEncoder)
443         err = dec.Decode(x)
444         if err != nil {
445                 t.Fatal("decode error:", err)
446         }
447         if x.X != 17 {
448                 t.Errorf("expected 17 got %c", x.X)
449         }
450 }
451
452 func TestGobEncoderIgnoreNonStructField(t *testing.T) {
453         b := new(bytes.Buffer)
454         // First a field that's a structure.
455         enc := NewEncoder(b)
456         gobber := Gobber(23)
457         err := enc.Encode(GobTest3{17, &gobber})
458         if err != nil {
459                 t.Fatal("encode error:", err)
460         }
461         dec := NewDecoder(b)
462         x := new(GobTestIgnoreEncoder)
463         err = dec.Decode(x)
464         if err != nil {
465                 t.Fatal("decode error:", err)
466         }
467         if x.X != 17 {
468                 t.Errorf("expected 17 got %c", x.X)
469         }
470 }
471
472 func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
473         b := new(bytes.Buffer)
474         // First a field that's a structure.
475         enc := NewEncoder(b)
476         err := enc.Encode(GobTest0{X: 18}) // G is nil
477         if err != nil {
478                 t.Fatal("encode error:", err)
479         }
480         dec := NewDecoder(b)
481         x := new(GobTest0)
482         err = dec.Decode(x)
483         if err != nil {
484                 t.Fatal("decode error:", err)
485         }
486         if x.X != 18 {
487                 t.Errorf("expected x.X = 18, got %v", x.X)
488         }
489         if x.G != nil {
490                 t.Errorf("expected x.G = nil, got %v", x.G)
491         }
492 }
493
494 type gobDecoderBug0 struct {
495         foo, bar string
496 }
497
498 func (br *gobDecoderBug0) String() string {
499         return br.foo + "-" + br.bar
500 }
501
502 func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
503         return []byte(br.String()), nil
504 }
505
506 func (br *gobDecoderBug0) GobDecode(b []byte) error {
507         br.foo = "foo"
508         br.bar = "bar"
509         return nil
510 }
511
512 // This was a bug: the receiver has a different indirection level
513 // than the variable.
514 func TestGobEncoderExtraIndirect(t *testing.T) {
515         gdb := &gobDecoderBug0{"foo", "bar"}
516         buf := new(bytes.Buffer)
517         e := NewEncoder(buf)
518         if err := e.Encode(gdb); err != nil {
519                 t.Fatalf("encode: %v", err)
520         }
521         d := NewDecoder(buf)
522         var got *gobDecoderBug0
523         if err := d.Decode(&got); err != nil {
524                 t.Fatalf("decode: %v", err)
525         }
526         if got.foo != gdb.foo || got.bar != gdb.bar {
527                 t.Errorf("got = %q, want %q", got, gdb)
528         }
529 }
530
531 // Another bug: this caused a crash with the new Go1 Time type.
532 // We throw in a gob-encoding array, to test another case of isZero
533
534 type isZeroBug struct {
535         T time.Time
536         S string
537         I int
538         A isZeroBugArray
539 }
540
541 type isZeroBugArray [2]uint8
542
543 // Receiver is value, not pointer, to test isZero of array.
544 func (a isZeroBugArray) GobEncode() (b []byte, e error) {
545         b = append(b, a[:]...)
546         return b, nil
547 }
548
549 func (a *isZeroBugArray) GobDecode(data []byte) error {
550         if len(data) != len(a) {
551                 return io.EOF
552         }
553         a[0] = data[0]
554         a[1] = data[1]
555         return nil
556 }
557
558 func TestGobEncodeIsZero(t *testing.T) {
559         x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}}
560         b := new(bytes.Buffer)
561         enc := NewEncoder(b)
562         err := enc.Encode(x)
563         if err != nil {
564                 t.Fatal("encode:", err)
565         }
566         var y isZeroBug
567         dec := NewDecoder(b)
568         err = dec.Decode(&y)
569         if err != nil {
570                 t.Fatal("decode:", err)
571         }
572         if x != y {
573                 t.Fatalf("%v != %v", x, y)
574         }
575 }
576
577 func TestGobEncodePtrError(t *testing.T) {
578         var err error
579         b := new(bytes.Buffer)
580         enc := NewEncoder(b)
581         err = enc.Encode(&err)
582         if err != nil {
583                 t.Fatal("encode:", err)
584         }
585         dec := NewDecoder(b)
586         err2 := fmt.Errorf("foo")
587         err = dec.Decode(&err2)
588         if err != nil {
589                 t.Fatal("decode:", err)
590         }
591         if err2 != nil {
592                 t.Fatalf("expected nil, got %v", err2)
593         }
594 }