OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
12 | 12 |
13 import org.appspot.apprtc.util.RobolectricLooperExecutor; | 13 |
14 import org.junit.After; | 14 import org.junit.After; |
15 import org.junit.Before; | 15 import org.junit.Before; |
16 import org.junit.Test; | 16 import org.junit.Test; |
17 import org.junit.runner.RunWith; | 17 import org.junit.runner.RunWith; |
18 import org.mockito.Mock; | 18 import org.mockito.Mock; |
19 import org.mockito.MockitoAnnotations; | 19 import org.mockito.MockitoAnnotations; |
20 import org.robolectric.RobolectricTestRunner; | 20 import org.robolectric.RobolectricTestRunner; |
21 import org.robolectric.annotation.Config; | 21 import org.robolectric.annotation.Config; |
22 import org.robolectric.shadows.ShadowLog; | 22 import org.robolectric.shadows.ShadowLog; |
23 | 23 |
24 import java.util.concurrent.ExecutorService; | |
25 import java.util.concurrent.Executors; | |
26 import java.util.concurrent.TimeUnit; | |
27 | |
24 import static org.junit.Assert.fail; | 28 import static org.junit.Assert.fail; |
25 import static org.mockito.Mockito.timeout; | 29 import static org.mockito.Mockito.timeout; |
26 import static org.mockito.Mockito.verify; | 30 import static org.mockito.Mockito.verify; |
27 import static org.mockito.Mockito.verifyNoMoreInteractions; | 31 import static org.mockito.Mockito.verifyNoMoreInteractions; |
28 | 32 |
29 @RunWith(RobolectricTestRunner.class) | 33 @RunWith(RobolectricTestRunner.class) |
30 @Config(manifest = Config.NONE) | 34 @Config(manifest = Config.NONE) |
31 public class TCPChannelClientTest { | 35 public class TCPChannelClientTest { |
32 private static final int PORT = 8888; | 36 private static final int PORT = 8888; |
33 /** | 37 /** |
34 * How long we wait before trying to connect to the server. Chosen quite arbit rarily and | 38 * How long we wait before trying to connect to the server. Chosen quite arbit rarily and |
35 * could be made smaller if need be. | 39 * could be made smaller if need be. |
36 */ | 40 */ |
37 private static final int SERVER_WAIT = 10; | 41 private static final int SERVER_WAIT = 10; |
38 private static final int CONNECT_TIMEOUT = 100; | 42 private static final int CONNECT_TIMEOUT = 100; |
39 private static final int SEND_TIMEOUT = 100; | 43 private static final int SEND_TIMEOUT = 100; |
40 private static final int DISCONNECT_TIMEOUT = 100; | 44 private static final int DISCONNECT_TIMEOUT = 100; |
45 private static final int TERMINATION_TIMEOUT = 1000; | |
41 private static final String TEST_MESSAGE_SERVER = "Hello, Server!"; | 46 private static final String TEST_MESSAGE_SERVER = "Hello, Server!"; |
42 private static final String TEST_MESSAGE_CLIENT = "Hello, Client!"; | 47 private static final String TEST_MESSAGE_CLIENT = "Hello, Client!"; |
43 | 48 |
44 @Mock TCPChannelClient.TCPChannelEvents serverEvents; | 49 @Mock TCPChannelClient.TCPChannelEvents serverEvents; |
45 @Mock TCPChannelClient.TCPChannelEvents clientEvents; | 50 @Mock TCPChannelClient.TCPChannelEvents clientEvents; |
46 | 51 |
47 private RobolectricLooperExecutor executor; | 52 private ExecutorService executor; |
48 private TCPChannelClient server; | 53 private TCPChannelClient server; |
49 private TCPChannelClient client; | 54 private TCPChannelClient client; |
50 | 55 |
51 | 56 |
52 @Before | 57 @Before |
53 public void setUp() { | 58 public void setUp() { |
54 ShadowLog.stream = System.out; | 59 ShadowLog.stream = System.out; |
55 | 60 |
56 MockitoAnnotations.initMocks(this); | 61 MockitoAnnotations.initMocks(this); |
57 | 62 |
58 executor = new RobolectricLooperExecutor(); | 63 executor = Executors.newSingleThreadExecutor(); |
59 executor.requestStart(); | |
60 } | 64 } |
61 | 65 |
62 @After | 66 @After |
63 public void tearDown() { | 67 public void tearDown() { |
64 verifyNoMoreEvents(); | 68 verifyNoMoreEvents(); |
65 | 69 |
66 executor.executeAndWait(new Runnable() { | 70 executeAndWait(new Runnable() { |
67 @Override | 71 @Override |
68 public void run() { | 72 public void run() { |
69 client.disconnect(); | 73 client.disconnect(); |
70 server.disconnect(); | 74 server.disconnect(); |
71 } | 75 } |
72 }); | 76 }); |
73 | 77 |
74 // Stop the executor thread | 78 // Stop the executor thread |
75 executor.requestStop(); | 79 executor.shutdown(); |
76 try { | 80 try { |
77 executor.join(); | 81 executor.awaitTermination(TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS); |
78 } catch (InterruptedException e) { | 82 } catch (InterruptedException e) { |
79 fail(e.getMessage()); | 83 fail(e.getMessage()); |
80 } | 84 } |
81 } | 85 } |
82 | 86 |
83 @Test | 87 @Test |
84 public void testConnectIPv4() { | 88 public void testConnectIPv4() { |
85 setUpIPv4Server(); | 89 setUpIPv4Server(); |
86 try { | 90 try { |
87 Thread.sleep(SERVER_WAIT); | 91 Thread.sleep(SERVER_WAIT); |
(...skipping 17 matching lines...) Expand all Loading... | |
105 setUpIPv6Client(); | 109 setUpIPv6Client(); |
106 | 110 |
107 verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true); | 111 verify(serverEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(true); |
108 verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false); | 112 verify(clientEvents, timeout(CONNECT_TIMEOUT)).onTCPConnected(false); |
109 } | 113 } |
110 | 114 |
111 @Test | 115 @Test |
112 public void testSendData() { | 116 public void testSendData() { |
113 testConnectIPv4(); | 117 testConnectIPv4(); |
114 | 118 |
115 executor.executeAndWait(new Runnable() { | 119 executeAndWait(new Runnable() { |
116 @Override | 120 @Override |
117 public void run() { | 121 public void run() { |
118 client.send(TEST_MESSAGE_SERVER); | 122 client.send(TEST_MESSAGE_SERVER); |
119 server.send(TEST_MESSAGE_CLIENT); | 123 server.send(TEST_MESSAGE_CLIENT); |
120 } | 124 } |
121 }); | 125 }); |
122 | 126 |
123 verify(serverEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_SERVER ); | 127 verify(serverEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_SERVER ); |
124 verify(clientEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_CLIENT ); | 128 verify(clientEvents, timeout(SEND_TIMEOUT)).onTCPMessage(TEST_MESSAGE_CLIENT ); |
125 } | 129 } |
126 | 130 |
127 @Test | 131 @Test |
128 public void testDisconnectServer() { | 132 public void testDisconnectServer() { |
129 testConnectIPv4(); | 133 testConnectIPv4(); |
130 executor.executeAndWait(new Runnable() { | 134 executeAndWait(new Runnable() { |
131 @Override | 135 @Override |
132 public void run() { | 136 public void run() { |
133 server.disconnect(); | 137 server.disconnect(); |
134 } | 138 } |
135 }); | 139 }); |
136 | 140 |
137 verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); | 141 verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); |
138 verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); | 142 verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); |
139 } | 143 } |
140 | 144 |
141 @Test | 145 @Test |
142 public void testDisconnectClient() { | 146 public void testDisconnectClient() { |
143 testConnectIPv4(); | 147 testConnectIPv4(); |
144 executor.executeAndWait(new Runnable() { | 148 executeAndWait(new Runnable() { |
145 @Override | 149 @Override |
146 public void run() { | 150 public void run() { |
147 client.disconnect(); | 151 client.disconnect(); |
148 } | 152 } |
149 }); | 153 }); |
150 | 154 |
151 verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); | 155 verify(serverEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); |
152 verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); | 156 verify(clientEvents, timeout(DISCONNECT_TIMEOUT)).onTCPClose(); |
153 } | 157 } |
154 | 158 |
(...skipping 21 matching lines...) Expand all Loading... | |
176 client = new TCPChannelClient(executor, clientEvents, ip, port); | 180 client = new TCPChannelClient(executor, clientEvents, ip, port); |
177 } | 181 } |
178 | 182 |
179 /** | 183 /** |
180 * Verifies no more server or client events have been issued | 184 * Verifies no more server or client events have been issued |
181 */ | 185 */ |
182 private void verifyNoMoreEvents() { | 186 private void verifyNoMoreEvents() { |
183 verifyNoMoreInteractions(serverEvents); | 187 verifyNoMoreInteractions(serverEvents); |
184 verifyNoMoreInteractions(clientEvents); | 188 verifyNoMoreInteractions(clientEvents); |
185 } | 189 } |
190 | |
191 /** | |
192 * Executes the runnable passed to the constructor and sets isDone flag afterw ards. | |
193 */ | |
194 private static class ExecuteAndWaitRunnable implements Runnable { | |
195 public boolean isDone = false; | |
196 private final Runnable runnable; | |
197 ExecuteAndWaitRunnable(Runnable runnable) { | |
198 this.runnable = runnable; | |
199 } | |
200 @Override | |
201 public void run() { | |
202 runnable.run(); | |
203 synchronized (this) { | |
204 isDone = true; | |
205 notifyAll(); | |
206 } | |
207 } | |
208 } | |
209 | |
210 /** | |
211 * Queues runnable to be run and waits for it to be executed by the executor t hread | |
212 */ | |
213 public void executeAndWait(Runnable runnable) { | |
magjed_webrtc
2016/05/19 12:07:54
Can you implement it like this?
public void execut
sakal
2016/05/19 12:39:03
Done.
| |
214 ExecuteAndWaitRunnable executeAndWaitRunnable = new ExecuteAndWaitRunnable(r unnable); | |
215 executor.execute(executeAndWaitRunnable); | |
216 synchronized (executeAndWaitRunnable) { | |
217 while (!executeAndWaitRunnable.isDone) { | |
218 try { | |
219 executeAndWaitRunnable.wait(); | |
220 } catch (InterruptedException e) { | |
221 fail(e.getMessage()); | |
222 } | |
223 } | |
224 } | |
225 } | |
186 } | 226 } |
OLD | NEW |