110 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package mucp
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"errors"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/asim/go-micro/v3/codec"
 | |
| 	"github.com/asim/go-micro/v3/network/transport"
 | |
| )
 | |
| 
 | |
| // testCodec is a dummy codec that only knows how to encode nil bodies
 | |
| type testCodec struct {
 | |
| 	buf *bytes.Buffer
 | |
| }
 | |
| 
 | |
| type testSocket struct {
 | |
| 	local  string
 | |
| 	remote string
 | |
| }
 | |
| 
 | |
| // TestCodecWriteError simulates what happens when a codec is unable
 | |
| // to encode a message (e.g. a missing branch of an "oneof" message in
 | |
| // protobufs)
 | |
| //
 | |
| // We expect an error to be sent to the socket. Previously the socket
 | |
| // would remain open with no bytes sent, leading to client-side
 | |
| // timeouts.
 | |
| func TestCodecWriteError(t *testing.T) {
 | |
| 	socket := testSocket{}
 | |
| 	message := transport.Message{
 | |
| 		Header: map[string]string{},
 | |
| 		Body:   []byte{},
 | |
| 	}
 | |
| 
 | |
| 	rwc := readWriteCloser{
 | |
| 		rbuf: new(bytes.Buffer),
 | |
| 		wbuf: new(bytes.Buffer),
 | |
| 	}
 | |
| 
 | |
| 	c := rpcCodec{
 | |
| 		buf: &rwc,
 | |
| 		codec: &testCodec{
 | |
| 			buf: rwc.wbuf,
 | |
| 		},
 | |
| 		req:    &message,
 | |
| 		socket: socket,
 | |
| 	}
 | |
| 
 | |
| 	err := c.Write(&codec.Message{
 | |
| 		Endpoint: "Service.Endpoint",
 | |
| 		Id:       "0",
 | |
| 		Error:    "",
 | |
| 	}, "body")
 | |
| 
 | |
| 	if err != nil {
 | |
| 		t.Fatalf(`Expected Write to fail; got "%+v" instead`, err)
 | |
| 	}
 | |
| 
 | |
| 	const expectedError = "Unable to encode body: simulating a codec write failure"
 | |
| 	actualError := rwc.wbuf.String()
 | |
| 	if actualError != expectedError {
 | |
| 		t.Fatalf(`Expected error "%+v" in the write buffer, got "%+v" instead`, expectedError, actualError)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (c *testCodec) ReadHeader(message *codec.Message, typ codec.MessageType) error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *testCodec) ReadBody(dest interface{}) error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *testCodec) Write(message *codec.Message, dest interface{}) error {
 | |
| 	if dest != nil {
 | |
| 		return errors.New("simulating a codec write failure")
 | |
| 	}
 | |
| 	c.buf.Write([]byte(message.Error))
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *testCodec) Close() error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *testCodec) String() string {
 | |
| 	return "string"
 | |
| }
 | |
| 
 | |
| func (s testSocket) Local() string {
 | |
| 	return s.local
 | |
| }
 | |
| 
 | |
| func (s testSocket) Remote() string {
 | |
| 	return s.remote
 | |
| }
 | |
| 
 | |
| func (s testSocket) Recv(message *transport.Message) error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (s testSocket) Send(message *transport.Message) error {
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (s testSocket) Close() error {
 | |
| 	return nil
 | |
| }
 |