package net.onrc.onos.ofcontroller.devicemanager.internal;

import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import net.floodlightcontroller.core.internal.TestDatabaseManager;
import net.floodlightcontroller.devicemanager.IDevice;
import net.floodlightcontroller.devicemanager.SwitchPort;
import net.floodlightcontroller.devicemanager.internal.Device;
import net.floodlightcontroller.packet.IPv4;
import net.onrc.onos.graph.GraphDBConnection;
import net.onrc.onos.graph.GraphDBOperation;
import net.onrc.onos.ofcontroller.core.IDeviceStorage;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IPortObject;
import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
import net.onrc.onos.ofcontroller.core.internal.SwitchStorageImpl;

import org.easymock.EasyMock;
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.slf4j.LoggerFactory;
import org.powermock.modules.junit4.PowerMockRunner;

import com.thinkaurelius.titan.core.TitanFactory;
import com.thinkaurelius.titan.core.TitanGraph;

/*
 * Jono, 11/4/2013
 * These tests are being ignored because they don't work because they
 * rely on test functionality that was written ages ago and hasn't been
 * updated as the database schema has evolved. 
 * These tests work by getting an in-memory Titan database and testing
 * the DeviceStorageImpl on top of that. In this regard they're not really
 * unit tests as they test the entire DB stack (i.e. GraphDBOperation and
 * GraphDBConnection), not just DeviceStorageImpl.
 * I've left them here as we may wish to resurrect this kind of 
 * integration testing of the DB layers in the future.
 */
@Ignore
//Add Powermock preparation
@RunWith(PowerMockRunner.class)
@PrepareForTest({TitanFactory.class, GraphDBConnection.class, GraphDBOperation.class, SwitchStorageImpl.class})
public class DeviceStorageImplTestBB {
	protected static org.slf4j.Logger log = LoggerFactory.getLogger(SwitchStorageImpl.class);

	String conf;
    private GraphDBConnection conn = null;
    private GraphDBOperation ope = null;
    private TitanGraph titanGraph = null;
    IDeviceStorage deviceImpl = null;
    
	@Before
	public void setUp() throws Exception {
		
		deviceImpl = new DeviceStorageImpl();
		conf = "/dummy/path/to/db";
		
		// Make mock cassandra DB
		// Replace TitanFactory.open() to return mock DB
		titanGraph = TestDatabaseManager.getTestDatabase();
		TestDatabaseManager.populateTestData(titanGraph);
		PowerMock.mockStatic(TitanFactory.class);
		EasyMock.expect(TitanFactory.open((String)EasyMock.anyObject())).andReturn(titanGraph);
		PowerMock.replay(TitanFactory.class);
		
		conn = GraphDBConnection.getInstance(conf);
		ope = new GraphDBOperation(conn);
		
		deviceImpl.init(conf);
	}

	@After
	public void tearDown() throws Exception {
		titanGraph.shutdown();
		TestDatabaseManager.deleteTestDatabase();

		deviceImpl.close();
		deviceImpl = null;
	}

	/**
	 * Desc:
	 *  Test method for addDevice method.
	 * Codition:
	 *  N/A
	 * Expect:
	 * 	Get proper IDeviceObject
	 *  Check the IDeviceObject properties set
	 */
	@Test
	public void testAddDevice() {
		try 
		{	   
			//Make mockDevice
			IDevice mockDev = EasyMock.createMock(Device.class);
			// Mac addr for test device.
			String macAddr = "99:99:99:99:99:99";
			// IP addr for test device
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			// Mac addr for attached switch
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			// Port number for attached switch
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);

			EasyMock.replay(mockDev);

			//Add the device
	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			//Test to take a Device from DB correctly
			IDeviceObject devObj1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, devObj1.getMACAddress());

			//Test to take a attached sw  from DB correctly
			for(ISwitchObject sw1: devObj1.getSwitch())
			{
				String swMacFromDB = sw1.getDPID();
				assertEquals(switchMacAddr, swMacFromDB);
			}

			//Test to take a IP addr from DB
			//TodoForGettingIPaddr. There may be bug in the test class.
			
			//XXX not updated to new interface
			//String ipFromDB = devObj1.getIPAddress();
			String ipFromDB = "foo";
			
			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
			List<String> ipsList = Arrays.asList(ipsFromDB);
			assertTrue(ipsList.contains(ip));

			//Test to take a attached port from DB
			for(IPortObject port : devObj1.getAttachedPorts())
			{

				//In this implementing, the object was not set the port. So it must be null.
				if(port.getNumber() != null)
				{
					String portNumFromDB = port.getNumber().toString();
					assertEquals(String.valueOf(portNum), portNumFromDB);				
				}
			}	
		} catch(Exception e) {
			fail(e.getMessage());
		}
	}
	
	/**
	 * Desc:
	 * 	Test method for addDevice method.
	 * Condition:
	 * 	Already added device is existed.
	 * Expect:
	 * 	Get proper IDeviceObject still.
	 *  Check the IDeviceObject properties set.
	 */
	@Test
	public void testAddDeviceExisting() {
		try 
		{	   
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

			//Add the device
	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			//Test to take a Device from DB correctly
			IDeviceObject devObj1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, devObj1.getMACAddress());

			//Add the same device
	        IDeviceObject obj2 = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj2);

			IDeviceObject devObj2 = ope.searchDevice(macAddr);
			assertEquals(macAddr, devObj2.getMACAddress());	

			//Test to take a attached port from DB
			for(IPortObject port : devObj2.getAttachedPorts())
			{
				//In this implementing, the object was not set the port. So it must be null.
				if(port.getNumber() != null)
				{

					String portNumFromDB = port.getNumber().toString();
					assertEquals(String.valueOf(portNum), portNumFromDB);

				}
			}	

			//XXX not updated to new interface
			//String ipFromDB = devObj2.getIPAddress();
			String ipFromDB = "foo";
			
			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
			List<String> ipsList = Arrays.asList(ipsFromDB);
			assertTrue(ipsList.contains(ip));

			//Test to take a attached port from DB
			for(IPortObject port : devObj2.getAttachedPorts())
			{

				//In this implementing, the object was not set the port. So it must be null.
				if(port.getNumber() != null)
				{
					String portNumFromDB = port.getNumber().toString();
					assertEquals(String.valueOf(portNum), portNumFromDB);				
				}
			}	
		} catch(Exception e) {
			fail(e.getMessage());
		}
	}
	/**
	 * Desc:
	 * 	Test method for updateDevice method.
	 * Condition:
	 * 	The mac address and attachment point are the same. 
	 *  All of the other parameter are different.
	 * Expect:
	 * 	Changed parameters are set properly.
	 */
	//@Ignore
	@Test
	public void testUpdateDevice() {
		try
		{
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

			//Dev2 (attached port is the same)
			IDevice mockDev2 = EasyMock.createMock(Device.class);
			String macAddr2 = "99:aa:aa:aa:aa:aa";
			Integer ip2 = IPv4.toIPv4Address("192.168.100.2");
			Integer[] ipaddrs2 = {ip2};

			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr2);
			EasyMock.replay(mockDev2);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			IDeviceObject dev1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev1.getMACAddress());

			//update theDevice
			deviceImpl.updateDevice(mockDev2);
			IDeviceObject dev2 = ope.searchDevice(macAddr2);
			assertEquals(macAddr2, dev2.getMACAddress());
			IPortObject iport = ope.searchPort(switchMacAddr, portNum);

			//Test to take a attached port from DB
			for(IDeviceObject dev : iport.getDevices())
			{
				String macAddrFromDB = dev.getMACAddress();	
				if(macAddr2.equals(macAddrFromDB)){
					//Nothing to do
				}
				else{
					fail("notFoundTheDeviceOnThePort");			
				}
			}

		} catch(Exception e) {
			fail(e.getMessage());
		}
	}

	/**
	 * Desc:
	 * 	Test method for testRemoveDevice method.
	 * Condition:
	 * 	1. Unregistered IDeviceObject argument is put. 
	 * Expect:
	 *  1. Nothing happen when unregistered IDeviceObject is put
	 * 	2. IDeviceObject will be removed.
	 */
	//@Ignore
	@Test
	public void testRemoveDevice() {
		try
		{
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			IDeviceObject dev1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev1.getMACAddress());

			deviceImpl.removeDevice(mockDev);		
		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
		    assertNull(dev);

		} catch(Exception e) {
			fail(e.getMessage());
		}
	}

	/**
	 * Desc:
	 * 	Test method for getDeviceByMac
	 * Condition:
	 * 	1. Unregistered mac address argument is set
	 * Expect:
	 * 	1.Nothing happen when you put unregistered mac address
	 *  2.Get the proper IDeviceObject.
	 *  3.Check the IDeviceObject properties set.
	 */
	//@Ignore
	@Test
	public void testGetDeviceByMac() {
		try
		{
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			IDeviceObject dev1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev1.getMACAddress());

		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
		    assertNotNull(dev);
			assertEquals(macAddr, dev.getMACAddress());

		} catch(Exception e) {
			fail(e.getMessage());
		}
	}

	/**
	 * Desc:
	 * 	Test method for getDeviceByIP method.
	 * Condition:
	 * 	1. Unregistered ip address argument is set
	 * Expect:
	 * 	1. Nothing happen when you put unregistered mac address
	 * 	2. Get the proper IDeviceObject.
	 *  3. Check the IDeviceObject properties set.
	 */
	//@Ignore
	@Test
	public void testGetDeviceByIP() {
		try
		{
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			IDeviceObject dev1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev1.getMACAddress());

			//XXX not updated to new interface
		    //IDeviceObject dev = deviceImpl.getDeviceByIP(ip);
			IDeviceObject dev = null;
			
		    assertNotNull(dev);
		    
		    //XXX not updated to new interface
			//String ipFromDB = dev.getIPAddress();
		    String ipFromDB = "foo";
		    
			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
			List<String> ipsList = Arrays.asList(ipsFromDB);
			assertTrue(ipsList.contains(ip));

		} catch(Exception e) {
			fail(e.getMessage());
		}
	}

	/**
	 * Desc:
	 * 	Test method for testChangeDeviceAttachmentsIDevice
	 * Condition:
	 * 	1. Unexisting attachment point argument is set
	 * Expect:
	 * 	1. Unexisting attachment point is ignored, so nothing happen.
	 * 	2. Change the attachment point.
	 */
	//@Ignore
	@Test
	public void testChangeDeviceAttachmentsIDevice() {
		try
		{
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

			//Dev2
			IDevice mockDev2 = EasyMock.createMock(Device.class);
			String switchMacAddr2 = "00:00:00:00:00:00:0a:02";
			long lSwitchMacAddr2 = HexString.toLong(switchMacAddr2);
			short portNum2 = 2; 
			SwitchPort sp2 = new SwitchPort(lSwitchMacAddr2, portNum2);
			SwitchPort sps2[] = {sp2};

			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev2.getAttachmentPoints()).andReturn(sps2);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev2);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

		    deviceImpl.changeDeviceAttachments(mockDev2);

		    IDeviceObject dev = deviceImpl.getDeviceByMac(macAddr);
		    assertNotNull(dev);

			for(ISwitchObject sw1: dev.getSwitch())
			{
				String swMacFromDB = sw1.getDPID();
				assertEquals(switchMacAddr2, swMacFromDB);
			}
		} catch(Exception e) {
			fail(e.getMessage());
		}
	}

	//@Ignore
	@Test
	public void testChangeDeviceAttachmentsIDeviceIDeviceObject() {
		//It is tested by the testChangeDeviceAttachmentsIDevice
	}

	/**
	 * Desc:
	 * 	Test method for testChangeDeviceIPv4Address
	 * Condition:
	 * 	N/A
	 * Expect:
	 *  1. Check correctly changed the ipadress
	 */
	//@Ignore
	@Test
	public void testChangeDeviceIPv4Address() {
		try
		{
			//Dev1
			IDevice mockDev = EasyMock.createMock(Device.class);
			String macAddr = "99:99:99:99:99:99";
			String ip = "192.168.100.1";
			Integer ipInt = IPv4.toIPv4Address(ip);
			Integer[] ipaddrs = {ipInt};
			String switchMacAddr = "00:00:00:00:00:00:0a:01";		
			long switchMacAddrL = HexString.toLong(switchMacAddr);
			short portNum = 2; 
			SwitchPort sp1 = new SwitchPort(switchMacAddrL, portNum);
			SwitchPort[] sps = {sp1};

			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getIPv4Addresses()).andReturn(ipaddrs);
			EasyMock.expect(mockDev.getAttachmentPoints()).andReturn(sps);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev.getMACAddressString()).andReturn(macAddr);
			EasyMock.replay(mockDev);

	        IDeviceObject obj = deviceImpl.addDevice(mockDev);	
			assertNotNull(obj);

			IDevice mockDev2 = EasyMock.createMock(Device.class);
			String ip2 = "192.168.100.2";
			Integer ipInt2 = IPv4.toIPv4Address(ip2);
			Integer[] ipaddrs2 = {ipInt2};
			EasyMock.expect(mockDev2.getMACAddressString()).andReturn(macAddr);
			EasyMock.expect(mockDev2.getIPv4Addresses()).andReturn(ipaddrs2);
			EasyMock.replay(mockDev2);

			IDeviceObject dev1 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev1.getMACAddress());
			
			//XXX not updated to new interface
			//String ipFromDB = dev1.getIPAddress();
			String ipFromDB = "foo";
			
			String[] ipsFromDB = ipFromDB.replace("[", "").replace("]", "").split(",");
			List<String> ipsList = Arrays.asList(ipsFromDB);
			assertTrue(ipsList.contains(ip));

	        deviceImpl.changeDeviceIPv4Address(mockDev2);	

			IDeviceObject dev2 = ope.searchDevice(macAddr);
			assertEquals(macAddr, dev2.getMACAddress());
			
			//XXX not updated to new interface
			//String ipFromDB2 = dev2.getIPAddress();
			String ipFromDB2 = "foo";
			
			String[] ipsFromDB2 = ipFromDB2.replace("[", "").replace("]", "").split(",");
			List<String> ipsList2 = Arrays.asList(ipsFromDB2);
			assertTrue(ipsList2.contains(ip2));
		} 
		catch(Exception e) {
			fail(e.getMessage());
		}
	}

}
