1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.test.transport;
17
18 import org.fourthline.cling.UpnpServiceConfiguration;
19 import org.fourthline.cling.mock.MockProtocolFactory;
20 import org.fourthline.cling.mock.MockRouter;
21 import org.fourthline.cling.mock.MockUpnpServiceConfiguration;
22 import org.fourthline.cling.model.message.StreamRequestMessage;
23 import org.fourthline.cling.model.message.StreamResponseMessage;
24 import org.fourthline.cling.model.message.UpnpRequest;
25 import org.fourthline.cling.model.message.UpnpResponse;
26 import org.fourthline.cling.protocol.ProtocolCreationException;
27 import org.fourthline.cling.protocol.ReceivingSync;
28 import org.fourthline.cling.transport.spi.StreamClient;
29 import org.fourthline.cling.transport.spi.StreamServer;
30 import org.fourthline.cling.transport.spi.UpnpStream;
31 import org.testng.annotations.AfterClass;
32 import org.testng.annotations.BeforeClass;
33 import org.testng.annotations.BeforeMethod;
34 import org.testng.annotations.Test;
35
36 import java.net.InetAddress;
37 import java.net.URI;
38 import java.util.logging.Logger;
39
40 import static org.testng.Assert.*;
41
42 abstract public class StreamServerClientTest {
43
44 final private static Logger log = Logger.getLogger(StreamServerClientTest.class.getName());
45
46 public static final String TEST_HOST = "localhost";
47 public static final int TEST_PORT = 8081;
48
49 public UpnpServiceConfiguration configuration = new MockUpnpServiceConfiguration(false, true);
50
51 public MockProtocolFactory protocolFactory = new MockProtocolFactory() {
52
53 @Override
54 public ReceivingSync createReceivingSync(StreamRequestMessage requestMessage) throws ProtocolCreationException {
55 String path = requestMessage.getUri().getPath();
56 if (path.endsWith(OKEmptyResponse.PATH)) {
57 lastExecutedServerProtocol = new OKEmptyResponse(requestMessage);
58 } else if (path.endsWith(OKBodyResponse.PATH)) {
59 lastExecutedServerProtocol = new OKBodyResponse(requestMessage);
60 } else if (path.endsWith(NoResponse.PATH)) {
61 lastExecutedServerProtocol = new NoResponse(requestMessage);
62 } else if (path.endsWith(DelayedResponse.PATH)) {
63 lastExecutedServerProtocol = new DelayedResponse(requestMessage);
64 } else if (path.endsWith(TooLongResponse.PATH)) {
65 lastExecutedServerProtocol = new TooLongResponse(requestMessage);
66 } else if (path.endsWith(CheckAliveResponse.PATH)) {
67 lastExecutedServerProtocol = new CheckAliveResponse(requestMessage);
68 } else if (path.endsWith(CheckAliveLongResponse.PATH)) {
69 lastExecutedServerProtocol = new CheckAliveLongResponse(requestMessage);
70 } else {
71 throw new ProtocolCreationException("Invalid test path: " + path);
72 }
73 return lastExecutedServerProtocol;
74 }
75 };
76
77 public MockRouter router = new MockRouter(configuration, protocolFactory) {
78 @Override
79 public void received(UpnpStream stream) {
80 stream.run();
81 }
82 };
83
84 public StreamServer server;
85 public StreamClient client;
86 public TestProtocol lastExecutedServerProtocol;
87
88
89 @BeforeClass
90 public void start() throws Exception {
91 server = createStreamServer(TEST_PORT);
92 server.init(InetAddress.getByName(TEST_HOST), router);
93 configuration.getStreamServerExecutorService().execute(server);
94
95 client = createStreamClient(configuration);
96 Thread.sleep(1000);
97 }
98
99 @AfterClass
100 public void stop() throws Exception {
101 server.stop();
102 client.stop();
103 Thread.sleep(1000);
104 }
105
106 @BeforeMethod
107 public void clearLastProtocol() {
108 lastExecutedServerProtocol = null;
109 }
110
111 @Test
112 public void basic() throws Exception {
113 StreamResponseMessage responseMessage;
114
115 responseMessage = client.sendRequest(createRequestMessage(OKEmptyResponse.PATH));
116 assertEquals(responseMessage.getOperation().getStatusCode(), 200);
117 assertFalse(responseMessage.hasBody());
118 assertTrue(lastExecutedServerProtocol.isComplete);
119
120 lastExecutedServerProtocol = null;
121 responseMessage = client.sendRequest(createRequestMessage(OKBodyResponse.PATH));
122 assertEquals(responseMessage.getOperation().getStatusCode(), 200);
123 assertTrue(responseMessage.hasBody());
124 assertEquals(responseMessage.getBodyString(), "foo");
125 assertTrue(lastExecutedServerProtocol.isComplete);
126
127 lastExecutedServerProtocol = null;
128 responseMessage = client.sendRequest(createRequestMessage(NoResponse.PATH));
129 assertEquals(responseMessage.getOperation().getStatusCode(), 404);
130 assertFalse(responseMessage.hasBody());
131 assertFalse(lastExecutedServerProtocol.isComplete);
132 }
133
134 @Test
135 public void cancelled() throws Exception {
136 final boolean[] tests = new boolean[1];
137
138 final Thread requestThread = new Thread(new Runnable() {
139 @Override
140 public void run() {
141 try {
142 client.sendRequest(createRequestMessage(DelayedResponse.PATH));
143 } catch (InterruptedException ex) {
144
145 tests[0] = true;
146 }
147 }
148 });
149
150 requestThread.start();
151
152
153 new Thread(new Runnable() {
154 @Override
155 public void run() {
156 try {
157 Thread.sleep(250);
158 } catch (InterruptedException ex) {
159
160 }
161 requestThread.interrupt();
162 }
163 }).start();
164
165 Thread.sleep(3000);
166 for (boolean test : tests) {
167 assertTrue(test);
168 }
169
170 assertTrue(lastExecutedServerProtocol.isComplete);
171 }
172
173 @Test
174 public void expired() throws Exception {
175 StreamResponseMessage responseMessage = client.sendRequest(createRequestMessage(TooLongResponse.PATH));
176 assertNull(responseMessage);
177 assertFalse(lastExecutedServerProtocol.isComplete);
178
179
180 Thread.sleep(3000);
181 assertTrue(lastExecutedServerProtocol.isComplete);
182 }
183
184 @Test
185 public void checkAlive() throws Exception {
186 StreamResponseMessage responseMessage = client.sendRequest(createRequestMessage(CheckAliveResponse.PATH));
187 assertEquals(responseMessage.getOperation().getStatusCode(), 200);
188 assertFalse(responseMessage.hasBody());
189 assertTrue(lastExecutedServerProtocol.isComplete);
190 }
191
192 @Test
193 public void checkAliveExpired() throws Exception {
194 StreamResponseMessage responseMessage = client.sendRequest(createRequestMessage(CheckAliveLongResponse.PATH));
195 assertNull(responseMessage);
196
197
198 Thread.sleep(3000);
199 assertFalse(lastExecutedServerProtocol.isComplete);
200 }
201
202 @Test
203 public void checkAliveCancelled() throws Exception {
204 final boolean[] tests = new boolean[1];
205
206 final Thread requestThread = new Thread(new Runnable() {
207 @Override
208 public void run() {
209 try {
210 client.sendRequest(createRequestMessage(CheckAliveResponse.PATH));
211 } catch (InterruptedException ex) {
212
213 tests[0] = true;
214 }
215 }
216 });
217
218 requestThread.start();
219
220
221 new Thread(new Runnable() {
222 @Override
223 public void run() {
224 try {
225 Thread.sleep(1000);
226 } catch (InterruptedException ex) {
227
228 }
229 requestThread.interrupt();
230 }
231 }).start();
232
233 Thread.sleep(3000);
234 for (boolean test : tests) {
235 assertTrue(test);
236 }
237 assertFalse(lastExecutedServerProtocol.isComplete);
238 }
239
240 protected StreamRequestMessage createRequestMessage(String path) {
241 return new StreamRequestMessage(
242 UpnpRequest.Method.GET,
243 URI.create("http://" + TEST_HOST + ":" + TEST_PORT + path)
244 );
245 }
246
247 abstract public StreamServer createStreamServer(int port);
248
249 abstract public StreamClient createStreamClient(UpnpServiceConfiguration configuration);
250
251 public abstract class TestProtocol extends ReceivingSync<StreamRequestMessage, StreamResponseMessage> {
252 volatile public boolean isComplete;
253
254 public TestProtocol(StreamRequestMessage inputMessage) {
255 super(null, inputMessage);
256 }
257 }
258
259 public class OKEmptyResponse extends TestProtocol {
260
261 public static final String PATH = "/ok";
262
263 public OKEmptyResponse(StreamRequestMessage inputMessage) {
264 super(inputMessage);
265 }
266
267 @Override
268 protected StreamResponseMessage executeSync() {
269 isComplete = true;
270 return new StreamResponseMessage(UpnpResponse.Status.OK);
271 }
272 }
273
274 public class OKBodyResponse extends TestProtocol{
275
276 public static final String PATH = "/okbody";
277
278 public OKBodyResponse(StreamRequestMessage inputMessage) {
279 super(inputMessage);
280 }
281
282 @Override
283 protected StreamResponseMessage executeSync() {
284 isComplete = true;
285 return new StreamResponseMessage("foo");
286 }
287 }
288
289 public class NoResponse extends TestProtocol {
290
291 public static final String PATH = "/noresponse";
292
293 public NoResponse(StreamRequestMessage inputMessage) {
294 super(inputMessage);
295 }
296
297 @Override
298 protected StreamResponseMessage executeSync() {
299 return null;
300 }
301 }
302
303 public class DelayedResponse extends TestProtocol {
304
305 public static final String PATH = "/delayed";
306
307 public DelayedResponse(StreamRequestMessage inputMessage) {
308 super(inputMessage);
309 }
310
311 @Override
312 protected StreamResponseMessage executeSync() {
313 try {
314 log.info("Sleeping for 2 seconds before completion...");
315 Thread.sleep(2000);
316 } catch (InterruptedException ex) {
317 throw new RuntimeException(ex);
318 }
319 isComplete = true;
320 return new StreamResponseMessage(UpnpResponse.Status.OK);
321 }
322 }
323
324 public class TooLongResponse extends TestProtocol {
325
326 public static final String PATH = "/toolong";
327
328 public TooLongResponse(StreamRequestMessage inputMessage) {
329 super(inputMessage);
330 }
331
332 @Override
333 protected StreamResponseMessage executeSync() {
334 try {
335 log.info("Sleeping for 4 seconds before completion...");
336 Thread.sleep(4000);
337 } catch (InterruptedException ex) {
338 throw new RuntimeException(ex);
339 }
340 isComplete = true;
341 return new StreamResponseMessage(UpnpResponse.Status.OK);
342 }
343 }
344
345 public class CheckAliveResponse extends TestProtocol {
346
347 public static final String PATH = "/checkalive";
348
349 public CheckAliveResponse(StreamRequestMessage inputMessage) {
350 super(inputMessage);
351 }
352
353 @Override
354 protected StreamResponseMessage executeSync() {
355
356 int i = 0;
357 while (i < 4) {
358 try {
359 log.info("Sleeping for 500ms before checking connection...");
360 Thread.sleep(500);
361 } catch (InterruptedException ex) {
362 return null;
363 }
364 if (getRemoteClientInfo().isRequestCancelled()) {
365 return null;
366 }
367 i++;
368 }
369 isComplete = true;
370 return new StreamResponseMessage(UpnpResponse.Status.OK);
371 }
372 }
373
374 public class CheckAliveLongResponse extends TestProtocol {
375
376 public static final String PATH = "/checkalivelong";
377
378 public CheckAliveLongResponse(StreamRequestMessage inputMessage) {
379 super(inputMessage);
380 }
381
382 @Override
383 protected StreamResponseMessage executeSync() {
384
385 int i = 0;
386 while (i < 10) {
387 try {
388 log.info("Sleeping for 500ms before checking connection...");
389 Thread.sleep(500);
390 } catch (InterruptedException ex) {
391 return null;
392 }
393 if (getRemoteClientInfo().isRequestCancelled()) {
394 return null;
395 }
396 i++;
397 }
398 isComplete = true;
399 return new StreamResponseMessage(UpnpResponse.Status.OK);
400 }
401 }
402
403 }