blob: b13993b73f1b3bc985bf7925c97feb435581b346 [file] [log] [blame]
Jonathan Hartdeda0ba2014-04-03 11:14:12 -07001package net.onrc.onos.core.registry;
Naoki Shiotad00accf2013-06-25 14:40:37 -07002
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.List;
6import java.util.Map;
7
8import net.floodlightcontroller.core.module.FloodlightModuleContext;
9import net.floodlightcontroller.test.FloodlightTestCase;
Jonathan Hartdeda0ba2014-04-03 11:14:12 -070010import net.onrc.onos.core.registry.StandaloneRegistryTest.LoggingCallback;
11import net.onrc.onos.core.registry.ZookeeperRegistry.SwitchLeaderListener;
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -070012import net.onrc.onos.core.util.OnosInstanceId;
Naoki Shiotad00accf2013-06-25 14:40:37 -070013
Jonathan Hart116b1fe2014-03-14 18:53:47 -070014import org.apache.curator.RetryPolicy;
15import org.apache.curator.framework.CuratorFramework;
16import org.apache.curator.framework.CuratorFrameworkFactory;
17import org.apache.curator.framework.listen.ListenerContainer;
18import org.apache.curator.framework.recipes.atomic.AtomicValue;
19import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
20import org.apache.curator.framework.recipes.cache.ChildData;
21import org.apache.curator.framework.recipes.cache.PathChildrenCache;
22import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
23import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
24import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
25import org.apache.curator.framework.recipes.leader.LeaderLatch;
26import org.apache.curator.x.discovery.ServiceCache;
27import org.apache.curator.x.discovery.ServiceCacheBuilder;
28import org.apache.curator.x.discovery.ServiceDiscovery;
29import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
30import org.apache.curator.x.discovery.ServiceInstance;
Naoki Shiotad00accf2013-06-25 14:40:37 -070031import org.easymock.IAnswer;
32import org.junit.After;
33import org.junit.Before;
34import org.junit.Ignore;
35import org.junit.Test;
36import org.junit.runner.RunWith;
Naoki Shiotad00accf2013-06-25 14:40:37 -070037import org.powermock.api.easymock.PowerMock;
38import org.powermock.core.classloader.annotations.PrepareForTest;
39import org.powermock.modules.junit4.PowerMockRunner;
Jonathan Hartc78b8f62014-08-07 22:31:09 -070040import org.projectfloodlight.openflow.util.HexString;
Naoki Shiotad00accf2013-06-25 14:40:37 -070041
Sho SHIMIZU107344e2014-08-13 16:11:53 -070042import static org.easymock.EasyMock.anyBoolean;
43import static org.easymock.EasyMock.anyInt;
44import static org.easymock.EasyMock.anyLong;
45import static org.easymock.EasyMock.anyObject;
46import static org.easymock.EasyMock.createMock;
47import static org.easymock.EasyMock.expect;
48import static org.easymock.EasyMock.expectLastCall;
49import static org.easymock.EasyMock.getCurrentArguments;
50import static org.easymock.EasyMock.replay;
51import static org.easymock.EasyMock.verify;
52
Naoki Shiotad00accf2013-06-25 14:40:37 -070053/**
Naoki Shiotaa3b2dfa2013-06-27 13:52:24 -070054 * Unit test for {@link ZookeeperRegistry}.
55 * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
Ray Milkey269ffb92014-04-03 14:43:30 -070056 * implement another test class to test them.
Naoki Shiotad00accf2013-06-25 14:40:37 -070057 */
58@RunWith(PowerMockRunner.class)
59@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
Ray Milkey269ffb92014-04-03 14:43:30 -070060 ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070061 ZookeeperRegistry.SwitchPathCacheListener.class })
Naoki Shiotad00accf2013-06-25 14:40:37 -070062public class ZookeeperRegistryTest extends FloodlightTestCase {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070063 private static final Long ID_BLOCK_SIZE = 0x100000000L;
Naoki Shiotad00accf2013-06-25 14:40:37 -070064
Ray Milkey269ffb92014-04-03 14:43:30 -070065 protected ZookeeperRegistry registry;
66 protected CuratorFramework client;
Naoki Shiotad00accf2013-06-25 14:40:37 -070067
Ray Milkey269ffb92014-04-03 14:43:30 -070068 protected PathChildrenCacheListener pathChildrenCacheListener;
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070069 protected static final String CONTROLLER_ID = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -070070
Ray Milkey269ffb92014-04-03 14:43:30 -070071 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -070072 * Initialize {@link ZookeeperRegistry} Object and inject initial value with
73 * {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
Ray Milkey269ffb92014-04-03 14:43:30 -070074 * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
75 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070076 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -070077 @Before
78 public void setUp() throws Exception {
79 super.setUp();
Naoki Shiotad00accf2013-06-25 14:40:37 -070080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 pathChildrenCacheListener = null;
Naoki Shiotad00accf2013-06-25 14:40:37 -070082
Ray Milkey269ffb92014-04-03 14:43:30 -070083 // Mock of CuratorFramework
84 client = createCuratorFrameworkMock();
Naoki Shiotad00accf2013-06-25 14:40:37 -070085
Ray Milkey269ffb92014-04-03 14:43:30 -070086 // Mock of CuratorFrameworkFactory
87 PowerMock.mockStatic(CuratorFrameworkFactory.class);
Sho SHIMIZU107344e2014-08-13 16:11:53 -070088 expect(CuratorFrameworkFactory.newClient((String) anyObject(),
89 anyInt(), anyInt(), (RetryPolicy) anyObject())).andReturn(client);
Ray Milkey269ffb92014-04-03 14:43:30 -070090 PowerMock.replay(CuratorFrameworkFactory.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -070091
Ray Milkey269ffb92014-04-03 14:43:30 -070092 FloodlightModuleContext fmc = new FloodlightModuleContext();
93 registry = new ZookeeperRegistry();
94 fmc.addService(ZookeeperRegistry.class, registry);
Naoki Shiotad00accf2013-06-25 14:40:37 -070095
Ray Milkey269ffb92014-04-03 14:43:30 -070096 registry.init(fmc);
Naoki Shiotad00accf2013-06-25 14:40:37 -070097
Ray Milkey269ffb92014-04-03 14:43:30 -070098 PowerMock.verify(client, CuratorFrameworkFactory.class);
99 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700100
Ray Milkey269ffb92014-04-03 14:43:30 -0700101 /**
102 * Clean up member variables (empty for now).
103 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700104 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -0700105 @After
106 public void tearDown() throws Exception {
107 super.tearDown();
108 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700109
Ray Milkey269ffb92014-04-03 14:43:30 -0700110 /**
111 * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700112 * (Exceptions are usually out of test target,
113 * but {@link ZookeeperRegistry#registerController(String)}
114 * throws an exception in case of invalid registration.)
Ray Milkey269ffb92014-04-03 14:43:30 -0700115 */
116 @Test
117 public void testRegisterController() {
118 String controllerIdToRegister = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700119
Ray Milkey269ffb92014-04-03 14:43:30 -0700120 try {
121 registry.registerController(controllerIdToRegister);
122 } catch (RegistryException e) {
123 e.printStackTrace();
124 fail(e.getMessage());
125 }
126 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700127
Ray Milkey269ffb92014-04-03 14:43:30 -0700128 /**
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700129 * Test if {@link ZookeeperRegistry#getOnosInstanceId()} correctly returns
130 * registered ID.
Ray Milkey269ffb92014-04-03 14:43:30 -0700131 *
132 * @throws Exception
133 */
134 @Test
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700135 public void testGetOnosInstanceId() throws Exception {
Ray Milkey269ffb92014-04-03 14:43:30 -0700136 String controllerIdToRegister = "controller1";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700137
Ray Milkey269ffb92014-04-03 14:43:30 -0700138 // try before controller is registered
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700139 OnosInstanceId onosInstanceId = registry.getOnosInstanceId();
140 assertNull(onosInstanceId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700141
Ray Milkey269ffb92014-04-03 14:43:30 -0700142 // register
143 registry.registerController(controllerIdToRegister);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700144
Pavlin Radoslavov53b208a2014-07-28 13:16:11 -0700145 // call getOnosInstanceId and verify
146 onosInstanceId = registry.getOnosInstanceId();
147 assertNotNull(onosInstanceId);
148 assertEquals(controllerIdToRegister, onosInstanceId.toString());
Ray Milkey269ffb92014-04-03 14:43:30 -0700149 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700150
Ray Milkey269ffb92014-04-03 14:43:30 -0700151 /**
152 * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700153 * Controllers to be returned are injected while setup.
154 * See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
Ray Milkey269ffb92014-04-03 14:43:30 -0700155 * to what controllers are injected using mock {@link ServiceCache}.
156 *
157 * @throws Exception
158 */
159 @Test
160 public void testGetAllControllers() throws Exception {
161 String controllerIdRegistered = "controller1";
162 String controllerIdNotRegistered = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700163
Ray Milkey269ffb92014-04-03 14:43:30 -0700164 try {
165 Collection<String> ctrls = registry.getAllControllers();
166 assertTrue(ctrls.contains(controllerIdRegistered));
167 assertFalse(ctrls.contains(controllerIdNotRegistered));
168 } catch (RegistryException e) {
169 e.printStackTrace();
170 fail(e.getMessage());
171 }
172 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700173
Ray Milkey269ffb92014-04-03 14:43:30 -0700174 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700175 * Test if {@link ZookeeperRegistry#requestControl(long, IControllerRegistryService.ControlChangeCallback)}
176 * correctly take control of specific switch.
177 * Because {@link ZookeeperRegistry#requestControl(long, IControllerRegistryService.ControlChangeCallback)}
Ray Milkey269ffb92014-04-03 14:43:30 -0700178 * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
179 *
180 * @throws Exception
181 */
182 @Test
183 public void testRequestControl() throws Exception {
184 // Mock LeaderLatch
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700185 LeaderLatch latch = createMock(LeaderLatch.class);
186 latch.addListener(anyObject(SwitchLeaderListener.class));
187 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700188 latch.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700189 expectLastCall().once();
190 replay(latch);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700191
Ray Milkey269ffb92014-04-03 14:43:30 -0700192 PowerMock.expectNew(LeaderLatch.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700193 anyObject(CuratorFramework.class),
194 anyObject(String.class),
195 anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700196 .andReturn(latch).once();
197 PowerMock.replay(LeaderLatch.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700198
Ray Milkey269ffb92014-04-03 14:43:30 -0700199 String controllerId = "controller2013";
200 registry.registerController(controllerId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700201
Ray Milkey269ffb92014-04-03 14:43:30 -0700202 LoggingCallback callback = new LoggingCallback(1);
203 long dpidToRequest = 2000L;
Naoki Shiotad00accf2013-06-25 14:40:37 -0700204
Ray Milkey269ffb92014-04-03 14:43:30 -0700205 try {
206 registry.requestControl(dpidToRequest, callback);
207 } catch (RegistryException e) {
208 e.printStackTrace();
209 fail(e.getMessage());
210 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700211
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700212 verify(latch);
Ray Milkey269ffb92014-04-03 14:43:30 -0700213 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700214
Ray Milkey269ffb92014-04-03 14:43:30 -0700215 /**
216 * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
217 * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
218 * {@link LeaderLatch} object and verify latch is correctly set up.
219 *
220 * @throws Exception
221 */
222 @Test
223 public void testReleaseControl() throws Exception {
224 // Mock of LeaderLatch
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700225 LeaderLatch latch = createMock(LeaderLatch.class);
226 latch.addListener(anyObject(SwitchLeaderListener.class));
227 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700228 latch.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700229 expectLastCall().once();
230 latch.removeListener(anyObject(SwitchLeaderListener.class));
231 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700232 latch.close();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700233 expectLastCall().once();
234 replay(latch);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700235
Ray Milkey269ffb92014-04-03 14:43:30 -0700236 PowerMock.expectNew(LeaderLatch.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700237 anyObject(CuratorFramework.class),
238 anyObject(String.class),
239 anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700240 .andReturn(latch).once();
241 PowerMock.replay(LeaderLatch.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700242
Ray Milkey269ffb92014-04-03 14:43:30 -0700243 String controllerId = "controller2013";
244 registry.registerController(controllerId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700245
Ray Milkey269ffb92014-04-03 14:43:30 -0700246 long dpidToRequest = 2000L;
247 LoggingCallback callback = new LoggingCallback(1);
248
249 registry.requestControl(dpidToRequest, callback);
250 registry.releaseControl(dpidToRequest);
251
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700252 verify(latch);
Ray Milkey269ffb92014-04-03 14:43:30 -0700253 }
254
255 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700256 * Test if {@link ZookeeperRegistry#hasControl(long)} returns
257 * correct status whether controller has control of specific switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700258 *
259 * @throws Exception
260 */
261 @Test
262 public void testHasControl() throws Exception {
263 // Mock of LeaderLatch
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700264 LeaderLatch latch = createMock(LeaderLatch.class);
265 latch.addListener(anyObject(SwitchLeaderListener.class));
266 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700267 latch.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700268 expectLastCall().once();
269 expect(latch.hasLeadership()).andReturn(true).anyTimes();
270 latch.removeListener(anyObject(SwitchLeaderListener.class));
271 expectLastCall().once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700272 latch.close();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700273 expectLastCall().once();
274 replay(latch);
Ray Milkey269ffb92014-04-03 14:43:30 -0700275
276 PowerMock.expectNew(LeaderLatch.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700277 anyObject(CuratorFramework.class),
278 anyObject(String.class),
279 anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700280 .andReturn(latch);
281 PowerMock.replay(LeaderLatch.class);
282
283 String controllerId = "controller2013";
284 registry.registerController(controllerId);
285
286 long dpidToRequest = 2000L;
287 LoggingCallback callback = new LoggingCallback(2);
288
289 // Test before request control
290 assertFalse(registry.hasControl(dpidToRequest));
291
292 registry.requestControl(dpidToRequest, callback);
293
294 // Test after request control
295 assertTrue(registry.hasControl(dpidToRequest));
296
297 registry.releaseControl(dpidToRequest);
298
299 // Test after release control
300 assertFalse(registry.hasControl(dpidToRequest));
301
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700302 verify(latch);
Ray Milkey269ffb92014-04-03 14:43:30 -0700303 }
304
305 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700306 * Test if {@link ZookeeperRegistry#getControllerForSwitch(long)}
307 * correctly returns controller ID of specific switch.
308 * Relation between controllers and switches are defined by
309 * {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
Ray Milkey269ffb92014-04-03 14:43:30 -0700310 *
311 * @throws Throwable
312 */
313 @Test
314 public void testGetControllerForSwitch() throws Throwable {
315 long dpidRegistered = 1000L;
316 long dpidNotRegistered = 2000L;
317
318 setPathChildrenCache();
319
320 String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
321 assertEquals("controller1", controllerForSw);
322
323 controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
324 assertEquals(null, controllerForSw);
325 }
326
327 /**
328 * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
329 * switches controlled by a controller.
330 *
331 * @throws Exception
332 */
333 // TODO: Test after getSwitchesControlledByController() is implemented.
334 @Ignore
335 @Test
336 public void testGetSwitchesControlledByController() throws Exception {
337 String controllerIdRegistered = "controller1";
338 String dpidRegistered = HexString.toHexString(1000L);
339 String controllerIdNotRegistered = CONTROLLER_ID;
340
341 Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
342 assertNotNull(switches);
343 assertTrue(switches.contains(dpidRegistered));
344
345 switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
346 assertNotNull(switches);
347 assertEquals(0, switches.size());
348 }
349
350 /**
351 * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
352 * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
353 *
354 * @throws Exception
355 */
356 @Test
357 public void testGetAllSwitches() throws Exception {
358 String[] dpids = {
359 HexString.toHexString(1000L),
360 HexString.toHexString(1001L),
361 HexString.toHexString(1002L),
362 };
363
364 setPathChildrenCache();
365
366 Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
367 assertNotNull(switches);
368 assertEquals(dpids.length, switches.size());
369 for (String dpid : dpids) {
370 assertTrue(switches.keySet().contains(dpid));
371 }
372 }
373
374 /**
375 * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
376 */
377 @Test
378 public void testAllocateUniqueIdBlock() {
379 // Number of blocks to be verified that any of them has unique block
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700380 final int numBlocks = 100;
381 ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(numBlocks);
Ray Milkey269ffb92014-04-03 14:43:30 -0700382
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700383 for (int i = 0; i < numBlocks; ++i) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700384 IdBlock block = registry.allocateUniqueIdBlock();
385 assertNotNull(block);
386 blocks.add(block);
387 }
388
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700389 for (int i = 0; i < numBlocks; ++i) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700390 IdBlock block1 = blocks.get(i);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700391 for (int j = i + 1; j < numBlocks; ++j) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700392 IdBlock block2 = blocks.get(j);
393 IdBlock lower, higher;
394
395 if (block1.getStart() < block2.getStart()) {
396 lower = block1;
397 higher = block2;
398 } else {
399 lower = block2;
400 higher = block1;
401 }
402
403 assertTrue(lower.getSize() > 0L);
404 assertTrue(higher.getSize() > 0L);
405 assertTrue(lower.getEnd() <= higher.getStart());
406 }
407 }
408 }
409
410
411 //-------------------------- Creation of mock objects --------------------------
412
413 /**
414 * Create mock {@link CuratorFramework} object with initial value below.<br>
415 * [Ctrl ID] : [DPID]<br>
416 * controller1 : 1000<br>
417 * controller2 : 1001<br>
418 * controller2 : 1002<br>
419 * controller2013 : nothing
420 *
421 * @return Created mock object
422 * @throws Exception
423 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700424 @SuppressWarnings({"serial", "unchecked" })
Ray Milkey269ffb92014-04-03 14:43:30 -0700425 private CuratorFramework createCuratorFrameworkMock() throws Exception {
426 // Mock of AtomicValue
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700427 AtomicValue<Long> atomicValue = createMock(AtomicValue.class);
428 expect(atomicValue.succeeded()).andReturn(true).anyTimes();
429 expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700430 private long value = 0;
431
432 @Override
433 public Long answer() throws Throwable {
434 value += ID_BLOCK_SIZE;
435 return value;
436 }
437 }).anyTimes();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700438 expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700439 private long value = ID_BLOCK_SIZE;
440
441 @Override
442 public Long answer() throws Throwable {
443 value += ID_BLOCK_SIZE;
444 return value;
445 }
446 }).anyTimes();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700447 replay(atomicValue);
Ray Milkey269ffb92014-04-03 14:43:30 -0700448
449 // Mock DistributedAtomicLong
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700450 DistributedAtomicLong daLong = createMock(DistributedAtomicLong.class);
451 expect(daLong.add(anyLong())).andReturn(atomicValue).anyTimes();
452 replay(daLong);
Ray Milkey269ffb92014-04-03 14:43:30 -0700453 PowerMock.expectNew(DistributedAtomicLong.class,
454 new Class<?>[]{CuratorFramework.class, String.class, RetryPolicy.class},
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700455 anyObject(CuratorFramework.class),
456 anyObject(String.class),
457 anyObject(RetryPolicy.class)).
Ray Milkey269ffb92014-04-03 14:43:30 -0700458 andReturn(daLong).anyTimes();
459 PowerMock.replay(DistributedAtomicLong.class);
460
461 // Mock ListenerContainer
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700462 ListenerContainer<PathChildrenCacheListener> listenerContainer = createMock(ListenerContainer.class);
463 listenerContainer.addListener(anyObject(PathChildrenCacheListener.class));
464 expectLastCall().andAnswer(new IAnswer<Object>() {
Ray Milkey269ffb92014-04-03 14:43:30 -0700465 @Override
466 public Object answer() throws Throwable {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700467 pathChildrenCacheListener = (PathChildrenCacheListener) getCurrentArguments()[0];
Ray Milkey269ffb92014-04-03 14:43:30 -0700468 return null;
469 }
470 }).once();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700471 replay(listenerContainer);
Ray Milkey269ffb92014-04-03 14:43:30 -0700472
473 // Mock PathChildrenCache
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700474 PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(
475 CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
476 PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1",
477 new String[] {HexString.toHexString(1000L)}, listenerContainer);
478 PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2",
479 new String[] {
480 HexString.toHexString(1001L), HexString.toHexString(1002L)},
481 listenerContainer);
Ray Milkey269ffb92014-04-03 14:43:30 -0700482
483 // Mock PathChildrenCache constructor
484 PowerMock.expectNew(PathChildrenCache.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700485 anyObject(CuratorFramework.class), anyObject(String.class), anyBoolean()).
Ray Milkey269ffb92014-04-03 14:43:30 -0700486 andReturn(pathChildrenCacheMain).once();
487 PowerMock.expectNew(PathChildrenCache.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700488 anyObject(CuratorFramework.class), anyObject(String.class), anyBoolean()).
Ray Milkey269ffb92014-04-03 14:43:30 -0700489 andReturn(pathChildrenCache1).once();
490 PowerMock.expectNew(PathChildrenCache.class,
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700491 anyObject(CuratorFramework.class), anyObject(String.class), anyBoolean()).
Ray Milkey269ffb92014-04-03 14:43:30 -0700492 andReturn(pathChildrenCache2).anyTimes();
493 PowerMock.replay(PathChildrenCache.class);
494
495 // Mock ServiceCache
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700496 ServiceCache<ControllerService> serviceCache = createMock(ServiceCache.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700497 serviceCache.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700498 expectLastCall().once();
499 expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService>>() { {
Ray Milkey269ffb92014-04-03 14:43:30 -0700500 add(createServiceInstanceMock("controller1"));
501 add(createServiceInstanceMock("controller2"));
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700502 } }).anyTimes();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700503 replay(serviceCache);
Ray Milkey269ffb92014-04-03 14:43:30 -0700504
505 // Mock ServiceCacheBuilder
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700506 ServiceCacheBuilder<ControllerService> serviceCacheBuilder = createMock(ServiceCacheBuilder.class);
507 expect(serviceCacheBuilder.name(anyObject(String.class)))
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700508 .andReturn(serviceCacheBuilder).once();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700509 expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
510 replay(serviceCacheBuilder);
Ray Milkey269ffb92014-04-03 14:43:30 -0700511
512 // Mock ServiceDiscovery
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700513 ServiceDiscovery<ControllerService> serviceDiscovery = createMock(ServiceDiscovery.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700514 serviceDiscovery.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700515 expectLastCall().once();
516 expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
517 serviceDiscovery.registerService(anyObject(ServiceInstance.class));
518 expectLastCall().once();
519 replay(serviceDiscovery);
Ray Milkey269ffb92014-04-03 14:43:30 -0700520
521 // Mock CuratorFramework
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700522 CuratorFramework mockClient = createMock(CuratorFramework.class);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700523 mockClient.start();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700524 expectLastCall().once();
525 expect(mockClient.usingNamespace(anyObject(String.class))).andReturn(mockClient);
526 replay(mockClient);
Ray Milkey269ffb92014-04-03 14:43:30 -0700527
528 // Mock ServiceDiscoveryBuilder
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700529 ServiceDiscoveryBuilder<ControllerService> builder = createMock(ServiceDiscoveryBuilder.class);
530 expect(builder.client(mockClient)).andReturn(builder).once();
531 expect(builder.basePath(anyObject(String.class))).andReturn(builder);
532 expect(builder.build()).andReturn(serviceDiscovery);
533 replay(builder);
Ray Milkey269ffb92014-04-03 14:43:30 -0700534
535 PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700536 expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700537 PowerMock.replay(ServiceDiscoveryBuilder.class);
538
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700539 return mockClient;
Ray Milkey269ffb92014-04-03 14:43:30 -0700540 }
541
542 /**
543 * Create mock {@link ServiceInstance} object using given controller ID.
544 *
545 * @param controllerId Controller ID to represent instance's payload (ControllerService).
546 * @return Mock ServiceInstance object
547 */
548 private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700549 ControllerService controllerService = createMock(ControllerService.class);
550 expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
551 replay(controllerService);
Ray Milkey269ffb92014-04-03 14:43:30 -0700552
553 @SuppressWarnings("unchecked")
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700554 ServiceInstance<ControllerService> serviceInstance = createMock(ServiceInstance.class);
555 expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
556 replay(serviceInstance);
Ray Milkey269ffb92014-04-03 14:43:30 -0700557
558 return serviceInstance;
559 }
560
561 /**
562 * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
563 *
564 * @param controllerId Controller ID to represent current data.
565 * @param paths List of HexString indicating switch's DPID.
566 * @param listener Callback object to be set as Listenable.
567 * @return Mock PathChildrenCache object
568 * @throws Exception
569 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700570 private PathChildrenCache createPathChildrenCacheMock(
571 final String controllerId,
572 final String[] paths,
573 ListenerContainer<PathChildrenCacheListener> listener)
574 throws Exception {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700575 PathChildrenCache pathChildrenCache = createMock(PathChildrenCache.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700576
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700577 expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700578
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700579 pathChildrenCache.start(anyObject(StartMode.class));
580 expectLastCall().anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700581
582 List<ChildData> childs = new ArrayList<ChildData>();
583 for (String path : paths) {
584 childs.add(createChildDataMockForCurrentData(controllerId, path));
585 }
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700586 expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700587
588 pathChildrenCache.rebuild();
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700589 expectLastCall().anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700590
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700591 replay(pathChildrenCache);
Ray Milkey269ffb92014-04-03 14:43:30 -0700592
593 return pathChildrenCache;
594 }
595
596 /**
597 * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
598 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
599 *
600 * @param controllerId Controller ID
601 * @param path HexString indicating switch's DPID
602 * @return Mock ChildData object
603 */
604 private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700605 ChildData data = createMock(ChildData.class);
606 expect(data.getPath()).andReturn(path + "-0").anyTimes();
607 expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
608 replay(data);
Ray Milkey269ffb92014-04-03 14:43:30 -0700609
610 return data;
611 }
612
613 /**
614 * Inject relations between controllers and switches using callback object.
615 *
616 * @throws Exception
617 */
618 private void setPathChildrenCache() throws Exception {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700619 pathChildrenCacheListener.childEvent(
620 client,
621 createChildrenCacheEventMock("controller1", HexString.toHexString(1000L),
622 PathChildrenCacheEvent.Type.CHILD_ADDED));
623 pathChildrenCacheListener.childEvent(
624 client,
625 createChildrenCacheEventMock("controller2", HexString.toHexString(1001L),
626 PathChildrenCacheEvent.Type.CHILD_ADDED));
627 pathChildrenCacheListener.childEvent(
628 client,
629 createChildrenCacheEventMock("controller2", HexString.toHexString(1002L),
630 PathChildrenCacheEvent.Type.CHILD_ADDED));
Ray Milkey269ffb92014-04-03 14:43:30 -0700631 }
632
633 /**
634 * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
635 *
636 * @param controllerId Controller ID.
637 * @param path HexString of DPID.
638 * @param type Event type to be set to mock object.
639 * @return Mock PathChildrenCacheEvent object
640 */
641 private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
642 PathChildrenCacheEvent.Type type) {
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700643 PathChildrenCacheEvent event = createMock(PathChildrenCacheEvent.class);
644 ChildData data = createMock(ChildData.class);
Ray Milkey269ffb92014-04-03 14:43:30 -0700645
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700646 expect(data.getPath()).andReturn(path).anyTimes();
647 expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
648 replay(data);
Ray Milkey269ffb92014-04-03 14:43:30 -0700649
Sho SHIMIZU107344e2014-08-13 16:11:53 -0700650 expect(event.getType()).andReturn(type).anyTimes();
651 expect(event.getData()).andReturn(data).anyTimes();
652 replay(event);
Ray Milkey269ffb92014-04-03 14:43:30 -0700653
654 return event;
655 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700656}