Fixed for bug : 1171 - issue while creating subnet
[controller.git] / opendaylight / md-sal / remoterpc-routingtable / implementation / src / test / java / org / opendaylight / controller / sal / connector / remoterpc / impl / RoutingTableImplTest.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.sal.connector.remoterpc.impl;
10
11 import static org.mockito.Mockito.doNothing;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.reset;
14 import static org.mockito.Mockito.when;
15
16 import java.net.URI;
17 import java.util.EnumSet;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap;
21 import java.util.concurrent.ExecutorService;
22 import java.util.concurrent.Executors;
23 import java.util.concurrent.TimeUnit;
24
25 import junit.framework.Assert;
26
27 import org.apache.felix.dm.Component;
28 import org.junit.After;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
32 import org.opendaylight.controller.clustering.services.IClusterServices;
33 import org.opendaylight.controller.sal.connector.api.RpcRouter;
34 import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
37
38 public class RoutingTableImplTest {
39
40     private final URI namespace = URI.create("http://cisco.com/example");
41     private final QName QNAME = new QName(namespace, "global");
42
43     private IClusterGlobalServices clusterService;
44     private RoutingTableImpl<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
45     ConcurrentMap mockGlobalRpcCache;
46     ConcurrentMap mockRpcCache;
47
48     @Before
49     public void setUp() throws Exception{
50         clusterService = mock(IClusterGlobalServices.class);
51         routingTable = new RoutingTableImpl<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
52         mockGlobalRpcCache = new ConcurrentHashMap<>();
53         mockRpcCache = new ConcurrentHashMap<>();
54         createRoutingTableCache();
55     }
56
57     @After
58     public void tearDown(){
59         reset(clusterService);
60         mockGlobalRpcCache = null;
61         mockRpcCache = null;
62     }
63
64     @Test
65     public void addGlobalRoute_ValidArguments_ShouldAdd() throws Exception {
66
67         Assert.assertNotNull(mockGlobalRpcCache);
68         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
69
70         final String expectedRoute = "172.27.12.1:5000";
71         routingTable.addGlobalRoute(routeIdentifier, expectedRoute);
72
73         ConcurrentMap latestCache = routingTable.getGlobalRpcCache();
74         Assert.assertEquals(mockGlobalRpcCache, latestCache);
75         Assert.assertEquals(expectedRoute, latestCache.get(routeIdentifier));
76     }
77
78     @Test (expected = RoutingTable.DuplicateRouteException.class)
79     public void addGlobalRoute_DuplicateRoute_ShouldThrow() throws Exception{
80
81         Assert.assertNotNull(mockGlobalRpcCache);
82
83         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
84         routingTable.addGlobalRoute(routeIdentifier, new String());
85         routingTable.addGlobalRoute(routeIdentifier, new String());
86     }
87
88     @Test
89     public void getGlobalRoute_ExistingRouteId_ShouldReturnRoute() throws Exception {
90
91         Assert.assertNotNull(mockGlobalRpcCache);
92         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
93         String expectedRoute = "172.27.12.1:5000";
94
95         routingTable.addGlobalRoute(routeIdentifier, expectedRoute);
96
97         String actualRoute = routingTable.getGlobalRoute(routeIdentifier);
98         Assert.assertEquals(expectedRoute, actualRoute);
99     }
100
101     @Test
102     public void getGlobalRoute_NonExistentRouteId_ShouldReturnNull() throws Exception {
103
104         Assert.assertNotNull(mockGlobalRpcCache);
105         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
106
107         String actualRoute = routingTable.getGlobalRoute(routeIdentifier);
108         Assert.assertNull(actualRoute);
109     }
110
111     @Test
112     public void removeGlobalRoute_ExistingRouteId_ShouldRemove() throws Exception {
113
114         Assert.assertNotNull(mockGlobalRpcCache);
115         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
116
117         ConcurrentMap cache = routingTable.getGlobalRpcCache();
118         Assert.assertTrue(cache.size() == 0);
119         routingTable.addGlobalRoute(routeIdentifier, "172.27.12.1:5000");
120         Assert.assertTrue(cache.size() == 1);
121
122         routingTable.removeGlobalRoute(routeIdentifier);
123         Assert.assertTrue(cache.size() == 0);
124
125     }
126
127     @Test
128     public void removeGlobalRoute_NonExistentRouteId_ShouldDoNothing() throws Exception {
129
130         Assert.assertNotNull(mockGlobalRpcCache);
131         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
132
133         ConcurrentMap cache = routingTable.getGlobalRpcCache();
134         Assert.assertTrue(cache.size() == 0);
135
136         routingTable.removeGlobalRoute(routeIdentifier);
137         Assert.assertTrue(cache.size() == 0);
138
139     }
140
141     @Test
142     public void addRoute_ForNewRouteId_ShouldAddRoute() throws Exception {
143         Assert.assertTrue(mockRpcCache.size() == 0);
144
145         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeId = getRouteIdentifier();
146
147         routingTable.addRoute(routeId, new String());
148         Assert.assertTrue(mockRpcCache.size() == 1);
149
150         Set<String> routes = routingTable.getRoutes(routeId);
151         Assert.assertEquals(1, routes.size());
152     }
153
154     @Test
155     public void addRoute_ForExistingRouteId_ShouldAppendRoute() throws Exception {
156
157         Assert.assertTrue(mockRpcCache.size() == 0);
158
159         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeId = getRouteIdentifier();
160
161         String route_1 = "10.0.0.1:5955";
162         String route_2 = "10.0.0.2:5955";
163
164         routingTable.addRoute(routeId, route_1);
165         routingTable.addRoute(routeId, route_2);
166
167         Assert.assertTrue(mockRpcCache.size() == 1);
168
169         Set<String> routes = routingTable.getRoutes(routeId);
170         Assert.assertEquals(2, routes.size());
171         Assert.assertTrue(routes.contains(route_1));
172         Assert.assertTrue(routes.contains(route_2));
173     }
174
175     @Test
176     public void addRoute_UsingMultipleThreads_ShouldNotOverwrite(){
177         ExecutorService threadPool = Executors.newCachedThreadPool();
178
179         int numOfRoutesToAdd = 100;
180         String routePrefix_1   = "10.0.0.1:555";
181         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
182         threadPool.submit(addRoutes(numOfRoutesToAdd, routePrefix_1, routeId));
183         String routePrefix_2   = "10.0.0.1:556";
184         threadPool.submit(addRoutes(numOfRoutesToAdd, routePrefix_2, routeId));
185
186         // wait for all tasks to complete; timeout in 10 sec
187         threadPool.shutdown();
188         try {
189             threadPool.awaitTermination(10, TimeUnit.SECONDS); //
190         } catch (InterruptedException e) {
191             e.printStackTrace();
192         }
193
194         Assert.assertEquals(2*numOfRoutesToAdd, routingTable.getRoutes(routeId).size());
195     }
196
197     @Test(expected = NullPointerException.class)
198     public void addRoute_NullRouteId_shouldThrowNpe() throws Exception {
199
200         routingTable.addRoute(null, new String());
201     }
202
203     @Test(expected = NullPointerException.class)
204     public void addRoute_NullRoute_shouldThrowNpe() throws Exception{
205
206         routingTable.addRoute(getRouteIdentifier(), null);
207     }
208
209     @Test (expected = UnsupportedOperationException.class)
210     public void getRoutes_Call_ShouldReturnImmutableCopy() throws Exception{
211         Assert.assertNotNull(routingTable);
212         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
213         routingTable.addRoute(routeId, new String());
214
215         Set<String> routes = routingTable.getRoutes(routeId); //returns Immutable Set
216
217         routes.add(new String()); //can not be modified; should throw
218     }
219
220     @Test
221     public void getRoutes_With2RoutesFor1RouteId_ShouldReturnASetWithSize2() throws Exception{
222         Assert.assertNotNull(routingTable);
223         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
224         routingTable.addRoute(routeId, "10.0.0.1:5555");
225         routingTable.addRoute(routeId, "10.0.0.2:5555");
226
227         Set<String> routes = routingTable.getRoutes(routeId); //returns Immutable Set
228
229         Assert.assertEquals(2, routes.size());
230     }
231
232     @Test
233     public void getLastAddedRoute_WhenMultipleRoutesExists_ShouldReturnLatestRoute()
234             throws Exception {
235
236         Assert.assertNotNull(routingTable);
237         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
238         String route_1 = "10.0.0.1:5555";
239         String route_2 = "10.0.0.2:5555";
240         routingTable.addRoute(routeId, route_1);
241         routingTable.addRoute(routeId, route_2);
242
243         Assert.assertEquals(route_2, routingTable.getLastAddedRoute(routeId));
244     }
245
246     @Test
247     public void removeRoute_WhenMultipleRoutesExist_RemovesGivenRoute() throws Exception{
248         Assert.assertNotNull(routingTable);
249         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
250         String route_1 = "10.0.0.1:5555";
251         String route_2 = "10.0.0.2:5555";
252
253         routingTable.addRoute(routeId, route_1);
254         routingTable.addRoute(routeId, route_2);
255
256         Assert.assertEquals(2, routingTable.getRoutes(routeId).size());
257
258         routingTable.removeRoute(routeId, route_1);
259         Assert.assertEquals(1, routingTable.getRoutes(routeId).size());
260
261     }
262
263     @Test
264     public void removeRoute_WhenOnlyOneRouteExists_RemovesRouteId() throws Exception{
265         Assert.assertNotNull(routingTable);
266         RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
267         String route_1 = "10.0.0.1:5555";
268
269         routingTable.addRoute(routeId, route_1);
270         Assert.assertEquals(1, routingTable.getRoutes(routeId).size());
271
272         routingTable.removeRoute(routeId, route_1);
273         ConcurrentMap cache = routingTable.getRpcCache();
274         Assert.assertFalse(cache.containsKey(routeId));
275
276     }
277
278     /*
279      * Private helper methods
280      */
281     private void createRoutingTableCache() throws Exception {
282
283         //here init
284         Component c = mock(Component.class);
285
286         when(clusterService.existCache(
287                 RoutingTableImpl.GLOBALRPC_CACHE)).thenReturn(false);
288
289         when(clusterService.createCache(RoutingTableImpl.GLOBALRPC_CACHE,
290                 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).
291                 thenReturn(mockGlobalRpcCache);
292
293         when(clusterService.existCache(
294                 RoutingTableImpl.RPC_CACHE)).thenReturn(false);
295
296         when(clusterService.createCache(RoutingTableImpl.RPC_CACHE,
297                 EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).
298                 thenReturn(mockRpcCache);
299
300         doNothing().when(clusterService).tbegin();
301         doNothing().when(clusterService).tcommit();
302
303         routingTable.setClusterGlobalServices(this.clusterService);
304         routingTable.init(c);
305
306         Assert.assertEquals(mockGlobalRpcCache, routingTable.getGlobalRpcCache());
307         Assert.assertEquals(mockRpcCache, routingTable.getRpcCache());
308     }
309
310     private RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> getRouteIdentifier(){
311         RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = mock(RpcRouter.RouteIdentifier.class);
312         InstanceIdentifier identifier = mock(InstanceIdentifier.class);
313         when(routeIdentifier.getType()).thenReturn(QNAME);
314         when(routeIdentifier.getRoute()).thenReturn(identifier);
315
316         return routeIdentifier;
317     }
318
319     private Runnable addRoutes(final int numRoutes, final String routePrefix, final RpcRouter.RouteIdentifier routeId){
320         return new Runnable() {
321             @Override
322             public void run() {
323                 for (int i=0;i<numRoutes;i++){
324                     String route = routePrefix + i;
325                     try {
326                         routingTable.addRoute(routeId, route);
327                     } catch (Exception e) {
328                         e.printStackTrace();
329                     }
330                 }
331             }
332         };
333     }
334 }