blob: f55766350acc4335fc2373588fa09f2643fb8593 [file] [log] [blame]
Naoki Shiotad00accf2013-06-25 14:40:37 -07001package net.onrc.onos.registry.controller;
2
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;
10import net.onrc.onos.registry.controller.StandaloneRegistryTest.LoggingCallback;
11import net.onrc.onos.registry.controller.ZookeeperRegistry.SwitchLeaderListener;
12
13import org.easymock.EasyMock;
14import org.easymock.IAnswer;
15import org.junit.After;
16import org.junit.Before;
17import org.junit.Ignore;
18import org.junit.Test;
19import org.junit.runner.RunWith;
20import org.openflow.util.HexString;
21import org.powermock.api.easymock.PowerMock;
22import org.powermock.core.classloader.annotations.PrepareForTest;
23import org.powermock.modules.junit4.PowerMockRunner;
24
25import com.netflix.curator.RetryPolicy;
26import com.netflix.curator.framework.CuratorFramework;
27import com.netflix.curator.framework.CuratorFrameworkFactory;
28import com.netflix.curator.framework.listen.ListenerContainer;
29import com.netflix.curator.framework.recipes.atomic.AtomicValue;
30import com.netflix.curator.framework.recipes.atomic.DistributedAtomicLong;
31import com.netflix.curator.framework.recipes.cache.ChildData;
32import com.netflix.curator.framework.recipes.cache.PathChildrenCache;
33import com.netflix.curator.framework.recipes.cache.PathChildrenCacheEvent;
34import com.netflix.curator.framework.recipes.cache.PathChildrenCacheListener;
35import com.netflix.curator.framework.recipes.cache.PathChildrenCache.StartMode;
36import com.netflix.curator.framework.recipes.leader.LeaderLatch;
37import com.netflix.curator.x.discovery.ServiceCache;
38import com.netflix.curator.x.discovery.ServiceCacheBuilder;
39import com.netflix.curator.x.discovery.ServiceDiscovery;
40import com.netflix.curator.x.discovery.ServiceDiscoveryBuilder;
41import com.netflix.curator.x.discovery.ServiceInstance;
42
43/**
44 * Unit test for ZookeeperRegistry.
45 * NOTE: FloodlightTestCase conflicts with PowerMock. If FloodLight-related methods need to be tested,
46 * implement another test class to test them.
47 * @author Naoki Shiota
48 *
49 */
50@RunWith(PowerMockRunner.class)
51@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
52 ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
53 ZookeeperRegistry.SwitchPathCacheListener.class})
54public class ZookeeperRegistryTest extends FloodlightTestCase {
55 private final static Long ID_BLOCK_SIZE = 0x100000000L;
56
57 protected ZookeeperRegistry registry;
58 protected CuratorFramework client;
59
60 protected PathChildrenCacheListener pathChildrenCacheListener;
61 protected final String CONTROLLER_ID = "controller2013";
62
63 /**
64 * Initialize ZookeeperRegistry Object and inject initial value with init() method.
65 * This setup code also tests init() method itself.
66 */
67 @Before
68 public void setUp() throws Exception {
69 super.setUp();
70
71 pathChildrenCacheListener = null;
72
73 // Mock of CuratorFramework
74 client = createCuratorFrameworkMock();
75
76 // Mock of CuratorFrameworkFactory
77 PowerMock.mockStatic(CuratorFrameworkFactory.class);
78 EasyMock.expect(CuratorFrameworkFactory.newClient((String)EasyMock.anyObject(),
79 EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy)EasyMock.anyObject())).andReturn(client);
80 PowerMock.replay(CuratorFrameworkFactory.class);
81
82 FloodlightModuleContext fmc = new FloodlightModuleContext();
83 registry = new ZookeeperRegistry();
84 fmc.addService(ZookeeperRegistry.class, registry);
85
86 registry.init(fmc);
87
88 PowerMock.verify(client, CuratorFrameworkFactory.class);
89 }
90
91 /**
92 * Clean up member variables (empty for now).
93 */
94 @After
95 public void tearDown() throws Exception {
96 super.tearDown();
97 }
98
99 /**
100 * Test if registerController() method can go through without exception.
101 * (Exceptions are usually out of test target, but registerController() throws an exception in case of invalid registration.)
102 */
103 @Test
104 public void testRegisterController() {
105 String controllerIdToRegister = "controller2013";
106
107 try {
108 registry.registerController(controllerIdToRegister);
109 } catch (RegistryException e) {
110 e.printStackTrace();
111 fail(e.getMessage());
112 }
113 }
114
115 /**
116 * Test if getControllerId() correctly returns registered ID.
117 * @throws Exception
118 */
119 @Test
120 public void testGetControllerId() throws Exception {
121 String controllerIdToRegister = "controller1";
122
123 // try before controller is registered
124 String controllerId = registry.getControllerId();
125 assertNull(controllerId);
126
127 // register
128 registry.registerController(controllerIdToRegister);
129
130 // call getControllerId and verify
131 controllerId = registry.getControllerId();
132 assertNotNull(controllerId);
133 assertEquals(controllerIdToRegister, controllerId);
134 }
135
136 /**
137 * Test if getAllControllers() returns all controllers.
138 * Controllers are injected while setup. See createCuratorFrameworkMock() to what controllers
139 * are injected using ServiceCache Mock.
140 * @throws Exception
141 */
142 @Test
143 public void testGetAllControllers() throws Exception {
144 String controllerIdRegistered = "controller1";
145 String controllerIdNotRegistered = "controller2013";
146
147 // Test registered controller
148 try {
149 Collection<String> ctrls = registry.getAllControllers();
150 assertTrue(ctrls.contains(controllerIdRegistered));
151 assertFalse(ctrls.contains(controllerIdNotRegistered));
152 } catch (RegistryException e) {
153 e.printStackTrace();
154 fail(e.getMessage());
155 }
156 }
157
158 /**
159 * Test if requestControl() correctly take control of specific switch.
160 * Because requestControl() doesn't return values, inject mock LeaderLatch object and verify latch is correctly set up.
161 * @throws Exception
162 */
163 @Test
164 public void testRequestControl() throws Exception {
165 // Mock of LeaderLatch
166 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
167 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
168 EasyMock.expectLastCall().once();
169 latch.start();
170 EasyMock.expectLastCall().once();
171 EasyMock.replay(latch);
172
173 PowerMock.expectNew(LeaderLatch.class,
174 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
175 .andReturn(latch);
176 PowerMock.replay(LeaderLatch.class);
177
178 String controllerId = "controller2013";
179 registry.registerController(controllerId);
180
181 LoggingCallback callback = new LoggingCallback(1);
182 long dpidToRequest = 2000L;
183
184 try {
185 registry.requestControl(dpidToRequest, callback);
186 } catch (RegistryException e) {
187 e.printStackTrace();
188 fail(e.getMessage());
189 }
190
191 EasyMock.verify(latch);
192 }
193
194 /**
195 * Test if releaseControl() correctly release control of specific switch.
196 * Because releaseControl() doesn't return values, inject mock LeaderLatch object and verify latch is correctly set up.
197 * @throws Exception
198 */
199 @Test
200 public void testReleaseControl() throws Exception {
201 // Mock of LeaderLatch
202 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
203 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
204 EasyMock.expectLastCall().once();
205 latch.start();
206 EasyMock.expectLastCall().once();
207 latch.removeAllListeners();
208 EasyMock.expectLastCall().once();
209 latch.close();
210 EasyMock.expectLastCall().once();
211 EasyMock.replay(latch);
212
213 PowerMock.expectNew(LeaderLatch.class,
214 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
215 .andReturn(latch);
216 PowerMock.replay(LeaderLatch.class);
217
218 String controllerId = "controller2013";
219 registry.registerController(controllerId);
220
221 long dpidToRequest = 1000L;
222 LoggingCallback callback = new LoggingCallback(1);
223
224 // to request and wait to take control
225 registry.requestControl(dpidToRequest, callback);
226 registry.releaseControl(dpidToRequest);
227
228 // verify
229 EasyMock.verify(latch);
230 }
231
232 /**
233 * Test if hasControl() returns correct status whether controller has control of specific switch.
234 * @throws Exception
235 */
236 @Test
237 public void testHasControl() throws Exception {
238 // Mock of LeaderLatch
239 LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
240 latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
241 EasyMock.expectLastCall().once();
242 latch.start();
243 EasyMock.expectLastCall().once();
244 EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
245 latch.removeAllListeners();
246 EasyMock.expectLastCall().once();
247 latch.close();
248 EasyMock.expectLastCall().once();
249 EasyMock.replay(latch);
250
251 PowerMock.expectNew(LeaderLatch.class,
252 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
253 .andReturn(latch);
254 PowerMock.replay(LeaderLatch.class);
255
256 String controllerId = "controller2013";
257 registry.registerController(controllerId);
258
259 long dpidToRequest = 2000L;
260 LoggingCallback callback = new LoggingCallback(2);
261
262 // Test before request control
263 assertFalse(registry.hasControl(dpidToRequest));
264
265 registry.requestControl(dpidToRequest, callback);
266
267 // Test after request control
268 assertTrue(registry.hasControl(dpidToRequest));
269
270 registry.releaseControl(dpidToRequest);
271
272 // Test after release control
273 assertFalse(registry.hasControl(dpidToRequest));
274
275 EasyMock.verify(latch);
276 }
277
278 /**
279 * Test if getControllerForSwitch() correctly returns controller ID of specific switch.
280 * Relation between controllers and switches are defined by setPathChildrenCache() function.
281 * @throws Throwable
282 */
283 @Test
284 public void testGetControllerForSwitch() throws Throwable {
285 long dpidRegistered = 1000L;
286 long dpidNotRegistered = 2000L;
287
288 setPathChildrenCache();
289
290 String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
291 assertEquals("controller1",controllerForSw);
292
293 controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
294 assertEquals(null, controllerForSw);
295 }
296
297 /**
298 * Test if getSwitchesControlledByController() returns correct list of switches controlled by
299 * a controller.
300 * @throws Exception
301 */
302 // TODO: Test after implementation of getSwitch() is done.
303 @Ignore @Test
304 public void testGetSwitchesControlledByController() throws Exception {
305 String controllerIdRegistered = "controller1";
306 String dpidRegistered = HexString.toHexString(1000L);
307 String controllerIdNotRegistered = CONTROLLER_ID;
308
309 Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
310 assertNotNull(switches);
311 assertTrue(switches.contains(dpidRegistered));
312
313 switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
314 assertNotNull(switches);
315 assertEquals(0, switches.size());
316 }
317
318 /**
319 * Test if getAllSwitches() returns correct list of all switches.
320 * Switches are injected in setPathChildrenCache() function.
321 * @throws Exception
322 */
323 @Test
324 public void testGetAllSwitches() throws Exception {
325 String [] dpids = {
326 HexString.toHexString(1000L),
327 HexString.toHexString(1001L),
328 HexString.toHexString(1002L),
329 };
330
331 setPathChildrenCache();
332
333 Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
334 assertNotNull(switches);
335 assertEquals(dpids.length, switches.size());
336 for(String dpid : dpids) {
337 assertTrue(switches.keySet().contains(dpid));
338 }
339 }
340
341 /**
342 * Test if allocateUniqueIdBlock() can assign IdBlock without duplication.
343 */
344 @Test
345 public void testAllocateUniqueIdBlock() {
346 // Number of blocks to be verified that any of them has unique block
347 final int NUM_BLOCKS = 100;
348 ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
349
350 for(int i = 0; i < NUM_BLOCKS; ++i) {
351 IdBlock block = registry.allocateUniqueIdBlock();
352 assertNotNull(block);
353 blocks.add(block);
354 }
355
356 for(int i = 0; i < NUM_BLOCKS; ++i) {
357 IdBlock block1 = blocks.get(i);
358 for(int j = i + 1; j < NUM_BLOCKS; ++j) {
359 IdBlock block2 = blocks.get(j);
360 IdBlock lower,higher;
361
362 if(block1.getStart() < block2.getStart()) {
363 lower = block1;
364 higher = block2;
365 } else {
366 lower = block2;
367 higher = block1;
368 }
369
370 assertTrue(lower.getSize() > 0L);
371 assertTrue(higher.getSize() > 0L);
372 assertTrue(lower.getEnd() <= higher.getStart());
373 }
374 }
375 }
376
377 /**
378 * Create mock CuratorFramework object with initial value below.
379 * [Ctrl ID] : [DPID]
380 * controller1 : 1000
381 * controller2 : 1001
382 * controller2 : 1002
383 * controller2013 : nothing
384 * @return Created mock object
385 * @throws Exception
386 */
387 @SuppressWarnings("serial")
388 private CuratorFramework createCuratorFrameworkMock() throws Exception {
389 // Mock of AtomicValue
390 @SuppressWarnings("unchecked")
391 AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
392 EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
393 EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
394 private long value = 0;
395 @Override
396 public Long answer() throws Throwable {
397 value += ID_BLOCK_SIZE;
398 return value;
399 }
400 }).anyTimes();
401 EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
402 private long value = ID_BLOCK_SIZE;
403 @Override
404 public Long answer() throws Throwable {
405 value += ID_BLOCK_SIZE;
406 return value;
407 }
408 }).anyTimes();
409 EasyMock.replay(atomicValue);
410
411 // Mock of DistributedAtomicLong
412 DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
413 EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
414 EasyMock.replay(daLong);
415 PowerMock.expectNew(DistributedAtomicLong.class,
416 new Class<?> [] {CuratorFramework.class, String.class, RetryPolicy.class},
417 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(RetryPolicy.class)).
418 andReturn(daLong).anyTimes();
419 PowerMock.replay(DistributedAtomicLong.class);
420
421 // Mock of ListenerContainer
422 @SuppressWarnings("unchecked")
423 ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
424 listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
425 EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
426 @Override
427 public Object answer() throws Throwable {
428 pathChildrenCacheListener = (PathChildrenCacheListener)EasyMock.getCurrentArguments()[0];
429 return null;
430 }
431 }).once();
432 EasyMock.replay(listenerContainer);
433
434 // Mock of PathChildrenCache
435 PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
436 PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1", new String[] {HexString.toHexString(1000L)}, listenerContainer);
437 PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2", new String[] {
438 HexString.toHexString(1001L), HexString.toHexString(1002L) },listenerContainer);
439
440 // Mock of PathChildrenCache constructor
441 PowerMock.expectNew(PathChildrenCache.class,
442 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
443 andReturn(pathChildrenCacheMain).once();
444 PowerMock.expectNew(PathChildrenCache.class,
445 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
446 andReturn(pathChildrenCache1).once();
447 PowerMock.expectNew(PathChildrenCache.class,
448 EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
449 andReturn(pathChildrenCache2).anyTimes();
450 PowerMock.replay(PathChildrenCache.class);
451
452 // Mock of ServiceCache
453 @SuppressWarnings("unchecked")
454 ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
455 serviceCache.start();
456 EasyMock.expectLastCall().once();
457 EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService> > () {{
458 add(createServiceInstanceMock("controller1"));
459 add(createServiceInstanceMock("controller2"));
460 }}).anyTimes();
461 EasyMock.replay(serviceCache);
462
463 // Mock of ServiceCacheBuilder
464 @SuppressWarnings("unchecked")
465 ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
466 EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class))).andReturn(serviceCacheBuilder).once();
467 EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
468 EasyMock.replay(serviceCacheBuilder);
469
470 // Mock of ServiceDiscovery
471 @SuppressWarnings("unchecked")
472 ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
473 serviceDiscovery.start();
474 EasyMock.expectLastCall().once();
475 EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
476 serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
477 EasyMock.expectLastCall().once();
478 EasyMock.replay(serviceDiscovery);
479
480 // Mock of CuratorFramework
481 CuratorFramework client = EasyMock.createMock(CuratorFramework.class);
482 client.start();
483 EasyMock.expectLastCall().once();
484 EasyMock.expect(client.usingNamespace(EasyMock.anyObject(String.class))).andReturn(client);
485 EasyMock.replay(client);
486
487 // Mock of ServiceDiscoveryBuilder
488 @SuppressWarnings("unchecked")
489 ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
490 EasyMock.expect(builder.client(client)).andReturn(builder).once();
491 EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
492 EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
493 EasyMock.replay(builder);
494
495 PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
496 EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
497 PowerMock.replay(ServiceDiscoveryBuilder.class);
498
499 return client;
500 }
501
502 /**
503 * Create mock ServiceInstance object using given controller ID.
504 * @param controllerId Controller ID to represent instance's payload (ControllerSeervice).
505 * @return
506 */
507 private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
508 ControllerService controllerService = EasyMock.createMock(ControllerService.class);
509 EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
510 EasyMock.replay(controllerService);
511
512 @SuppressWarnings("unchecked")
513 ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
514 EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
515 EasyMock.replay(serviceInstance);
516
517 return serviceInstance;
518 }
519
520 /**
521 * Create mock PathChildrenCache using given controller ID and DPIDs.
522 * @param controllerId Controller ID to represent current data.
523 * @param paths List of HexString indicating switch's DPID.
524 * @param listener Callback object to be set as Listenable.
525 * @return
526 * @throws Exception
527 */
528 private PathChildrenCache createPathChildrenCacheMock(final String controllerId, final String [] paths,
529 ListenerContainer<PathChildrenCacheListener> listener) throws Exception {
530 PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
531
532 EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
533
534 pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
535 EasyMock.expectLastCall().anyTimes();
536
537 List<ChildData> childs = new ArrayList<ChildData>();
538 for(String path : paths) {
539 childs.add(createChildDataMockForCurrentData(controllerId,path));
540 }
541 EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
542
543 pathChildrenCache.rebuild();
544 EasyMock.expectLastCall().anyTimes();
545
546 EasyMock.replay(pathChildrenCache);
547
548 return pathChildrenCache;
549 }
550
551 /**
552 * Create mock ChildData for {@link PathChildrenCache#getCurrentData()} return value.
553 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
554 * @param controllerId Controller ID
555 * @param path HexString indicating switch's DPID
556 * @return
557 */
558 private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
559 ChildData data = EasyMock.createMock(ChildData.class);
560 EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
561 EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
562 EasyMock.replay(data);
563
564 return data;
565 }
566
567 /**
568 * Inject relations between controllers and switches using callback object.
569 * @throws Exception
570 */
571 private void setPathChildrenCache() throws Exception {
572 pathChildrenCacheListener.childEvent(client,
573 createChildDataEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
574 pathChildrenCacheListener.childEvent(client,
575 createChildDataEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
576 pathChildrenCacheListener.childEvent(client,
577 createChildDataEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
578 }
579
580 /**
581 * Create mock ChildDataEvent object using given controller ID and DPID.
582 * @param controllerId Controller ID.
583 * @param path HexString of DPID.
584 * @param type Event type to be set to mock object.
585 * @return
586 */
587 private PathChildrenCacheEvent createChildDataEventMock(String controllerId, String path,
588 PathChildrenCacheEvent.Type type) {
589 PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
590 ChildData data = EasyMock.createMock(ChildData.class);
591
592 EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
593 EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
594 EasyMock.replay(data);
595
596 EasyMock.expect(event.getType()).andReturn(type).anyTimes();
597 EasyMock.expect(event.getData()).andReturn(data).anyTimes();
598 EasyMock.replay(event);
599
600 return event;
601 }
602}