1// Copyright 2014 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
5package rpc
6
7import (
8	"errors"
9	"fmt"
10	"net"
11	"runtime"
12	"strings"
13	"testing"
14)
15
16type shutdownCodec struct {
17	responded chan int
18	closed    bool
19}
20
21func (c *shutdownCodec) WriteRequest(*Request, interface{}) error { return nil }
22func (c *shutdownCodec) ReadResponseBody(interface{}) error       { return nil }
23func (c *shutdownCodec) ReadResponseHeader(*Response) error {
24	c.responded <- 1
25	return errors.New("shutdownCodec ReadResponseHeader")
26}
27func (c *shutdownCodec) Close() error {
28	c.closed = true
29	return nil
30}
31
32func TestCloseCodec(t *testing.T) {
33	codec := &shutdownCodec{responded: make(chan int)}
34	client := NewClientWithCodec(codec)
35	<-codec.responded
36	client.Close()
37	if !codec.closed {
38		t.Error("client.Close did not close codec")
39	}
40}
41
42// Test that errors in gob shut down the connection. Issue 7689.
43
44type R struct {
45	msg []byte // Not exported, so R does not work with gob.
46}
47
48type S struct{}
49
50func (s *S) Recv(nul *struct{}, reply *R) error {
51	*reply = R{[]byte("foo")}
52	return nil
53}
54
55func TestGobError(t *testing.T) {
56	if runtime.GOOS == "plan9" {
57		t.Skip("skipping test; see https://golang.org/issue/8908")
58	}
59	defer func() {
60		err := recover()
61		if err == nil {
62			t.Fatal("no error")
63		}
64		if !strings.Contains("reading body EOF", err.(error).Error()) {
65			t.Fatal("expected `reading body EOF', got", err)
66		}
67	}()
68	Register(new(S))
69
70	listen, err := net.Listen("tcp", "127.0.0.1:0")
71	if err != nil {
72		panic(err)
73	}
74	go Accept(listen)
75
76	client, err := Dial("tcp", listen.Addr().String())
77	if err != nil {
78		panic(err)
79	}
80
81	var reply Reply
82	err = client.Call("S.Recv", &struct{}{}, &reply)
83	if err != nil {
84		panic(err)
85	}
86
87	fmt.Printf("%#v\n", reply)
88	client.Close()
89
90	listen.Close()
91}
92