Merge "BUG-731: fix unused imports"
[controller.git] / opendaylight / md-sal / sal-remoterpc-connector / implementation / src / test / java / org / opendaylight / controller / sal / connector / remoterpc / ServerImplTest.java
1 /*
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
6  */
7
8 package org.opendaylight.controller.sal.connector.remoterpc;
9
10
11 import com.google.common.base.Optional;
12 import junit.framework.Assert;
13 import org.junit.*;
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;
21 import zmq.Ctx;
22 import zmq.SocketBase;
23
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;
30
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33
34 public class ServerImplTest {
35
36   private static ZMQ.Context context;
37   private ServerImpl server;
38   private Broker.ProviderSession brokerSession;
39   private RoutingTableProvider routingTableProvider;
40   private RpcRegistrationListener listener;
41
42   ExecutorService pool;
43
44   //Server configuration
45   private final int HANDLER_COUNT = 2;
46   private final int HWM = 200;
47   private final int port = 5554;
48   //server address
49   private final String SERVER_ADDRESS = "tcp://localhost:5554";
50
51   //@BeforeClass
52   public static void init() {
53     context = ZMQ.context(1);
54   }
55
56   //@AfterClass
57   public static void destroy() {
58     MessagingUtil.closeZmqContext(context);
59   }
60
61   @Before
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);
67
68     server = new ServerImpl(port);
69     server.setBrokerSession(brokerSession);
70
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);
74
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);
78     server.start();
79     Thread.sleep(5000);//wait for server to start
80   }
81
82   @After
83   public void tearDown() throws InterruptedException {
84
85     if (pool != null)
86       pool.shutdown();
87
88     if (server != null)
89       server.stop();
90
91     MessagingUtil.closeZmqContext(context);
92
93     Thread.sleep(5000);//wait for server to stop
94     Assert.assertEquals(ServerImpl.State.STOPPED, server.getStatus());
95   }
96
97   @Test
98   public void getBrokerSession_Call_ShouldReturnBrokerSession() throws Exception {
99     Optional<Broker.ProviderSession> mayBeBroker = server.getBrokerSession();
100
101     if (mayBeBroker.isPresent())
102       Assert.assertEquals(brokerSession, mayBeBroker.get());
103     else
104       Assert.fail("Broker does not exist in Remote RPC Server");
105
106   }
107
108   @Test
109   public void start_Call_ShouldSetServerStatusToStarted() throws Exception {
110     Assert.assertEquals(ServerImpl.State.STARTED, server.getStatus());
111
112   }
113
114   @Test
115   public void start_Call_ShouldCreateNZmqSockets() throws Exception {
116     final int EXPECTED_COUNT = 2 + HANDLER_COUNT; //1 ROUTER + 1 DEALER + HANDLER_COUNT
117
118     Optional<ZMQ.Context> mayBeContext = server.getZmqContext();
119     if (mayBeContext.isPresent())
120       Assert.assertEquals(EXPECTED_COUNT, findSocketCount(mayBeContext.get()));
121     else
122       Assert.fail("ZMQ Context does not exist in Remote RPC Server");
123   }
124
125   @Test
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());
131   }
132
133   @Test
134   public void start_Call_ShouldCreateNHandlerThreads() {
135     //final String WORKER_THREAD_NAME = "remote-rpc-worker";
136     final int EXPECTED_COUNT = HANDLER_COUNT;
137
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());
143     } else {
144       Assert.fail("Server is in illegal state. ServerHandler does not exist");
145     }
146
147   }
148
149   @Test
150   public void testStop() throws Exception {
151
152   }
153
154   @Test
155   public void testOnRouteUpdated() throws Exception {
156
157   }
158
159   @Test
160   public void testOnRouteDeleted() throws Exception {
161
162   }
163
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));
169
170     Field socketListField = ctx.getClass().getDeclaredField("sockets");
171     socketListField.setAccessible(true);
172     List<SocketBase> sockets = List.class.cast(socketListField.get(ctx));
173
174     return sockets.size();
175   }
176
177   private List<Thread> findThreadsWithName(String name) {
178     Thread[] threads = new Thread[Thread.activeCount()];
179     Thread.enumerate(threads);
180
181     List<Thread> foundThreads = new ArrayList();
182     for (Thread t : threads) {
183       if (t.getName().startsWith(name))
184         foundThreads.add(t);
185     }
186
187     return foundThreads;
188   }
189 }