View Javadoc

1   // Copyright (C) 2005 - 2012 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.communication;
23  
24  import static org.junit.Assert.assertNull;
25  import static org.junit.Assert.assertSame;
26  import static org.junit.Assert.fail;
27  import static org.mockito.Matchers.isA;
28  import static org.mockito.Mockito.doThrow;
29  import static org.mockito.Mockito.times;
30  import static org.mockito.Mockito.verify;
31  import static org.mockito.Mockito.verifyNoMoreInteractions;
32  import net.grinder.communication.MessageDispatchRegistry.AbstractBlockingHandler;
33  import net.grinder.communication.MessageDispatchRegistry.AbstractHandler;
34  import net.grinder.communication.MessageDispatchRegistry.BlockingHandler;
35  import net.grinder.communication.MessageDispatchRegistry.Handler;
36  
37  import org.junit.Before;
38  import org.junit.Test;
39  import org.mockito.Mock;
40  import org.mockito.MockitoAnnotations;
41  
42  
43  /**
44   * Unit tests for {@link MessageDispatchSender}.
45   *
46   * @author Philip Aston
47   */
48  public class TestMessageDispatchSender {
49  
50    @Mock private Handler<Message> m_fallBackHandler;
51    @Mock private Handler<Message> m_handler;
52    @Mock private Handler<Message> m_handler2;
53    @Mock private BlockingHandler<OtherMessage> m_responder;
54    @Mock private Sender m_sender;
55  
56    @Before public void setUp() {
57      MockitoAnnotations.initMocks(this);
58    }
59  
60    @Test public void testSend() throws Exception {
61      final MessageDispatchSender messageDispatchSender =
62        new MessageDispatchSender();
63  
64      messageDispatchSender.send(new SimpleMessage());
65  
66      messageDispatchSender.addFallback(m_fallBackHandler);
67  
68      final Message m1 = new SimpleMessage();
69      final Message m2 = new SimpleMessage();
70  
71      messageDispatchSender.send(m1);
72      messageDispatchSender.send(m2);
73  
74      verify(m_fallBackHandler).handle(m1);
75      verify(m_fallBackHandler).handle(m2);
76  
77      final Handler<Message> previousHandler =
78        messageDispatchSender.set(SimpleMessage.class, m_handler);
79      assertNull(previousHandler);
80  
81      final Handler<Message> previousHandler2 =
82        messageDispatchSender.set(OtherMessage.class, m_handler2);
83      assertNull(previousHandler2);
84  
85      messageDispatchSender.send(m1);
86      messageDispatchSender.send(m2);
87  
88      verify(m_handler).handle(m1);
89      verify(m_handler).handle(m2);
90  
91      final OtherMessage m3 = new OtherMessage();
92      messageDispatchSender.send(m3);
93  
94      verify(m_handler2).handle(m3);
95  
96      final CommunicationException e = new CommunicationException("");
97      doThrow(e).when(m_handler).handle(m1);
98  
99      try {
100       messageDispatchSender.send(m1);
101       fail("Expected CommunicationException");
102     }
103     catch (CommunicationException e2) {
104       assertSame(e, e2);
105     }
106 
107     verify(m_handler, times(2)).handle(m1);
108 
109     verifyNoMoreInteractions(m_handler, m_handler2, m_fallBackHandler);
110   }
111 
112   @Test public void testWithMessageRequiringResponse() throws Exception {
113     final MessageDispatchSender messageDispatchSender =
114       new MessageDispatchSender();
115 
116     final Message message = new SimpleMessage();
117     final MessageRequiringResponse messageRequiringResponse =
118       new MessageRequiringResponse(message);
119 
120     try {
121       messageDispatchSender.send(messageRequiringResponse);
122       fail("Expected CommunicationException");
123     }
124     catch (CommunicationException e) {
125     }
126 
127     messageRequiringResponse.setResponder(m_sender);
128 
129     messageDispatchSender.send(messageRequiringResponse);
130     verify(m_sender).send(isA(NoResponseMessage.class));
131 
132     // Now check a handler can send a response.
133     final Message responseMessage = new SimpleMessage();
134 
135     messageDispatchSender.set(
136       SimpleMessage.class,
137       new MessageDispatchRegistry.AbstractBlockingHandler<SimpleMessage>() {
138         public Message blockingSend(SimpleMessage someMessage)  {
139           return responseMessage;
140         }
141       });
142 
143     final MessageRequiringResponse messageRequiringResponse2 =
144       new MessageRequiringResponse(message);
145     messageRequiringResponse2.setResponder(m_sender);
146 
147     messageDispatchSender.send(messageRequiringResponse2);
148     verify(m_sender).send(responseMessage);
149 
150     // Finally, check that fallback handler can handle response.
151     final Message responseMessage2 = new SimpleMessage();
152 
153     messageDispatchSender.addFallback(
154       new AbstractHandler<Message>() {
155         public void handle(Message theMessage) throws CommunicationException {
156           if (theMessage instanceof MessageRequiringResponse) {
157             final MessageRequiringResponse m =
158               (MessageRequiringResponse) theMessage;
159             m.sendResponse(responseMessage2);
160           }
161         }
162       });
163 
164     final MessageRequiringResponse messageRequiringResponse3 =
165       new MessageRequiringResponse(new OtherMessage());
166     messageRequiringResponse3.setResponder(m_sender);
167 
168     messageDispatchSender.send(messageRequiringResponse3);
169     verify(m_sender).send(responseMessage2);
170 
171     verifyNoMoreInteractions(m_sender);
172   }
173 
174   @Test public void testWithBadHandlers() throws Exception {
175     final MessageDispatchSender messageDispatchSender =
176       new MessageDispatchSender();
177 
178     final Message message = new SimpleMessage();
179 
180     final CommunicationException communicationException =
181       new CommunicationException("");
182     doThrow(communicationException).when(m_handler).handle(message);
183 
184     messageDispatchSender.addFallback(m_handler);
185 
186     try {
187       messageDispatchSender.send(message);
188     }
189     catch (CommunicationException e) {
190       assertSame(communicationException, e);
191     }
192 
193     messageDispatchSender.set(SimpleMessage.class, m_handler);
194 
195     try {
196       messageDispatchSender.send(message);
197     }
198     catch (CommunicationException e) {
199       assertSame(communicationException, e);
200     }
201 
202     verify(m_handler, times(2)).handle(message);
203 
204     verifyNoMoreInteractions(m_handler);
205   }
206 
207   @Test public void testShutdown() throws Exception {
208     final MessageDispatchSender messageDispatchSender =
209       new MessageDispatchSender();
210 
211     messageDispatchSender.shutdown();
212 
213     messageDispatchSender.set(SimpleMessage.class, m_handler);
214 
215     messageDispatchSender.shutdown();
216 
217     verify(m_handler).shutdown();
218 
219     messageDispatchSender.addFallback(m_handler2);
220     messageDispatchSender.addFallback(m_handler2);
221 
222     messageDispatchSender.set(OtherMessage.class, m_responder);
223 
224     final BlockingHandler<Message> blockingHandler2 =
225       new AbstractBlockingHandler<Message>() {
226         public Message blockingSend(Message message)
227           throws CommunicationException {
228             return null;
229         }};
230     messageDispatchSender.set(Message.class, blockingHandler2);
231 
232     messageDispatchSender.shutdown();
233 
234     verify(m_handler, times(2)).shutdown();
235 
236     verify(m_handler2, times(2)).shutdown();
237 
238     verify(m_responder).shutdown();
239 
240     verifyNoMoreInteractions(m_handler, m_handler2, m_responder);
241   }
242 
243   public static class OtherMessage implements Message {
244   }
245 }