2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
3 * This program and the accompanying materials are made available under the
4 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
5 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.sal.connector.remoterpc;
11 import com.google.common.base.Optional;
12 import junit.framework.Assert;
14 import org.opendaylight.controller.sal.connector.api.RpcRouter;
15 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
16 import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
17 import org.opendaylight.controller.sal.core.api.Broker;
18 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
19 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
20 import org.zeromq.ZMQ;
22 import zmq.SocketBase;
24 import java.lang.reflect.Field;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.concurrent.ExecutorService;
29 import java.util.concurrent.ThreadPoolExecutor;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
34 public class ServerImplTest {
36 private static ZMQ.Context context;
37 private ServerImpl server;
38 private Broker.ProviderSession brokerSession;
39 private RoutingTableProvider routingTableProvider;
40 private RpcRegistrationListener listener;
44 //Server configuration
45 private final int HANDLER_COUNT = 2;
46 private final int HWM = 200;
47 private final int port = 5554;
49 private final String SERVER_ADDRESS = "tcp://localhost:5554";
52 public static void init() {
53 context = ZMQ.context(1);
57 public static void destroy() {
58 MessagingUtil.closeZmqContext(context);
62 public void setup() throws InterruptedException {
63 context = ZMQ.context(1);
64 brokerSession = mock(Broker.ProviderSession.class);
65 routingTableProvider = mock(RoutingTableProvider.class);
66 listener = mock(RpcRegistrationListener.class);
68 server = new ServerImpl(port);
69 server.setBrokerSession(brokerSession);
71 RoutingTable<RpcRouter.RouteIdentifier, String> mockRoutingTable = new MockRoutingTable<String, String>();
72 Optional<RoutingTable<RpcRouter.RouteIdentifier, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
73 when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
75 when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
76 when(brokerSession.getSupportedRpcs()).thenReturn(Collections.EMPTY_SET);
77 when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null);
79 Thread.sleep(5000);//wait for server to start
83 public void tearDown() throws InterruptedException {
91 MessagingUtil.closeZmqContext(context);
93 Thread.sleep(5000);//wait for server to stop
94 Assert.assertEquals(ServerImpl.State.STOPPED, server.getStatus());
98 public void getBrokerSession_Call_ShouldReturnBrokerSession() throws Exception {
99 Optional<Broker.ProviderSession> mayBeBroker = server.getBrokerSession();
101 if (mayBeBroker.isPresent())
102 Assert.assertEquals(brokerSession, mayBeBroker.get());
104 Assert.fail("Broker does not exist in Remote RPC Server");
109 public void start_Call_ShouldSetServerStatusToStarted() throws Exception {
110 Assert.assertEquals(ServerImpl.State.STARTED, server.getStatus());
115 public void start_Call_ShouldCreateNZmqSockets() throws Exception {
116 final int EXPECTED_COUNT = 2 + HANDLER_COUNT; //1 ROUTER + 1 DEALER + HANDLER_COUNT
118 Optional<ZMQ.Context> mayBeContext = server.getZmqContext();
119 if (mayBeContext.isPresent())
120 Assert.assertEquals(EXPECTED_COUNT, findSocketCount(mayBeContext.get()));
122 Assert.fail("ZMQ Context does not exist in Remote RPC Server");
126 public void start_Call_ShouldCreate1ServerThread() {
127 final String SERVER_THREAD_NAME = "remote-rpc-server";
128 final int EXPECTED_COUNT = 1;
129 List<Thread> serverThreads = findThreadsWithName(SERVER_THREAD_NAME);
130 Assert.assertEquals(EXPECTED_COUNT, serverThreads.size());
134 public void start_Call_ShouldCreateNHandlerThreads() {
135 //final String WORKER_THREAD_NAME = "remote-rpc-worker";
136 final int EXPECTED_COUNT = HANDLER_COUNT;
138 Optional<ServerRequestHandler> serverRequestHandlerOptional = server.getHandler();
139 if (serverRequestHandlerOptional.isPresent()){
140 ServerRequestHandler handler = serverRequestHandlerOptional.get();
141 ThreadPoolExecutor workerPool = handler.getWorkerPool();
142 Assert.assertEquals(EXPECTED_COUNT, workerPool.getPoolSize());
144 Assert.fail("Server is in illegal state. ServerHandler does not exist");
150 public void testStop() throws Exception {
155 public void testOnRouteUpdated() throws Exception {
160 public void testOnRouteDeleted() throws Exception {
164 private int findSocketCount(ZMQ.Context context)
165 throws NoSuchFieldException, IllegalAccessException {
166 Field ctxField = context.getClass().getDeclaredField("ctx");
167 ctxField.setAccessible(true);
168 Ctx ctx = Ctx.class.cast(ctxField.get(context));
170 Field socketListField = ctx.getClass().getDeclaredField("sockets");
171 socketListField.setAccessible(true);
172 List<SocketBase> sockets = List.class.cast(socketListField.get(ctx));
174 return sockets.size();
177 private List<Thread> findThreadsWithName(String name) {
178 Thread[] threads = new Thread[Thread.activeCount()];
179 Thread.enumerate(threads);
181 List<Thread> foundThreads = new ArrayList();
182 for (Thread t : threads) {
183 if (t.getName().startsWith(name))