package net.onrc.onos.core.registry;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.test.FloodlightTestCase;
import net.onrc.onos.core.registry.ControllerRegistryEntry;
import net.onrc.onos.core.registry.ControllerService;
import net.onrc.onos.core.registry.IdBlock;
import net.onrc.onos.core.registry.RegistryException;
import net.onrc.onos.core.registry.ZookeeperRegistry;
import net.onrc.onos.core.registry.StandaloneRegistryTest.LoggingCallback;
import net.onrc.onos.core.registry.ZookeeperRegistry.SwitchLeaderListener;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.listen.ListenerContainer;
import org.apache.curator.framework.recipes.atomic.AtomicValue;
import org.apache.curator.framework.recipes.atomic.DistributedAtomicLong;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCache.StartMode;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.framework.recipes.leader.LeaderLatch;
import org.apache.curator.x.discovery.ServiceCache;
import org.apache.curator.x.discovery.ServiceCacheBuilder;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openflow.util.HexString;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * Unit test for {@link ZookeeperRegistry}.
 * NOTE: {@link FloodlightTestCase} conflicts with PowerMock. If FloodLight-related methods need to be tested,
 *       implement another test class to test them.
 * @author Naoki Shiota
 *
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest({ZookeeperRegistry.class, CuratorFramework.class, CuratorFrameworkFactory.class,
	ServiceDiscoveryBuilder.class, ServiceDiscovery.class, ServiceCache.class, PathChildrenCache.class,
	ZookeeperRegistry.SwitchPathCacheListener.class})
public class ZookeeperRegistryTest extends FloodlightTestCase {
	private final static Long ID_BLOCK_SIZE = 0x100000000L;
	
	protected ZookeeperRegistry registry;
	protected CuratorFramework client;
	
	protected PathChildrenCacheListener pathChildrenCacheListener;
	protected final String CONTROLLER_ID = "controller2013";

	/**
	 * Initialize {@link ZookeeperRegistry} Object and inject initial value with {@link ZookeeperRegistry#init(FloodlightModuleContext)} method.
	 * This setup code also tests {@link ZookeeperRegistry#init(FloodlightModuleContext)} method itself.
	 */
	@Before
	public void setUp() throws Exception {
		super.setUp();
		
		pathChildrenCacheListener = null;
		
		// Mock of CuratorFramework
		client = createCuratorFrameworkMock();
		
		// Mock of CuratorFrameworkFactory
		PowerMock.mockStatic(CuratorFrameworkFactory.class);
		EasyMock.expect(CuratorFrameworkFactory.newClient((String)EasyMock.anyObject(),
				EasyMock.anyInt(), EasyMock.anyInt(), (RetryPolicy)EasyMock.anyObject())).andReturn(client);
		PowerMock.replay(CuratorFrameworkFactory.class);

		FloodlightModuleContext fmc = new FloodlightModuleContext();
		registry = new ZookeeperRegistry();
		fmc.addService(ZookeeperRegistry.class, registry);
		
		registry.init(fmc);
		
		PowerMock.verify(client, CuratorFrameworkFactory.class);
	}

	/**
	 * Clean up member variables (empty for now).
	 */
	@After
	public void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * Test if {@link ZookeeperRegistry#registerController(String)} method can go through without exception.
	 * (Exceptions are usually out of test target, but {@link ZookeeperRegistry#registerController(String)} throws an exception in case of invalid registration.)
	 */
	@Test
	public void testRegisterController() {
		String controllerIdToRegister = "controller2013";
		
		try {
			registry.registerController(controllerIdToRegister);
		} catch (RegistryException e) {
			e.printStackTrace();
			fail(e.getMessage());
		}
	}

	/**
	 * Test if {@link ZookeeperRegistry#getControllerId()} correctly returns registered ID.
	 * @throws Exception
	 */
	@Test
	public void testGetControllerId() throws Exception {
		String controllerIdToRegister = "controller1";
		
		// try before controller is registered
		String controllerId = registry.getControllerId();
		assertNull(controllerId);
		
		// register
		registry.registerController(controllerIdToRegister);
	
		// call getControllerId and verify
		controllerId = registry.getControllerId();
		assertNotNull(controllerId);
		assertEquals(controllerIdToRegister, controllerId);
	}

	/**
	 * Test if {@link ZookeeperRegistry#getAllControllers()} returns all controllers.
	 * Controllers to be returned are injected while setup. See {@link ZookeeperRegistryTest#createCuratorFrameworkMock()}
	 * to what controllers are injected using mock {@link ServiceCache}.
	 * @throws Exception
	 */
	@Test
	public void testGetAllControllers() throws Exception {
		String controllerIdRegistered = "controller1";
		String controllerIdNotRegistered = "controller2013";

		try {
			Collection<String> ctrls = registry.getAllControllers();
			assertTrue(ctrls.contains(controllerIdRegistered));
			assertFalse(ctrls.contains(controllerIdNotRegistered));
		} catch (RegistryException e) {
			e.printStackTrace();
			fail(e.getMessage());
		}
	}

	/**
	 * Test if {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback)}
	 * correctly take control of specific switch. Because {@link ZookeeperRegistry#requestControl(long, net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback)}
	 * doesn't return values, inject mock {@link LeaderLatch} object and verify latch is correctly set up.
	 * @throws Exception
	 */
	@Test
	public void testRequestControl() throws Exception {
		// Mock LeaderLatch
		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
		EasyMock.expectLastCall().once();
		latch.start();
		EasyMock.expectLastCall().once();
		EasyMock.replay(latch);
		
		PowerMock.expectNew(LeaderLatch.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
				.andReturn(latch).once();
		PowerMock.replay(LeaderLatch.class);
		
		String controllerId = "controller2013";
		registry.registerController(controllerId);

		LoggingCallback callback = new LoggingCallback(1);
		long dpidToRequest = 2000L;

		try {
			registry.requestControl(dpidToRequest, callback);
		} catch (RegistryException e) {
			e.printStackTrace();
			fail(e.getMessage());
		}
		
		EasyMock.verify(latch);
	}

	/**
	 * Test if {@link ZookeeperRegistry#releaseControl(long)} correctly release control of specific switch.
	 * Because {@link ZookeeperRegistry#releaseControl(long)} doesn't return values, inject mock
	 * {@link LeaderLatch} object and verify latch is correctly set up.
	 * @throws Exception
	 */
	@Test
	public void testReleaseControl() throws Exception {
		// Mock of LeaderLatch
		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
		EasyMock.expectLastCall().once();
		latch.start();
		EasyMock.expectLastCall().once();
		latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
		EasyMock.expectLastCall().once();
		latch.close();
		EasyMock.expectLastCall().once();
		EasyMock.replay(latch);
		
		PowerMock.expectNew(LeaderLatch.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
				.andReturn(latch).once();
		PowerMock.replay(LeaderLatch.class);
		
		String controllerId = "controller2013";
		registry.registerController(controllerId);
		
		long dpidToRequest = 2000L;
		LoggingCallback callback = new LoggingCallback(1);
		
		registry.requestControl(dpidToRequest, callback);
		registry.releaseControl(dpidToRequest);
		
		EasyMock.verify(latch);
	}

	/**
	 * Test if {@link ZookeeperRegistry#hasControl(long)} returns correct status whether controller has control of specific switch.
	 * @throws Exception
	 */
	@Test
	public void testHasControl() throws Exception {
		// Mock of LeaderLatch
		LeaderLatch latch = EasyMock.createMock(LeaderLatch.class);
		latch.addListener(EasyMock.anyObject(SwitchLeaderListener.class));
		EasyMock.expectLastCall().once();
		latch.start();
		EasyMock.expectLastCall().once();
		EasyMock.expect(latch.hasLeadership()).andReturn(true).anyTimes();
		latch.removeListener(EasyMock.anyObject(SwitchLeaderListener.class));
		EasyMock.expectLastCall().once();
		latch.close();
		EasyMock.expectLastCall().once();
		EasyMock.replay(latch);
		
		PowerMock.expectNew(LeaderLatch.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(String.class))
				.andReturn(latch);
		PowerMock.replay(LeaderLatch.class);
		
		String controllerId = "controller2013";
		registry.registerController(controllerId);
		
		long dpidToRequest = 2000L;
		LoggingCallback callback = new LoggingCallback(2);
		
		// Test before request control
		assertFalse(registry.hasControl(dpidToRequest));

		registry.requestControl(dpidToRequest, callback);
		
		// Test after request control
		assertTrue(registry.hasControl(dpidToRequest));
		
		registry.releaseControl(dpidToRequest);
		
		// Test after release control
		assertFalse(registry.hasControl(dpidToRequest));
		
		EasyMock.verify(latch);
	}

	/**
	 * Test if {@link ZookeeperRegistry#getControllerForSwitch(long)} correctly returns controller ID of specific switch.
	 * Relation between controllers and switches are defined by {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
	 * @throws Throwable
	 */
	@Test
	public void testGetControllerForSwitch() throws Throwable {
		long dpidRegistered = 1000L;
		long dpidNotRegistered = 2000L;
		
		setPathChildrenCache();
		
		String controllerForSw = registry.getControllerForSwitch(dpidRegistered);
		assertEquals("controller1",controllerForSw);

		controllerForSw = registry.getControllerForSwitch(dpidNotRegistered);
		assertEquals(null, controllerForSw);
	}

	/**
	 * Test if {@link ZookeeperRegistry#getSwitchesControlledByController(String)} returns correct list of
	 * switches controlled by a controller.
	 * @throws Exception
	 */
	// TODO: Test after getSwitchesControlledByController() is implemented.
	@Ignore @Test
	public void testGetSwitchesControlledByController() throws Exception {
		String controllerIdRegistered = "controller1";
		String dpidRegistered = HexString.toHexString(1000L);
		String controllerIdNotRegistered = CONTROLLER_ID;
		
		Collection<Long> switches = registry.getSwitchesControlledByController(controllerIdRegistered);
		assertNotNull(switches);
		assertTrue(switches.contains(dpidRegistered));

		switches = registry.getSwitchesControlledByController(controllerIdNotRegistered);
		assertNotNull(switches);
		assertEquals(0, switches.size());
	}

	/**
	 * Test if {@link ZookeeperRegistry#getAllSwitches()} returns correct list of all switches.
	 * Switches are injected in {@link ZookeeperRegistryTest#setPathChildrenCache()} function.
	 * @throws Exception
	 */
	@Test
	public void testGetAllSwitches() throws Exception {
		String [] dpids = {
				HexString.toHexString(1000L),
				HexString.toHexString(1001L),
				HexString.toHexString(1002L),
		};
		
		setPathChildrenCache();

		Map<String, List<ControllerRegistryEntry>> switches = registry.getAllSwitches();
		assertNotNull(switches);
		assertEquals(dpids.length, switches.size());
		for(String dpid : dpids) {
			assertTrue(switches.keySet().contains(dpid));
		}
	}

	/**
	 * Test if {@link ZookeeperRegistry#allocateUniqueIdBlock()} can assign IdBlock without duplication.
	 */
	@Test
	public void testAllocateUniqueIdBlock() {
		// Number of blocks to be verified that any of them has unique block
		final int NUM_BLOCKS = 100;
		ArrayList<IdBlock> blocks = new ArrayList<IdBlock>(NUM_BLOCKS);
		
		for(int i = 0; i < NUM_BLOCKS; ++i) {
			IdBlock block = registry.allocateUniqueIdBlock();
			assertNotNull(block);
			blocks.add(block);
		}
		
		for(int i = 0; i < NUM_BLOCKS; ++i) {
			IdBlock block1 = blocks.get(i);
			for(int j = i + 1; j < NUM_BLOCKS; ++j) {
				IdBlock block2 = blocks.get(j);
				IdBlock lower,higher;
				
				if(block1.getStart() < block2.getStart()) {
					lower = block1;
					higher = block2;
				} else {
					lower = block2;
					higher = block1;
				}
				
				assertTrue(lower.getSize() > 0L);
				assertTrue(higher.getSize() > 0L);
				assertTrue(lower.getEnd() <= higher.getStart());
			}
		}
	}
	
	
	//-------------------------- Creation of mock objects --------------------------
	/**
	 * Create mock {@link CuratorFramework} object with initial value below.<br>
	 *   [Ctrl ID]    : [DPID]<br>
	 * controller1    :  1000<br>
	 * controller2    :  1001<br>
	 * controller2    :  1002<br>
	 * controller2013 : nothing
	 * @return Created mock object
	 * @throws Exception
	 */
	@SuppressWarnings({ "serial", "unchecked" })
	private CuratorFramework createCuratorFrameworkMock() throws Exception {
		// Mock of AtomicValue
		AtomicValue<Long> atomicValue = EasyMock.createMock(AtomicValue.class);
		EasyMock.expect(atomicValue.succeeded()).andReturn(true).anyTimes();
		EasyMock.expect(atomicValue.preValue()).andAnswer(new IAnswer<Long>() {
			private long value = 0;
			@Override
			public Long answer() throws Throwable {
				value += ID_BLOCK_SIZE;
				return value;
			}
		}).anyTimes();
		EasyMock.expect(atomicValue.postValue()).andAnswer(new IAnswer<Long>() {
			private long value = ID_BLOCK_SIZE;
			@Override
			public Long answer() throws Throwable {
				value += ID_BLOCK_SIZE;
				return value;
			}
		}).anyTimes();
		EasyMock.replay(atomicValue);
		
		// Mock DistributedAtomicLong
		DistributedAtomicLong daLong = EasyMock.createMock(DistributedAtomicLong.class);
		EasyMock.expect(daLong.add(EasyMock.anyLong())).andReturn(atomicValue).anyTimes();
		EasyMock.replay(daLong);
		PowerMock.expectNew(DistributedAtomicLong.class,
				new Class<?> [] {CuratorFramework.class, String.class, RetryPolicy.class},
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyObject(RetryPolicy.class)).
				andReturn(daLong).anyTimes();
		PowerMock.replay(DistributedAtomicLong.class);
		
		// Mock ListenerContainer
		ListenerContainer<PathChildrenCacheListener> listenerContainer = EasyMock.createMock(ListenerContainer.class);
		listenerContainer.addListener(EasyMock.anyObject(PathChildrenCacheListener.class));
		EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
			@Override
			public Object answer() throws Throwable {
				pathChildrenCacheListener = (PathChildrenCacheListener)EasyMock.getCurrentArguments()[0];
				return null;
			}
		}).once();
		EasyMock.replay(listenerContainer);

		// Mock PathChildrenCache
		PathChildrenCache pathChildrenCacheMain = createPathChildrenCacheMock(CONTROLLER_ID, new String[] {"/switches"}, listenerContainer);
		PathChildrenCache pathChildrenCache1 = createPathChildrenCacheMock("controller1", new String[] {HexString.toHexString(1000L)}, listenerContainer);
		PathChildrenCache pathChildrenCache2 = createPathChildrenCacheMock("controller2", new String[] { 
			HexString.toHexString(1001L), HexString.toHexString(1002L) },listenerContainer);
		
		// Mock PathChildrenCache constructor
		PowerMock.expectNew(PathChildrenCache.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
				andReturn(pathChildrenCacheMain).once();
		PowerMock.expectNew(PathChildrenCache.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
				andReturn(pathChildrenCache1).once();
		PowerMock.expectNew(PathChildrenCache.class,
				EasyMock.anyObject(CuratorFramework.class), EasyMock.anyObject(String.class), EasyMock.anyBoolean()).
				andReturn(pathChildrenCache2).anyTimes();
		PowerMock.replay(PathChildrenCache.class);
		
		// Mock ServiceCache
		ServiceCache<ControllerService> serviceCache = EasyMock.createMock(ServiceCache.class);
		serviceCache.start();
		EasyMock.expectLastCall().once();
		EasyMock.expect(serviceCache.getInstances()).andReturn(new ArrayList<ServiceInstance<ControllerService> > () {{
			add(createServiceInstanceMock("controller1"));
			add(createServiceInstanceMock("controller2"));
		}}).anyTimes();
		EasyMock.replay(serviceCache);
		
		// Mock ServiceCacheBuilder
		ServiceCacheBuilder<ControllerService> serviceCacheBuilder = EasyMock.createMock(ServiceCacheBuilder.class);
		EasyMock.expect(serviceCacheBuilder.name(EasyMock.anyObject(String.class))).andReturn(serviceCacheBuilder).once();
		EasyMock.expect(serviceCacheBuilder.build()).andReturn(serviceCache).once();
		EasyMock.replay(serviceCacheBuilder);

		// Mock ServiceDiscovery
		ServiceDiscovery<ControllerService> serviceDiscovery = EasyMock.createMock(ServiceDiscovery.class);
		serviceDiscovery.start();
		EasyMock.expectLastCall().once();
		EasyMock.expect(serviceDiscovery.serviceCacheBuilder()).andReturn(serviceCacheBuilder).once();
		serviceDiscovery.registerService(EasyMock.anyObject(ServiceInstance.class));
		EasyMock.expectLastCall().once();
		EasyMock.replay(serviceDiscovery);
		
		// Mock CuratorFramework
		CuratorFramework client = EasyMock.createMock(CuratorFramework.class);
		client.start();
		EasyMock.expectLastCall().once();
		EasyMock.expect(client.usingNamespace(EasyMock.anyObject(String.class))).andReturn(client);
		EasyMock.replay(client);

		// Mock ServiceDiscoveryBuilder
		ServiceDiscoveryBuilder<ControllerService> builder = EasyMock.createMock(ServiceDiscoveryBuilder.class);
		EasyMock.expect(builder.client(client)).andReturn(builder).once();
		EasyMock.expect(builder.basePath(EasyMock.anyObject(String.class))).andReturn(builder);
		EasyMock.expect(builder.build()).andReturn(serviceDiscovery);
		EasyMock.replay(builder);
		
		PowerMock.mockStatic(ServiceDiscoveryBuilder.class);
		EasyMock.expect(ServiceDiscoveryBuilder.builder(ControllerService.class)).andReturn(builder).once();
		PowerMock.replay(ServiceDiscoveryBuilder.class);

		return client;
	}
	
	/**
	 * Create mock {@link ServiceInstance} object using given controller ID.
	 * @param controllerId Controller ID to represent instance's payload (ControllerService).
	 * @return Mock ServiceInstance object
	 */
	private ServiceInstance<ControllerService> createServiceInstanceMock(String controllerId) {
		ControllerService controllerService = EasyMock.createMock(ControllerService.class);
		EasyMock.expect(controllerService.getControllerId()).andReturn(controllerId).anyTimes();
		EasyMock.replay(controllerService);
		
		@SuppressWarnings("unchecked")
		ServiceInstance<ControllerService> serviceInstance = EasyMock.createMock(ServiceInstance.class);
		EasyMock.expect(serviceInstance.getPayload()).andReturn(controllerService).anyTimes();
		EasyMock.replay(serviceInstance);

		return serviceInstance;
	}
	
	/**
	 * Create mock {@link PathChildrenCache} using given controller ID and DPIDs.
	 * @param controllerId Controller ID to represent current data.
	 * @param paths List of HexString indicating switch's DPID.
	 * @param listener Callback object to be set as Listenable.
	 * @return Mock PathChildrenCache object
	 * @throws Exception
	 */
	private PathChildrenCache createPathChildrenCacheMock(final String controllerId, final String [] paths,
			ListenerContainer<PathChildrenCacheListener> listener) throws Exception {
		PathChildrenCache pathChildrenCache = EasyMock.createMock(PathChildrenCache.class);
		
		EasyMock.expect(pathChildrenCache.getListenable()).andReturn(listener).anyTimes();
		
		pathChildrenCache.start(EasyMock.anyObject(StartMode.class));
		EasyMock.expectLastCall().anyTimes();
		
		List<ChildData> childs = new ArrayList<ChildData>();
		for(String path : paths) {
			childs.add(createChildDataMockForCurrentData(controllerId,path));
		}
		EasyMock.expect(pathChildrenCache.getCurrentData()).andReturn(childs).anyTimes();
		
		pathChildrenCache.rebuild();
		EasyMock.expectLastCall().anyTimes();
		
		EasyMock.replay(pathChildrenCache);

		return pathChildrenCache;
	}
	
	/**
	 * Create mock {@link ChildData} for {@link PathChildrenCache#getCurrentData()} return value.
	 * This object need to include 'sequence number' in tail of path string. ("-0" means 0th sequence)
	 * @param controllerId Controller ID
	 * @param path HexString indicating switch's DPID
	 * @return Mock ChildData object
	 */
	private ChildData createChildDataMockForCurrentData(String controllerId, String path) {
		ChildData data = EasyMock.createMock(ChildData.class);
		EasyMock.expect(data.getPath()).andReturn(path + "-0").anyTimes();
		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
		EasyMock.replay(data);
		
		return data;
	}

	/**
	 * Inject relations between controllers and switches using callback object.
	 * @throws Exception
	 */
	private void setPathChildrenCache() throws Exception {
		pathChildrenCacheListener.childEvent(client,
				createChildrenCacheEventMock("controller1", HexString.toHexString(1000L), PathChildrenCacheEvent.Type.CHILD_ADDED));
		pathChildrenCacheListener.childEvent(client,
				createChildrenCacheEventMock("controller2", HexString.toHexString(1001L), PathChildrenCacheEvent.Type.CHILD_ADDED));
		pathChildrenCacheListener.childEvent(client,
				createChildrenCacheEventMock("controller2", HexString.toHexString(1002L), PathChildrenCacheEvent.Type.CHILD_ADDED));
	}

	/**
	 * Create mock {@link PathChildrenCacheEvent} object using given controller ID and DPID.
	 * @param controllerId Controller ID.
	 * @param path HexString of DPID.
	 * @param type Event type to be set to mock object.
	 * @return Mock PathChildrenCacheEvent object
	 */
	private PathChildrenCacheEvent createChildrenCacheEventMock(String controllerId, String path,
			PathChildrenCacheEvent.Type type) {
		PathChildrenCacheEvent event = EasyMock.createMock(PathChildrenCacheEvent.class);
		ChildData data = EasyMock.createMock(ChildData.class);
		
		EasyMock.expect(data.getPath()).andReturn(path).anyTimes();
		EasyMock.expect(data.getData()).andReturn(controllerId.getBytes()).anyTimes();
		EasyMock.replay(data);
		
		EasyMock.expect(event.getType()).andReturn(type).anyTimes();
		EasyMock.expect(event.getData()).andReturn(data).anyTimes();
		EasyMock.replay(event);
		
		return event;
	}
}
