blob: ca56736ec73239e4b342f6ed56a7a2230eb996d8 [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;
Naoki Shiotad00accf2013-06-25 14:40:37 -070012
Jonathan Hart116b1fe2014-03-14 18:53:47 -070013import org.apache.curator.RetryPolicy;
14import org.apache.curator.framework.CuratorFramework;
15import org.apache.curator.framework.CuratorFrameworkFactory;
16import org.apache.curator.framework.listen.ListenerContainer;
17import org.apache.curator.framework.recipes.atomic.AtomicValue;
18import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
19import org.apache.curator.framework.recipes.cache.ChildData;
20import org.apache.curator.framework.recipes.cache.PathChildrenCache;
21import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
22import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
23import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
24import org.apache.curator.framework.recipes.leader.LeaderLatch;
25import org.apache.curator.x.discovery.ServiceCache;
26import org.apache.curator.x.discovery.ServiceCacheBuilder;
27import org.apache.curator.x.discovery.ServiceDiscovery;
28import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
29import org.apache.curator.x.discovery.ServiceInstance;
Naoki Shiotad00accf2013-06-25 14:40:37 -070030import org.easymock.EasyMock;
31import org.easymock.IAnswer;
32import org.junit.After;
33import org.junit.Before;
34import org.junit.Ignore;
35import org.junit.Test;
36import org.junit.runner.RunWith;
37import org.openflow.util.HexString;
38import org.powermock.api.easymock.PowerMock;
39import org.powermock.core.classloader.annotations.PrepareForTest;
40import org.powermock.modules.junit4.PowerMockRunner;
41
Naoki Shiotad00accf2013-06-25 14:40:37 -070042/**
Naoki Shiotaa3b2dfa2013-06-27 13:52:24 -070043 * Unit test for {@link ZookeeperRegistry}.
44 * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
Ray Milkey269ffb92014-04-03 14:43:30 -070045 * implement another test class to test them.
Naoki Shiotad00accf2013-06-25 14:40:37 -070046 */
47@RunWith(PowerMockRunner.class)
48@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
Ray Milkey269ffb92014-04-03 14:43:30 -070049 ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070050 ZookeeperRegistry.SwitchPathCacheListener.class })
Naoki Shiotad00accf2013-06-25 14:40:37 -070051public class ZookeeperRegistryTest extends FloodlightTestCase {
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070052 private static final Long ID_BLOCK_SIZE = 0x100000000L;
Naoki Shiotad00accf2013-06-25 14:40:37 -070053
Ray Milkey269ffb92014-04-03 14:43:30 -070054 protected ZookeeperRegistry registry;
55 protected CuratorFramework client;
Naoki Shiotad00accf2013-06-25 14:40:37 -070056
Ray Milkey269ffb92014-04-03 14:43:30 -070057 protected PathChildrenCacheListener pathChildrenCacheListener;
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070058 protected static final String CONTROLLER_ID = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -070059
Ray Milkey269ffb92014-04-03 14:43:30 -070060 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -070061 * Initialize {@link ZookeeperRegistry} Object and inject initial value with
62 * {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
Ray Milkey269ffb92014-04-03 14:43:30 -070063 * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
64 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070065 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -070066 @Before
67 public void setUp() throws Exception {
68 super.setUp();
Naoki Shiotad00accf2013-06-25 14:40:37 -070069
Ray Milkey269ffb92014-04-03 14:43:30 -070070 pathChildrenCacheListener = null;
Naoki Shiotad00accf2013-06-25 14:40:37 -070071
Ray Milkey269ffb92014-04-03 14:43:30 -070072 // Mock of CuratorFramework
73 client = createCuratorFrameworkMock();
Naoki Shiotad00accf2013-06-25 14:40:37 -070074
Ray Milkey269ffb92014-04-03 14:43:30 -070075 // Mock of CuratorFrameworkFactory
76 PowerMock.mockStatic(CuratorFrameworkFactory.class);
77 EasyMock.expect(CuratorFrameworkFactory.newClient((String) EasyMock.anyObject(),
78 EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy) EasyMock.anyObject())).andReturn(client);
79 PowerMock.replay(CuratorFrameworkFactory.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -070080
Ray Milkey269ffb92014-04-03 14:43:30 -070081 FloodlightModuleContext fmc = new FloodlightModuleContext();
82 registry = new ZookeeperRegistry();
83 fmc.addService(ZookeeperRegistry.class, registry);
Naoki Shiotad00accf2013-06-25 14:40:37 -070084
Ray Milkey269ffb92014-04-03 14:43:30 -070085 registry.init(fmc);
Naoki Shiotad00accf2013-06-25 14:40:37 -070086
Ray Milkey269ffb92014-04-03 14:43:30 -070087 PowerMock.verify(client, CuratorFrameworkFactory.class);
88 }
Naoki Shiotad00accf2013-06-25 14:40:37 -070089
Ray Milkey269ffb92014-04-03 14:43:30 -070090 /**
91 * Clean up member variables (empty for now).
92 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -070093 @Override
Ray Milkey269ffb92014-04-03 14:43:30 -070094 @After
95 public void tearDown() throws Exception {
96 super.tearDown();
97 }
Naoki Shiotad00accf2013-06-25 14:40:37 -070098
Ray Milkey269ffb92014-04-03 14:43:30 -070099 /**
100 * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700101 * (Exceptions are usually out of test target,
102 * but {@link ZookeeperRegistry#registerController(String)}
103 * throws an exception in case of invalid registration.)
Ray Milkey269ffb92014-04-03 14:43:30 -0700104 */
105 @Test
106 public void testRegisterController() {
107 String controllerIdToRegister = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700108
Ray Milkey269ffb92014-04-03 14:43:30 -0700109 try {
110 registry.registerController(controllerIdToRegister);
111 } catch (RegistryException e) {
112 e.printStackTrace();
113 fail(e.getMessage());
114 }
115 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700116
Ray Milkey269ffb92014-04-03 14:43:30 -0700117 /**
118 * Test if {@link ZookeeperRegistry#getControllerId()} correctly returns registered ID.
119 *
120 * @throws Exception
121 */
122 @Test
123 public void testGetControllerId() throws Exception {
124 String controllerIdToRegister = "controller1";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700125
Ray Milkey269ffb92014-04-03 14:43:30 -0700126 // try before controller is registered
127 String controllerId = registry.getControllerId();
128 assertNull(controllerId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700129
Ray Milkey269ffb92014-04-03 14:43:30 -0700130 // register
131 registry.registerController(controllerIdToRegister);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700132
Ray Milkey269ffb92014-04-03 14:43:30 -0700133 // call getControllerId and verify
134 controllerId = registry.getControllerId();
135 assertNotNull(controllerId);
136 assertEquals(controllerIdToRegister, controllerId);
137 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700138
Ray Milkey269ffb92014-04-03 14:43:30 -0700139 /**
140 * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700141 * Controllers to be returned are injected while setup.
142 * See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
Ray Milkey269ffb92014-04-03 14:43:30 -0700143 * to what controllers are injected using mock {@link ServiceCache}.
144 *
145 * @throws Exception
146 */
147 @Test
148 public void testGetAllControllers() throws Exception {
149 String controllerIdRegistered = "controller1";
150 String controllerIdNotRegistered = "controller2013";
Naoki Shiotad00accf2013-06-25 14:40:37 -0700151
Ray Milkey269ffb92014-04-03 14:43:30 -0700152 try {
153 Collection<String> ctrls = registry.getAllControllers();
154 assertTrue(ctrls.contains(controllerIdRegistered));
155 assertFalse(ctrls.contains(controllerIdNotRegistered));
156 } catch (RegistryException e) {
157 e.printStackTrace();
158 fail(e.getMessage());
159 }
160 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700161
Ray Milkey269ffb92014-04-03 14:43:30 -0700162 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700163 * Test if {@link ZookeeperRegistry#requestControl(long, IControllerRegistryService.ControlChangeCallback)}
164 * correctly take control of specific switch.
165 * Because {@link ZookeeperRegistry#requestControl(long, IControllerRegistryService.ControlChangeCallback)}
Ray Milkey269ffb92014-04-03 14:43:30 -0700166 * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
167 *
168 * @throws Exception
169 */
170 @Test
171 public void testRequestControl() throws Exception {
172 // Mock LeaderLatch
173 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
174 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
175 EasyMock.expectLastCall().once();
176 latch.start();
177 EasyMock.expectLastCall().once();
178 EasyMock.replay(latch);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700179
Ray Milkey269ffb92014-04-03 14:43:30 -0700180 PowerMock.expectNew(LeaderLatch.class,
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700181 EasyMock.anyObject(CuratorFramework.class),
182 EasyMock.anyObject(String.class),
183 EasyMock.anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700184 .andReturn(latch).once();
185 PowerMock.replay(LeaderLatch.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700186
Ray Milkey269ffb92014-04-03 14:43:30 -0700187 String controllerId = "controller2013";
188 registry.registerController(controllerId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700189
Ray Milkey269ffb92014-04-03 14:43:30 -0700190 LoggingCallback callback = new LoggingCallback(1);
191 long dpidToRequest = 2000L;
Naoki Shiotad00accf2013-06-25 14:40:37 -0700192
Ray Milkey269ffb92014-04-03 14:43:30 -0700193 try {
194 registry.requestControl(dpidToRequest, callback);
195 } catch (RegistryException e) {
196 e.printStackTrace();
197 fail(e.getMessage());
198 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700199
Ray Milkey269ffb92014-04-03 14:43:30 -0700200 EasyMock.verify(latch);
201 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700202
Ray Milkey269ffb92014-04-03 14:43:30 -0700203 /**
204 * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
205 * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
206 * {@link LeaderLatch} object and verify latch is correctly set up.
207 *
208 * @throws Exception
209 */
210 @Test
211 public void testReleaseControl() throws Exception {
212 // Mock of LeaderLatch
213 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
214 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
215 EasyMock.expectLastCall().once();
216 latch.start();
217 EasyMock.expectLastCall().once();
218 latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
219 EasyMock.expectLastCall().once();
220 latch.close();
221 EasyMock.expectLastCall().once();
222 EasyMock.replay(latch);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700223
Ray Milkey269ffb92014-04-03 14:43:30 -0700224 PowerMock.expectNew(LeaderLatch.class,
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700225 EasyMock.anyObject(CuratorFramework.class),
226 EasyMock.anyObject(String.class),
227 EasyMock.anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700228 .andReturn(latch).once();
229 PowerMock.replay(LeaderLatch.class);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700230
Ray Milkey269ffb92014-04-03 14:43:30 -0700231 String controllerId = "controller2013";
232 registry.registerController(controllerId);
Naoki Shiotad00accf2013-06-25 14:40:37 -0700233
Ray Milkey269ffb92014-04-03 14:43:30 -0700234 long dpidToRequest = 2000L;
235 LoggingCallback callback = new LoggingCallback(1);
236
237 registry.requestControl(dpidToRequest, callback);
238 registry.releaseControl(dpidToRequest);
239
240 EasyMock.verify(latch);
241 }
242
243 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700244 * Test if {@link ZookeeperRegistry#hasControl(long)} returns
245 * correct status whether controller has control of specific switch.
Ray Milkey269ffb92014-04-03 14:43:30 -0700246 *
247 * @throws Exception
248 */
249 @Test
250 public void testHasControl() throws Exception {
251 // Mock of LeaderLatch
252 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
253 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
254 EasyMock.expectLastCall().once();
255 latch.start();
256 EasyMock.expectLastCall().once();
257 EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
258 latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
259 EasyMock.expectLastCall().once();
260 latch.close();
261 EasyMock.expectLastCall().once();
262 EasyMock.replay(latch);
263
264 PowerMock.expectNew(LeaderLatch.class,
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700265 EasyMock.anyObject(CuratorFramework.class),
266 EasyMock.anyObject(String.class),
267 EasyMock.anyObject(String.class))
Ray Milkey269ffb92014-04-03 14:43:30 -0700268 .andReturn(latch);
269 PowerMock.replay(LeaderLatch.class);
270
271 String controllerId = "controller2013";
272 registry.registerController(controllerId);
273
274 long dpidToRequest = 2000L;
275 LoggingCallback callback = new LoggingCallback(2);
276
277 // Test before request control
278 assertFalse(registry.hasControl(dpidToRequest));
279
280 registry.requestControl(dpidToRequest, callback);
281
282 // Test after request control
283 assertTrue(registry.hasControl(dpidToRequest));
284
285 registry.releaseControl(dpidToRequest);
286
287 // Test after release control
288 assertFalse(registry.hasControl(dpidToRequest));
289
290 EasyMock.verify(latch);
291 }
292
293 /**
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700294 * Test if {@link ZookeeperRegistry#getControllerForSwitch(long)}
295 * correctly returns controller ID of specific switch.
296 * Relation between controllers and switches are defined by
297 * {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
Ray Milkey269ffb92014-04-03 14:43:30 -0700298 *
299 * @throws Throwable
300 */
301 @Test
302 public void testGetControllerForSwitch() throws Throwable {
303 long dpidRegistered = 1000L;
304 long dpidNotRegistered = 2000L;
305
306 setPathChildrenCache();
307
308 String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
309 assertEquals("controller1", controllerForSw);
310
311 controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
312 assertEquals(null, controllerForSw);
313 }
314
315 /**
316 * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
317 * switches controlled by a controller.
318 *
319 * @throws Exception
320 */
321 // TODO: Test after getSwitchesControlledByController() is implemented.
322 @Ignore
323 @Test
324 public void testGetSwitchesControlledByController() throws Exception {
325 String controllerIdRegistered = "controller1";
326 String dpidRegistered = HexString.toHexString(1000L);
327 String controllerIdNotRegistered = CONTROLLER_ID;
328
329 Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
330 assertNotNull(switches);
331 assertTrue(switches.contains(dpidRegistered));
332
333 switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
334 assertNotNull(switches);
335 assertEquals(0, switches.size());
336 }
337
338 /**
339 * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
340 * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
341 *
342 * @throws Exception
343 */
344 @Test
345 public void testGetAllSwitches() throws Exception {
346 String[] dpids = {
347 HexString.toHexString(1000L),
348 HexString.toHexString(1001L),
349 HexString.toHexString(1002L),
350 };
351
352 setPathChildrenCache();
353
354 Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
355 assertNotNull(switches);
356 assertEquals(dpids.length, switches.size());
357 for (String dpid : dpids) {
358 assertTrue(switches.keySet().contains(dpid));
359 }
360 }
361
362 /**
363 * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
364 */
365 @Test
366 public void testAllocateUniqueIdBlock() {
367 // Number of blocks to be verified that any of them has unique block
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700368 final int numBlocks = 100;
369 ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(numBlocks);
Ray Milkey269ffb92014-04-03 14:43:30 -0700370
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700371 for (int i = 0; i < numBlocks; ++i) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700372 IdBlock block = registry.allocateUniqueIdBlock();
373 assertNotNull(block);
374 blocks.add(block);
375 }
376
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700377 for (int i = 0; i < numBlocks; ++i) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700378 IdBlock block1 = blocks.get(i);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700379 for (int j = i + 1; j < numBlocks; ++j) {
Ray Milkey269ffb92014-04-03 14:43:30 -0700380 IdBlock block2 = blocks.get(j);
381 IdBlock lower, higher;
382
383 if (block1.getStart() < block2.getStart()) {
384 lower = block1;
385 higher = block2;
386 } else {
387 lower = block2;
388 higher = block1;
389 }
390
391 assertTrue(lower.getSize() > 0L);
392 assertTrue(higher.getSize() > 0L);
393 assertTrue(lower.getEnd() <= higher.getStart());
394 }
395 }
396 }
397
398
399 //-------------------------- Creation of mock objects --------------------------
400
401 /**
402 * Create mock {@link CuratorFramework} object with initial value below.<br>
403 * [Ctrl ID] : [DPID]<br>
404 * controller1 : 1000<br>
405 * controller2 : 1001<br>
406 * controller2 : 1002<br>
407 * controller2013 : nothing
408 *
409 * @return Created mock object
410 * @throws Exception
411 */
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700412 @SuppressWarnings({"serial", "unchecked" })
Ray Milkey269ffb92014-04-03 14:43:30 -0700413 private CuratorFramework createCuratorFrameworkMock() throws Exception {
414 // Mock of AtomicValue
415 AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
416 EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
417 EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
418 private long value = 0;
419
420 @Override
421 public Long answer() throws Throwable {
422 value += ID_BLOCK_SIZE;
423 return value;
424 }
425 }).anyTimes();
426 EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
427 private long value = ID_BLOCK_SIZE;
428
429 @Override
430 public Long answer() throws Throwable {
431 value += ID_BLOCK_SIZE;
432 return value;
433 }
434 }).anyTimes();
435 EasyMock.replay(atomicValue);
436
437 // Mock DistributedAtomicLong
438 DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
439 EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
440 EasyMock.replay(daLong);
441 PowerMock.expectNew(DistributedAtomicLong.class,
442 new Class<?>[]{CuratorFramework.class, String.class, RetryPolicy.class},
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700443 EasyMock.anyObject(CuratorFramework.class),
444 EasyMock.anyObject(String.class),
445 EasyMock.anyObject(RetryPolicy.class)).
Ray Milkey269ffb92014-04-03 14:43:30 -0700446 andReturn(daLong).anyTimes();
447 PowerMock.replay(DistributedAtomicLong.class);
448
449 // Mock ListenerContainer
450 ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
451 listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
452 EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
453 @Override
454 public Object answer() throws Throwable {
455 pathChildrenCacheListener = (PathChildrenCacheListener) EasyMock.getCurrentArguments()[0];
456 return null;
457 }
458 }).once();
459 EasyMock.replay(listenerContainer);
460
461 // Mock PathChildrenCache
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700462 PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(
463 CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
464 PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1",
465 new String[] {HexString.toHexString(1000L)}, listenerContainer);
466 PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2",
467 new String[] {
468 HexString.toHexString(1001L), HexString.toHexString(1002L)},
469 listenerContainer);
Ray Milkey269ffb92014-04-03 14:43:30 -0700470
471 // Mock PathChildrenCache constructor
472 PowerMock.expectNew(PathChildrenCache.class,
473 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
474 andReturn(pathChildrenCacheMain).once();
475 PowerMock.expectNew(PathChildrenCache.class,
476 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
477 andReturn(pathChildrenCache1).once();
478 PowerMock.expectNew(PathChildrenCache.class,
479 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
480 andReturn(pathChildrenCache2).anyTimes();
481 PowerMock.replay(PathChildrenCache.class);
482
483 // Mock ServiceCache
484 ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
485 serviceCache.start();
486 EasyMock.expectLastCall().once();
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700487 EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService>>() { {
Ray Milkey269ffb92014-04-03 14:43:30 -0700488 add(createServiceInstanceMock("controller1"));
489 add(createServiceInstanceMock("controller2"));
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700490 } }).anyTimes();
Ray Milkey269ffb92014-04-03 14:43:30 -0700491 EasyMock.replay(serviceCache);
492
493 // Mock ServiceCacheBuilder
494 ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700495 EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class)))
496 .andReturn(serviceCacheBuilder).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700497 EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
498 EasyMock.replay(serviceCacheBuilder);
499
500 // Mock ServiceDiscovery
501 ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
502 serviceDiscovery.start();
503 EasyMock.expectLastCall().once();
504 EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
505 serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
506 EasyMock.expectLastCall().once();
507 EasyMock.replay(serviceDiscovery);
508
509 // Mock CuratorFramework
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700510 CuratorFramework mockClient = EasyMock.createMock(CuratorFramework.class);
511 mockClient.start();
Ray Milkey269ffb92014-04-03 14:43:30 -0700512 EasyMock.expectLastCall().once();
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700513 EasyMock.expect(mockClient.usingNamespace(EasyMock.anyObject(String.class))).andReturn(mockClient);
514 EasyMock.replay(mockClient);
Ray Milkey269ffb92014-04-03 14:43:30 -0700515
516 // Mock ServiceDiscoveryBuilder
517 ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700518 EasyMock.expect(builder.client(mockClient)).andReturn(builder).once();
Ray Milkey269ffb92014-04-03 14:43:30 -0700519 EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
520 EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
521 EasyMock.replay(builder);
522
523 PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
524 EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
525 PowerMock.replay(ServiceDiscoveryBuilder.class);
526
Yuta HIGUCHI44a0b352014-05-14 21:32:48 -0700527 return mockClient;
Ray Milkey269ffb92014-04-03 14:43:30 -0700528 }
529
530 /**
531 * Create mock {@link ServiceInstance} object using given controller ID.
532 *
533 * @param controllerId Controller ID to represent instance's payload (ControllerService).
534 * @return Mock ServiceInstance object
535 */
536 private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
537 ControllerService controllerService = EasyMock.createMock(ControllerService.class);
538 EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
539 EasyMock.replay(controllerService);
540
541 @SuppressWarnings("unchecked")
542 ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
543 EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
544 EasyMock.replay(serviceInstance);
545
546 return serviceInstance;
547 }
548
549 /**
550 * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
551 *
552 * @param controllerId Controller ID to represent current data.
553 * @param paths List of HexString indicating switch's DPID.
554 * @param listener Callback object to be set as Listenable.
555 * @return Mock PathChildrenCache object
556 * @throws Exception
557 */
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700558 private PathChildrenCache createPathChildrenCacheMock(
559 final String controllerId,
560 final String[] paths,
561 ListenerContainer<PathChildrenCacheListener> listener)
562 throws Exception {
Ray Milkey269ffb92014-04-03 14:43:30 -0700563 PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
564
565 EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
566
567 pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
568 EasyMock.expectLastCall().anyTimes();
569
570 List<ChildData> childs = new ArrayList<ChildData>();
571 for (String path : paths) {
572 childs.add(createChildDataMockForCurrentData(controllerId, path));
573 }
574 EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
575
576 pathChildrenCache.rebuild();
577 EasyMock.expectLastCall().anyTimes();
578
579 EasyMock.replay(pathChildrenCache);
580
581 return pathChildrenCache;
582 }
583
584 /**
585 * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
586 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
587 *
588 * @param controllerId Controller ID
589 * @param path HexString indicating switch's DPID
590 * @return Mock ChildData object
591 */
592 private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
593 ChildData data = EasyMock.createMock(ChildData.class);
594 EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
595 EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
596 EasyMock.replay(data);
597
598 return data;
599 }
600
601 /**
602 * Inject relations between controllers and switches using callback object.
603 *
604 * @throws Exception
605 */
606 private void setPathChildrenCache() throws Exception {
Yuta HIGUCHI91a8f502014-06-17 10:15:29 -0700607 pathChildrenCacheListener.childEvent(
608 client,
609 createChildrenCacheEventMock("controller1", HexString.toHexString(1000L),
610 PathChildrenCacheEvent.Type.CHILD_ADDED));
611 pathChildrenCacheListener.childEvent(
612 client,
613 createChildrenCacheEventMock("controller2", HexString.toHexString(1001L),
614 PathChildrenCacheEvent.Type.CHILD_ADDED));
615 pathChildrenCacheListener.childEvent(
616 client,
617 createChildrenCacheEventMock("controller2", HexString.toHexString(1002L),
618 PathChildrenCacheEvent.Type.CHILD_ADDED));
Ray Milkey269ffb92014-04-03 14:43:30 -0700619 }
620
621 /**
622 * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
623 *
624 * @param controllerId Controller ID.
625 * @param path HexString of DPID.
626 * @param type Event type to be set to mock object.
627 * @return Mock PathChildrenCacheEvent object
628 */
629 private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
630 PathChildrenCacheEvent.Type type) {
631 PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
632 ChildData data = EasyMock.createMock(ChildData.class);
633
634 EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
635 EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
636 EasyMock.replay(data);
637
638 EasyMock.expect(event.getType()).andReturn(type).anyTimes();
639 EasyMock.expect(event.getData()).andReturn(data).anyTimes();
640 EasyMock.replay(event);
641
642 return event;
643 }
Naoki Shiotad00accf2013-06-25 14:40:37 -0700644}