blob: 69db5714036a32115049091e9e73c3dfe8b76037 [file] [log] [blame]
HIGUCHI Yuta15653fd2015-11-09 11:05:09 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.incubator.rpc.grpc;
17
18import static org.junit.Assert.*;
19import static org.onosproject.net.DeviceId.deviceId;
20
21import java.io.IOException;
22import java.net.ServerSocket;
23import java.net.URI;
24import java.util.Collection;
25import java.util.Collections;
26import java.util.List;
27import java.util.Set;
28import java.util.concurrent.CountDownLatch;
29import java.util.concurrent.TimeUnit;
30
31import org.apache.commons.lang3.RandomUtils;
32import org.junit.After;
33import org.junit.Before;
34import org.junit.Test;
35import org.onlab.packet.ChassisId;
36import org.onosproject.incubator.rpc.RemoteServiceContext;
37import org.onosproject.incubator.rpc.RemoteServiceContextProvider;
38import org.onosproject.incubator.rpc.RemoteServiceContextProviderService;
39import org.onosproject.incubator.rpc.RemoteServiceProviderRegistry;
40import org.onosproject.net.DefaultAnnotations;
41import org.onosproject.net.Device.Type;
42import org.onosproject.net.DeviceId;
43import org.onosproject.net.MastershipRole;
44import org.onosproject.net.PortNumber;
45import org.onosproject.net.SparseAnnotations;
46import org.onosproject.net.device.DefaultDeviceDescription;
47import org.onosproject.net.device.DefaultPortDescription;
48import org.onosproject.net.device.DeviceDescription;
49import org.onosproject.net.device.DeviceProvider;
50import org.onosproject.net.device.DeviceProviderRegistry;
51import org.onosproject.net.device.DeviceProviderService;
52import org.onosproject.net.device.PortDescription;
53import org.onosproject.net.device.PortStatistics;
54import org.onosproject.net.provider.AbstractProviderRegistry;
55import org.onosproject.net.provider.AbstractProviderService;
56import org.onosproject.net.provider.ProviderId;
57import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
60import com.google.common.collect.ImmutableList;
61
62/**
63 * Set of tests of the gRPC RemoteService components.
64 */
65public class GrpcRemoteServiceTest {
66
67 private static final DeviceId DEVICE_ID = deviceId("dev:000001");
68
69 private final Logger log = LoggerFactory.getLogger(getClass());
70
71 private static final ProviderId PID = new ProviderId("test", "com.exmaple.test");
72
73 private static final URI DURI = URI.create("dev:000001");
74
75 private static final String MFR = "mfr";
76
77 private static final String HW = "hw";
78
79 private static final String SW = "sw";
80
81 private static final String SN = "serial";
82
83 private static final ChassisId CHASSIS = new ChassisId(42);
84
85 private static final SparseAnnotations ANON = DefaultAnnotations.builder()
86 .set("foo", "var")
87 .build();
88
89 private static final PortNumber PORT = PortNumber.portNumber(99);
90
91 private static final DeviceDescription DDESC
92 = new DefaultDeviceDescription(DURI, Type.SWITCH, MFR, HW, SW, SN,
93 CHASSIS, ANON);
94
95 private GrpcRemoteServiceServer server;
96 private GrpcRemoteServiceProvider client;
97
98 private DeviceProvider svSideDeviceProvider;
99
100 private MTestDeviceProviderService svDeviceProviderService;
101
102 private CountDownLatch serverReady;
103
104 private URI uri;
105
106 public static int pickListenPort() {
107 try {
108 // pick unused port
109 ServerSocket socket = new ServerSocket(0);
110 int port = socket.getLocalPort();
111 socket.close();
112 return port;
113 } catch (IOException e) {
114 // something went wrong, try picking randomly
115 return RandomUtils.nextInt(49152, 0xFFFF + 1);
116 }
117 }
118
119 @Before
120 public void setUp() throws Exception {
121 serverReady = new CountDownLatch(1);
122 server = new GrpcRemoteServiceServer();
123 server.deviceProviderRegistry = new MTestDeviceProviderRegistry();
124 // todo: pass proper ComponentContext
125 server.listenPort = pickListenPort();
126 uri = URI.create("grpc://localhost:" + server.listenPort);
127 server.activate(null);
128
129 client = new GrpcRemoteServiceProvider();
130 client.rpcRegistry = new NoOpRemoteServiceProviderRegistry();
131 client.activate();
132 }
133
134 @After
135 public void tearDown() {
136 client.deactivate();
137 server.deactivate();
138 }
139
140 private static void assertEqualsButNotSame(Object expected, Object actual) {
141 assertEquals(expected, actual);
142 assertNotSame("Cannot be same instance if it properly went through gRPC",
143 expected, actual);
144 }
145
146 @Test
147 public void basics() throws InterruptedException {
148 RemoteServiceContext remoteServiceContext = client.get(uri);
149 assertNotNull(remoteServiceContext);
150
151 DeviceProviderRegistry deviceProviderRegistry = remoteServiceContext.get(DeviceProviderRegistry.class);
152 assertNotNull(deviceProviderRegistry);
153
154 CTestDeviceProvider clDeviceProvider = new CTestDeviceProvider();
155 DeviceProviderService clDeviceProviderService = deviceProviderRegistry.register(clDeviceProvider);
156
157 assertTrue(serverReady.await(10, TimeUnit.SECONDS));
158
159 // client to server communication
160 clDeviceProviderService.deviceConnected(DEVICE_ID, DDESC);
161 assertTrue(svDeviceProviderService.deviceConnected.await(10, TimeUnit.SECONDS));
162 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceConnectedDid);
163 assertEqualsButNotSame(DDESC, svDeviceProviderService.deviceConnectedDesc);
164
165 PortDescription portDescription = new DefaultPortDescription(PORT, true, ANON);
166 List<PortDescription> portDescriptions = ImmutableList.of(portDescription);
167 clDeviceProviderService.updatePorts(DEVICE_ID, portDescriptions);
168 assertTrue(svDeviceProviderService.updatePorts.await(10, TimeUnit.SECONDS));
169 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortsDid);
170 assertEqualsButNotSame(portDescriptions, svDeviceProviderService.updatePortsDescs);
171
172 MastershipRole cRole = MastershipRole.MASTER;
173 MastershipRole dRole = MastershipRole.STANDBY;
174 clDeviceProviderService.receivedRoleReply(DEVICE_ID, cRole, dRole);
175 assertTrue(svDeviceProviderService.receivedRoleReply.await(10, TimeUnit.SECONDS));
176 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.receivedRoleReplyDid);
177 assertEquals(cRole, svDeviceProviderService.receivedRoleReplyRequested);
178 assertEquals(dRole, svDeviceProviderService.receivedRoleReplyResponse);
179
180 clDeviceProviderService.portStatusChanged(DEVICE_ID, portDescription);
181 assertTrue(svDeviceProviderService.portStatusChanged.await(10, TimeUnit.SECONDS));
182 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.portStatusChangedDid);
183 assertEqualsButNotSame(portDescription, svDeviceProviderService.portStatusChangedDesc);
184
185 Collection<PortStatistics> portStatistics = Collections.emptyList();
186 clDeviceProviderService.updatePortStatistics(DEVICE_ID, portStatistics);
187 assertTrue(svDeviceProviderService.updatePortStatistics.await(10, TimeUnit.SECONDS));
188 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.updatePortStatisticsDid);
189 assertEqualsButNotSame(portStatistics, svDeviceProviderService.updatePortStatisticsStats);
190
191 clDeviceProviderService.deviceDisconnected(DEVICE_ID);
192 assertTrue(svDeviceProviderService.deviceDisconnected.await(10, TimeUnit.SECONDS));
193 assertEqualsButNotSame(DEVICE_ID, svDeviceProviderService.deviceDisconnectedDid);
194
195
196
197 // server to client communication
198 svSideDeviceProvider.triggerProbe(DEVICE_ID);
199 assertTrue(clDeviceProvider.triggerProbe.await(10, TimeUnit.SECONDS));
200 assertEquals(DEVICE_ID, clDeviceProvider.triggerProbeDid);
201 assertNotSame("Cannot be same instance if it properly went through gRPC",
202 DEVICE_ID, clDeviceProvider.triggerProbeDid);
203
204 svSideDeviceProvider.roleChanged(DEVICE_ID, MastershipRole.STANDBY);
205 assertTrue(clDeviceProvider.roleChanged.await(10, TimeUnit.SECONDS));
206 assertEquals(DEVICE_ID, clDeviceProvider.roleChangedDid);
207 assertNotSame("Cannot be same instance if it properly went through gRPC",
208 DEVICE_ID, clDeviceProvider.roleChangedDid);
209 assertEquals(MastershipRole.STANDBY, clDeviceProvider.roleChangedNewRole);
210
211 clDeviceProvider.isReachableReply = false;
212 assertEquals(clDeviceProvider.isReachableReply,
213 svSideDeviceProvider.isReachable(DEVICE_ID));
214 assertTrue(clDeviceProvider.isReachable.await(10, TimeUnit.SECONDS));
215 assertEquals(DEVICE_ID, clDeviceProvider.isReachableDid);
216 assertNotSame("Cannot be same instance if it properly went through gRPC",
217 DEVICE_ID, clDeviceProvider.isReachableDid);
218 }
219
220 /**
221 * Device Provider on CO side.
222 */
223 public class CTestDeviceProvider implements DeviceProvider {
224
225 final CountDownLatch triggerProbe = new CountDownLatch(1);
226 DeviceId triggerProbeDid;
227
228 final CountDownLatch roleChanged = new CountDownLatch(1);
229 DeviceId roleChangedDid;
230 MastershipRole roleChangedNewRole;
231
232 final CountDownLatch isReachable = new CountDownLatch(1);
233 DeviceId isReachableDid;
234 boolean isReachableReply = false;
235
236 @Override
237 public ProviderId id() {
238 return PID;
239 }
240
241 @Override
242 public void triggerProbe(DeviceId deviceId) {
243 log.info("triggerProbe({}) on Client called", deviceId);
244 triggerProbeDid = deviceId;
245 triggerProbe.countDown();
246 }
247
248 @Override
249 public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
250 log.info("roleChanged({},{}) on Client called", deviceId, newRole);
251 roleChangedDid = deviceId;
252 roleChangedNewRole = newRole;
253 roleChanged.countDown();
254 }
255
256 @Override
257 public boolean isReachable(DeviceId deviceId) {
258 log.info("isReachable({}) on Client called", deviceId);
259 isReachableDid = deviceId;
260 isReachable.countDown();
261 return isReachableReply;
262 }
263
264 }
265
266 class NoOpRemoteServiceProviderRegistry
267 implements RemoteServiceProviderRegistry {
268
269 @Override
270 public RemoteServiceContextProviderService register(RemoteServiceContextProvider provider) {
271 return new RemoteServiceContextProviderService() {
272
273 @Override
274 public RemoteServiceContextProvider provider() {
275 return provider;
276 }
277 };
278 }
279
280 @Override
281 public void unregister(RemoteServiceContextProvider provider) {
282 }
283
284 @Override
285 public Set<ProviderId> getProviders() {
286 return Collections.emptySet();
287 }
288 }
289
290 /**
291 * DeviceProvider on Metro side.
292 */
293 public class MTestDeviceProviderRegistry
294 extends AbstractProviderRegistry<DeviceProvider, DeviceProviderService>
295 implements DeviceProviderRegistry {
296
297 @Override
298 protected DeviceProviderService createProviderService(DeviceProvider provider) {
299 log.info("createProviderService({})", provider);
300 svSideDeviceProvider = provider;
301 svDeviceProviderService = new MTestDeviceProviderService(provider);
302 serverReady.countDown();
303 return svDeviceProviderService;
304 }
305
306 }
307
308 private final class MTestDeviceProviderService
309 extends AbstractProviderService<DeviceProvider>
310 implements DeviceProviderService {
311
312 public MTestDeviceProviderService(DeviceProvider provider) {
313 super(provider);
314 }
315
316
317 final CountDownLatch deviceConnected = new CountDownLatch(1);
318 DeviceId deviceConnectedDid;
319 DeviceDescription deviceConnectedDesc;
320
321 @Override
322 public void deviceConnected(DeviceId deviceId,
323 DeviceDescription deviceDescription) {
324 log.info("deviceConnected({}, {}) on Server called", deviceId, deviceDescription);
325 deviceConnectedDid = deviceId;
326 deviceConnectedDesc = deviceDescription;
327 deviceConnected.countDown();
328 }
329
330
331 final CountDownLatch updatePorts = new CountDownLatch(1);
332 DeviceId updatePortsDid;
333 List<PortDescription> updatePortsDescs;
334
335 @Override
336 public void updatePorts(DeviceId deviceId,
337 List<PortDescription> portDescriptions) {
338 log.info("updatePorts({}, {}) on Server called", deviceId, portDescriptions);
339 updatePortsDid = deviceId;
340 updatePortsDescs = portDescriptions;
341 updatePorts.countDown();
342 }
343
344 final CountDownLatch receivedRoleReply = new CountDownLatch(1);
345 DeviceId receivedRoleReplyDid;
346 MastershipRole receivedRoleReplyRequested;
347 MastershipRole receivedRoleReplyResponse;
348
349 @Override
350 public void receivedRoleReply(DeviceId deviceId, MastershipRole requested,
351 MastershipRole response) {
352 log.info("receivedRoleReply({}, {}, {}) on Server called", deviceId, requested, response);
353 receivedRoleReplyDid = deviceId;
354 receivedRoleReplyRequested = requested;
355 receivedRoleReplyResponse = response;
356 receivedRoleReply.countDown();
357 }
358
359 final CountDownLatch portStatusChanged = new CountDownLatch(1);
360 DeviceId portStatusChangedDid;
361 PortDescription portStatusChangedDesc;
362
363
364 @Override
365 public void portStatusChanged(DeviceId deviceId,
366 PortDescription portDescription) {
367 log.info("portStatusChanged({}, {}) on Server called", deviceId, portDescription);
368 portStatusChangedDid = deviceId;
369 portStatusChangedDesc = portDescription;
370 portStatusChanged.countDown();
371 }
372
373 final CountDownLatch updatePortStatistics = new CountDownLatch(1);
374 DeviceId updatePortStatisticsDid;
375 Collection<PortStatistics> updatePortStatisticsStats;
376
377
378 @Override
379 public void updatePortStatistics(DeviceId deviceId,
380 Collection<PortStatistics> portStatistics) {
381 log.info("updatePortStatistics({}, {}) on Server called", deviceId, portStatistics);
382 updatePortStatisticsDid = deviceId;
383 updatePortStatisticsStats = portStatistics;
384 updatePortStatistics.countDown();
385 }
386
387 final CountDownLatch deviceDisconnected = new CountDownLatch(1);
388 DeviceId deviceDisconnectedDid;
389
390 @Override
391 public void deviceDisconnected(DeviceId deviceId) {
392 log.info("deviceDisconnected({}) on Server called", deviceId);
393 deviceDisconnectedDid = deviceId;
394 deviceDisconnected.countDown();
395 }
396 }
397
398}