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 static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.when;
14 import java.lang.reflect.Field;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.concurrent.ExecutorService;
19 import java.util.concurrent.ThreadPoolExecutor;
21 import junit.framework.Assert;
23 import org.junit.After;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.opendaylight.controller.sal.connector.api.RpcRouter;
27 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
28 import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
29 import org.opendaylight.controller.sal.core.api.Broker;
30 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
33 import org.zeromq.ZMQ;
36 import zmq.SocketBase;
38 import com.google.common.base.Optional;
40 public class ServerImplTest {
42 private static ZMQ.Context context;
43 private ServerImpl server;
44 private Broker.ProviderSession brokerSession;
45 private RoutingTableProvider routingTableProvider;
46 private RpcRegistrationListener listener;
50 //Server configuration
51 private final int HANDLER_COUNT = 2;
52 private final int HWM = 200;
53 private final int port = 5554;
55 private final String SERVER_ADDRESS = "tcp://localhost:5554";
58 public static void init() {
59 context = ZMQ.context(1);
63 public static void destroy() {
64 MessagingUtil.closeZmqContext(context);
68 public void setup() throws InterruptedException {
69 context = ZMQ.context(1);
70 brokerSession = mock(Broker.ProviderSession.class);
71 routingTableProvider = mock(RoutingTableProvider.class);
72 listener = mock(RpcRegistrationListener.class);
74 server = new ServerImpl(port);
75 server.setBrokerSession(brokerSession);
77 RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> mockRoutingTable = new MockRoutingTable<String, String>();
78 Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
79 when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
81 when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
82 when(brokerSession.getSupportedRpcs()).thenReturn(Collections.<QName>emptySet());
83 when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null);
85 Thread.sleep(5000);//wait for server to start
89 public void tearDown() throws InterruptedException {
97 MessagingUtil.closeZmqContext(context);
99 Thread.sleep(5000);//wait for server to stop
100 Assert.assertEquals(ServerImpl.State.STOPPED, server.getStatus());
104 public void getBrokerSession_Call_ShouldReturnBrokerSession() throws Exception {
105 Optional<Broker.ProviderSession> mayBeBroker = server.getBrokerSession();
107 if (mayBeBroker.isPresent())
108 Assert.assertEquals(brokerSession, mayBeBroker.get());
110 Assert.fail("Broker does not exist in Remote RPC Server");
115 public void start_Call_ShouldSetServerStatusToStarted() throws Exception {
116 Assert.assertEquals(ServerImpl.State.STARTED, server.getStatus());
121 public void start_Call_ShouldCreateNZmqSockets() throws Exception {
122 final int EXPECTED_COUNT = 2 + HANDLER_COUNT; //1 ROUTER + 1 DEALER + HANDLER_COUNT
124 Optional<ZMQ.Context> mayBeContext = server.getZmqContext();
125 if (mayBeContext.isPresent())
126 Assert.assertEquals(EXPECTED_COUNT, findSocketCount(mayBeContext.get()));
128 Assert.fail("ZMQ Context does not exist in Remote RPC Server");
132 public void start_Call_ShouldCreate1ServerThread() {
133 final String SERVER_THREAD_NAME = "remote-rpc-server";
134 final int EXPECTED_COUNT = 1;
135 List<Thread> serverThreads = findThreadsWithName(SERVER_THREAD_NAME);
136 Assert.assertEquals(EXPECTED_COUNT, serverThreads.size());
140 public void start_Call_ShouldCreateNHandlerThreads() {
141 //final String WORKER_THREAD_NAME = "remote-rpc-worker";
142 final int EXPECTED_COUNT = HANDLER_COUNT;
144 Optional<ServerRequestHandler> serverRequestHandlerOptional = server.getHandler();
145 if (serverRequestHandlerOptional.isPresent()){
146 ServerRequestHandler handler = serverRequestHandlerOptional.get();
147 ThreadPoolExecutor workerPool = handler.getWorkerPool();
148 Assert.assertEquals(EXPECTED_COUNT, workerPool.getPoolSize());
150 Assert.fail("Server is in illegal state. ServerHandler does not exist");
156 public void testStop() throws Exception {
161 public void testOnRouteUpdated() throws Exception {
166 public void testOnRouteDeleted() throws Exception {
170 private int findSocketCount(ZMQ.Context context)
171 throws NoSuchFieldException, IllegalAccessException {
172 Field ctxField = context.getClass().getDeclaredField("ctx");
173 ctxField.setAccessible(true);
174 Ctx ctx = Ctx.class.cast(ctxField.get(context));
176 Field socketListField = ctx.getClass().getDeclaredField("sockets");
177 socketListField.setAccessible(true);
178 List<SocketBase> sockets = List.class.cast(socketListField.get(ctx));
180 return sockets.size();
183 private List<Thread> findThreadsWithName(String name) {
184 Thread[] threads = new Thread[Thread.activeCount()];
185 Thread.enumerate(threads);
187 List<Thread> foundThreads = new ArrayList<Thread>();
188 for (Thread t : threads) {
189 if (t.getName().startsWith(name))