1package muduo.rpc.test;
2
3import static org.junit.Assert.assertEquals;
4
5import java.util.HashMap;
6import java.util.Map;
7
8import muduo.rpc.RpcChannel;
9import muduo.rpc.RpcDecoder;
10import muduo.rpc.RpcEncoder;
11import muduo.rpc.proto.RpcProto.MessageType;
12import muduo.rpc.proto.RpcProto.RpcMessage;
13
14import org.jboss.netty.buffer.BigEndianHeapChannelBuffer;
15import org.jboss.netty.buffer.ChannelBuffer;
16import org.jboss.netty.channel.UpstreamMessageEvent;
17import org.junit.Test;
18
19import sudoku.Sudoku;
20import sudoku.Sudoku.SudokuRequest;
21import sudoku.Sudoku.SudokuResponse;
22import sudoku.Sudoku.SudokuService;
23import sudoku.Sudoku.SudokuService.Interface;
24
25import com.google.protobuf.RpcCallback;
26import com.google.protobuf.RpcController;
27import com.google.protobuf.Service;
28
29import echo.EchoProto.EchoService;
30import echo.EchoServer;
31import echo.EchoProto.EchoRequest;
32
33public class RpcTest {
34
35    @Test
36    public void testEncoder() throws Exception {
37        RpcEncoder encoder = new RpcEncoder();
38        RpcMessage message = RpcMessage.newBuilder().setType(MessageType.REQUEST).setId(1).build();
39        encoder.encode(null, null, message);
40    }
41
42    @Test
43    public void testEncoder2() throws Exception {
44        RpcEncoder encoder = new RpcEncoder();
45        EchoRequest request = EchoRequest.newBuilder().setPayload("Hello").build();
46        RpcMessage message = RpcMessage.newBuilder().setType(MessageType.REQUEST).setId(1)
47                .setService(EchoService.getDescriptor().getFullName())
48                .setMethod(EchoService.getDescriptor().getMethods().get(0).getName())
49                .setRequest(request.toByteString()).build();
50        encoder.encode(null, null, message);
51    }
52
53    @Test
54    public void testDecoder() throws Exception {
55        RpcEncoder encoder = new RpcEncoder();
56        SudokuRequest request = SudokuRequest.newBuilder().setCheckerboard("001010").build();
57        RpcMessage message = RpcMessage.newBuilder().setType(MessageType.REQUEST).setId(1)
58                .setService(SudokuService.getDescriptor().getFullName())
59                .setMethod(SudokuService.getDescriptor().getMethods().get(0).getName())
60                .setRequest(request.toByteString()).build();
61        ChannelBuffer buffer = (ChannelBuffer) encoder.encode(null, null, message);
62
63        RpcDecoder decoder = new RpcDecoder();
64        RpcMessage decodedMessage = (RpcMessage) decoder.decode(null, null, buffer);
65        assertEquals(1, decodedMessage.getId());
66    }
67
68    @Test
69    public void testDecoder2() throws Exception {
70        RpcEncoder encoder = new RpcEncoder();
71        RpcMessage message = RpcMessage.newBuilder().setType(MessageType.REQUEST).setId(2).build();
72        ChannelBuffer buffer = (ChannelBuffer) encoder.encode(null, null, message);
73        ChannelBuffer buf2 = new BigEndianHeapChannelBuffer(buffer.readableBytes() + 8);
74        buf2.writeInt(123);
75        buf2.writeBytes(buffer);
76
77        buf2.readInt();
78        RpcDecoder decoder = new RpcDecoder();
79        RpcMessage decodedMessage = (RpcMessage) decoder.decode(null, null, buf2);
80        assertEquals(2, decodedMessage.getId());
81    }
82
83    SudokuResponse gotResponse;
84
85    @Test
86    public void testClient() throws Exception {
87        MockChannel mockChannel = new MockChannel();
88        RpcChannel channel = new RpcChannel(mockChannel);
89        SudokuService remoteService = Sudoku.SudokuService.newStub(channel);
90        SudokuRequest request = SudokuRequest.newBuilder().setCheckerboard("001010").build();
91        remoteService.solve(null, request, new RpcCallback<Sudoku.SudokuResponse>() {
92            @Override
93            public void run(SudokuResponse response) {
94                // System.out.println(parameter);
95                gotResponse = response;
96            }
97        });
98        RpcMessage message = (RpcMessage) mockChannel.message;
99        assertEquals(1, message.getId());
100        assertEquals(MessageType.REQUEST, message.getType());
101        assertEquals(remoteService.getDescriptorForType().getFullName(), message.getService());
102        assertEquals("Solve", message.getMethod());
103
104        SudokuResponse sudokuResponse = SudokuResponse.newBuilder()
105                .setSolved(true)
106                .setCheckerboard("123456")
107                .build();
108        RpcMessage response = RpcMessage.newBuilder()
109                .setType(MessageType.RESPONSE)
110                .setId(1)
111                .setResponse(sudokuResponse.toByteString())
112                .build();
113        channel.messageReceived(null, new UpstreamMessageEvent(mockChannel, response, null));
114        assertEquals(sudokuResponse, gotResponse);
115    }
116
117    SudokuRequest gotRequest;
118
119    @Test
120    public void testServer() throws Exception {
121
122        MockChannel mockChannel = new MockChannel();
123        Map<String, Service> services = new HashMap<String, Service>();
124        final SudokuResponse sudokuResponse = SudokuResponse.newBuilder()
125                .setSolved(true)
126                .setCheckerboard("98765")
127                .build();
128        Interface mockImpl = new Interface() {
129
130            @Override
131            public void solve(RpcController controller, SudokuRequest request,
132                    RpcCallback<SudokuResponse> done) {
133                gotRequest = request;
134
135                done.run(sudokuResponse);
136            }
137        };
138        services.put(SudokuService.getDescriptor().getFullName(),
139                SudokuService.newReflectiveService(mockImpl));
140        RpcChannel channel = new RpcChannel(mockChannel);
141        channel.setServiceMap(services);
142
143        SudokuRequest sudokuRequest = SudokuRequest.newBuilder().setCheckerboard("001010").build();
144        RpcMessage request = RpcMessage.newBuilder()
145                .setType(MessageType.REQUEST)
146                .setId(2)
147                .setService(SudokuService.getDescriptor().getFullName())
148                .setMethod("Solve")
149                .setRequest(sudokuRequest.toByteString())
150                .build();
151
152        channel.messageReceived(null, new UpstreamMessageEvent(mockChannel, request, null));
153        assertEquals(sudokuRequest, gotRequest);
154
155        RpcMessage response = RpcMessage.newBuilder()
156                .setType(MessageType.RESPONSE)
157                .setId(2)
158                .setResponse(sudokuResponse.toByteString())
159                .build();
160        assertEquals(response, mockChannel.message);
161    }
162}
163