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