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.Index(err.Error(), "type") < 0 { 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.Index(err.Error(), "type") < 0 { 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.Now(), "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