diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouter.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouter.java
index fb18502..57b997c 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouter.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouter.java
@@ -26,11 +26,11 @@
 /**
  * Implementation of external peer router.
  */
-public class DefaultExternalPeerRouter implements ExternalPeerRouter {
+public final class DefaultExternalPeerRouter implements ExternalPeerRouter {
 
-    private IpAddress externalPeerRouterIp;
-    private MacAddress externalPeerRouterMac;
-    private VlanId externalPeerRouterVlanId;
+    private final IpAddress externalPeerRouterIp;
+    private final MacAddress externalPeerRouterMac;
+    private final VlanId externalPeerRouterVlanId;
 
     public DefaultExternalPeerRouter(IpAddress externalPeerRouterIp,
                                      MacAddress externalPeerRouterMac,
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouterTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouterTest.java
new file mode 100644
index 0000000..c3aeab1
--- /dev/null
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultExternalPeerRouterTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknetworking.impl;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+
+/**
+ * Unit tests for DefaultExternalPeerRouter.
+ */
+public class DefaultExternalPeerRouterTest {
+
+    private static final IpAddress ROUTER_IP_1 = IpAddress.valueOf("1.2.3.4");
+    private static final IpAddress ROUTER_IP_2 = IpAddress.valueOf("5.6.7.8");
+    private static final MacAddress ROUTER_MAC_1 = MacAddress.valueOf("11:22:33:44:55:66");
+    private static final MacAddress ROUTER_MAC_2 = MacAddress.valueOf("77:88:99:AA:BB:CC");
+    private static final VlanId VLAN_ID_1 = VlanId.vlanId("1");
+    private static final VlanId VLAN_ID_2 = VlanId.vlanId("2");
+
+    private ExternalPeerRouter router1;
+    private ExternalPeerRouter sameAsRouter1;
+    private ExternalPeerRouter router2;
+
+    /**
+     * Checks that the DefaultExternalPeerRouter class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultExternalPeerRouter.class);
+    }
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setUp() {
+        router1 = new DefaultExternalPeerRouter(ROUTER_IP_1, ROUTER_MAC_1, VLAN_ID_1);
+        sameAsRouter1 = new DefaultExternalPeerRouter(ROUTER_IP_1, ROUTER_MAC_1, VLAN_ID_1);
+        router2 = new DefaultExternalPeerRouter(ROUTER_IP_2, ROUTER_MAC_2, VLAN_ID_2);
+    }
+
+    /**
+     * Tests object equality.
+     */
+    @Test
+    public void testEquality() {
+        new EqualsTester().addEqualityGroup(router1, sameAsRouter1)
+                .addEqualityGroup(router2)
+                .testEquals();
+    }
+
+    /**
+     * Test object construction.
+     */
+    @Test
+    public void testConstruction() {
+        ExternalPeerRouter router = router1;
+
+        assertThat(router.externalPeerRouterIp(), is(router1.externalPeerRouterIp()));
+        assertThat(router.externalPeerRouterMac(), is(router1.externalPeerRouterMac()));
+        assertThat(router.externalPeerRouterVlanId(), is(router1.externalPeerRouterVlanId()));
+    }
+}
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultInstancePortTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultInstancePortTest.java
new file mode 100644
index 0000000..6fecc1a
--- /dev/null
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/DefaultInstancePortTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknetworking.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.openstacknetworking.api.InstancePort;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
+import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_CREATE_TIME;
+
+/**
+ * Unit tests for the default instance port class.
+ */
+public class DefaultInstancePortTest {
+
+    private static final String ANNOTATION_NETWORK_ID = "networkId";
+    private static final String ANNOTATION_PORT_ID = "portId";
+
+    private static final IpAddress IP_ADDRESS_1 = IpAddress.valueOf("1.2.3.4");
+    private static final IpAddress IP_ADDRESS_2 = IpAddress.valueOf("5.6.7.8");
+
+    private static final MacAddress MAC_ADDRESS_1 = MacAddress.valueOf("11:22:33:44:55:66");
+    private static final MacAddress MAC_ADDRESS_2 = MacAddress.valueOf("77:88:99:AA:BB:CC");
+
+    private static final DeviceId DEV_ID_1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV_ID_2 = DeviceId.deviceId("of:0000000000000002");
+    private static final PortNumber PORT_NUM_1 = PortNumber.portNumber(1L);
+    private static final PortNumber PORT_NUM_2 = PortNumber.portNumber(2L);
+
+    private static final VlanId VLAN_ID = VlanId.vlanId();
+    private static final ProviderId PROVIDER_ID = ProviderId.NONE;
+    private static final HostId HOST_ID_1 = HostId.hostId("00:00:11:00:00:01/1");
+    private static final HostId HOST_ID_2 = HostId.hostId("00:00:11:00:00:02/1");
+
+    private static final String NETWORK_ID_1 = "net-id-1";
+    private static final String NETWORK_ID_2 = "net-id-2";
+    private static final String PORT_ID_1 = "port-id-1";
+    private static final String PORT_ID_2 = "port-id-2";
+
+    private static final long TIME_1 = 1L;
+    private static final long TIME_2 = 2L;
+
+    private InstancePort instancePort1;
+    private InstancePort sameAsInstancePort1;
+    private InstancePort instancePort2;
+
+    /**
+     * Checks that the DefaultInstancePort class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(DefaultInstancePort.class);
+    }
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setUp() {
+
+        HostLocation location1 = new HostLocation(DEV_ID_1, PORT_NUM_1, TIME_1);
+        HostLocation location2 = new HostLocation(DEV_ID_2, PORT_NUM_2, TIME_2);
+
+        DefaultAnnotations.Builder annotations1 = DefaultAnnotations.builder()
+                .set(ANNOTATION_NETWORK_ID, NETWORK_ID_1)
+                .set(ANNOTATION_PORT_ID, PORT_ID_1)
+                .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_1));
+
+        DefaultAnnotations.Builder annotations2 = DefaultAnnotations.builder()
+                .set(ANNOTATION_NETWORK_ID, NETWORK_ID_2)
+                .set(ANNOTATION_PORT_ID, PORT_ID_2)
+                .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_2));
+
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_1, MAC_ADDRESS_1,
+                                VLAN_ID, location1, ImmutableSet.of(IP_ADDRESS_1),
+                                annotations1.build());
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_2, MAC_ADDRESS_2,
+                                VLAN_ID, location2, ImmutableSet.of(IP_ADDRESS_2),
+                                annotations2.build());
+
+        instancePort1 = DefaultInstancePort.from(host1, ACTIVE);
+        sameAsInstancePort1 = DefaultInstancePort.from(host1, ACTIVE);
+        instancePort2 = DefaultInstancePort.from(host2, ACTIVE);
+    }
+
+    /**
+     * Tests object equality.
+     */
+    @Test
+    public void testEquality() {
+        new EqualsTester().addEqualityGroup(instancePort1, sameAsInstancePort1)
+                .addEqualityGroup(instancePort2)
+                .testEquals();
+    }
+
+    /**
+     * Test object construction.
+     */
+    @Test
+    public void testConstruction() {
+        InstancePort instancePort = instancePort1;
+
+        assertThat(instancePort.portId(), is(PORT_ID_1));
+        assertThat(instancePort.networkId(), is(NETWORK_ID_1));
+        assertThat(instancePort.macAddress(), is(MAC_ADDRESS_1));
+        assertThat(instancePort.ipAddress(), is(IP_ADDRESS_1));
+        assertThat(instancePort.portNumber(), is(PORT_NUM_1));
+        assertThat(instancePort.deviceId(), is(DEV_ID_1));
+        assertThat(instancePort.state(), is(ACTIVE));
+    }
+}
diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java
new file mode 100644
index 0000000..9070452
--- /dev/null
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/InstancePortManagerTest.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openstacknetworking.impl;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.MoreExecutors;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.event.Event;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.openstacknetworking.api.InstancePort;
+import org.onosproject.openstacknetworking.api.InstancePortEvent;
+import org.onosproject.openstacknetworking.api.InstancePortListener;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.ACTIVE;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.INACTIVE;
+import static org.onosproject.openstacknetworking.api.InstancePort.State.MIGRATING;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_ENDED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_DETECTED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_UPDATED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_PORT_VANISHED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_RESTARTED;
+import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_TERMINATED;
+import static org.onosproject.openstacknetworking.impl.HostBasedInstancePort.ANNOTATION_CREATE_TIME;
+
+/**
+ * Unit tests for instance port manager.
+ */
+public class InstancePortManagerTest {
+
+    private static final ApplicationId TEST_APP_ID = new DefaultApplicationId(1, "test");
+
+    private static final String ANNOTATION_NETWORK_ID = "networkId";
+    private static final String ANNOTATION_PORT_ID = "portId";
+
+    private static final IpAddress IP_ADDRESS_1 = IpAddress.valueOf("1.2.3.4");
+    private static final IpAddress IP_ADDRESS_2 = IpAddress.valueOf("5.6.7.8");
+
+    private static final MacAddress MAC_ADDRESS_1 = MacAddress.valueOf("11:22:33:44:55:66");
+    private static final MacAddress MAC_ADDRESS_2 = MacAddress.valueOf("77:88:99:AA:BB:CC");
+
+    private static final DeviceId DEV_ID_1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV_ID_2 = DeviceId.deviceId("of:0000000000000002");
+    private static final PortNumber PORT_NUM_1 = PortNumber.portNumber(1L);
+    private static final PortNumber PORT_NUM_2 = PortNumber.portNumber(2L);
+
+    private static final VlanId VLAN_ID = VlanId.vlanId();
+    private static final ProviderId PROVIDER_ID = ProviderId.NONE;
+    private static final HostId HOST_ID_1 = HostId.hostId("00:00:11:00:00:01/1");
+    private static final HostId HOST_ID_2 = HostId.hostId("00:00:11:00:00:02/1");
+
+    private static final String NETWORK_ID_1 = "net-id-1";
+    private static final String NETWORK_ID_2 = "net-id-2";
+    private static final String PORT_ID_1 = "port-id-1";
+    private static final String PORT_ID_2 = "port-id-2";
+    private static final String UNKNOWN_ID = "port-id-x";
+
+    private static final long TIME_1 = 1L;
+    private static final long TIME_2 = 2L;
+
+    private InstancePort instancePort1;
+    private InstancePort instancePort2;
+
+    private InstancePortManager target;
+    private DistributedInstancePortStore store;
+
+    private final TestInstancePortListener testInstancePortListener = new TestInstancePortListener();
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setUp() {
+
+        store = new DistributedInstancePortStore();
+        TestUtils.setField(store, "coreService", new TestCoreService());
+        TestUtils.setField(store, "storageService", new TestStorageService());
+        TestUtils.setField(store, "eventExecutor", MoreExecutors.newDirectExecutorService());
+        store.activate();
+
+        target = new InstancePortManager();
+        TestUtils.setField(target, "coreService", new TestCoreService());
+        TestUtils.setField(target, "hostService", new TestHostService());
+        target.instancePortStore = store;
+        target.addListener(testInstancePortListener);
+        target.activate();
+
+        HostLocation location1 = new HostLocation(DEV_ID_1, PORT_NUM_1, TIME_1);
+        HostLocation location2 = new HostLocation(DEV_ID_2, PORT_NUM_2, TIME_2);
+
+        DefaultAnnotations.Builder annotations1 = DefaultAnnotations.builder()
+                .set(ANNOTATION_NETWORK_ID, NETWORK_ID_1)
+                .set(ANNOTATION_PORT_ID, PORT_ID_1)
+                .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_1));
+
+        DefaultAnnotations.Builder annotations2 = DefaultAnnotations.builder()
+                .set(ANNOTATION_NETWORK_ID, NETWORK_ID_2)
+                .set(ANNOTATION_PORT_ID, PORT_ID_2)
+                .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_2));
+
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_1, MAC_ADDRESS_1,
+                VLAN_ID, location1, ImmutableSet.of(IP_ADDRESS_1),
+                annotations1.build());
+        Host host2 = new DefaultHost(PROVIDER_ID, HOST_ID_2, MAC_ADDRESS_2,
+                VLAN_ID, location2, ImmutableSet.of(IP_ADDRESS_2),
+                annotations2.build());
+
+        instancePort1 = DefaultInstancePort.from(host1, ACTIVE);
+        instancePort2 = DefaultInstancePort.from(host2, INACTIVE);
+    }
+
+    /**
+     * Tears down all of this unit test.
+     */
+    @After
+    public void tearDown() {
+        target.removeListener(testInstancePortListener);
+        store.deactivate();
+        target.deactivate();
+        store = null;
+        target = null;
+    }
+
+    /**
+     * Tests if getting all instance ports returns the correct set of ports.
+     */
+    @Test
+    public void testGetInstancePorts() {
+        createBasicInstancePorts();
+        assertEquals("Number of instance port did not match",
+                2, target.instancePorts().size());
+    }
+
+    /**
+     * Tests if getting an instance port with port ID returns the correct port.
+     */
+    @Test
+    public void testGetInstancePortById() {
+        createBasicInstancePorts();
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_2));
+        assertNull("Instance port did not match", target.instancePort(UNKNOWN_ID));
+    }
+
+
+    /**
+     * Tests if getting an instance port with IP and network ID returns correct port.
+     */
+    @Test
+    public void testGetInstancePortByIpAndNetId() {
+        createBasicInstancePorts();
+        InstancePort port = target.instancePort(IP_ADDRESS_1, NETWORK_ID_1);
+        assertEquals("Instance port did not match", port, instancePort1);
+    }
+
+    /**
+     * Tests if getting an instance port with MAC returns correct port.
+     */
+    @Test
+    public void testGetInstancePortByMac() {
+        createBasicInstancePorts();
+        InstancePort port = target.instancePort(MAC_ADDRESS_1);
+        assertEquals("Instance port did not match", port, instancePort1);
+    }
+
+    /**
+     * Tests if getting instance ports with network ID returns correct ports.
+     */
+    @Test
+    public void testGetInstancePortsByNetId() {
+        createBasicInstancePorts();
+        Set<InstancePort> ports = target.instancePorts(NETWORK_ID_1);
+        assertEquals("Number of instance port did not match",
+                1, ports.size());
+    }
+
+    /**
+     * Tests creating and removing an instance port, and checks if it triggers proper events.
+     */
+    @Test
+    public void testCreateAndRemoveInstancePort() {
+        target.createInstancePort(instancePort1);
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        target.removeInstancePort(PORT_ID_1);
+        assertEquals("Number of instance port did not match",
+                0, target.instancePorts().size());
+        assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_PORT_VANISHED);
+    }
+
+    /**
+     * Tests updating an instance port, and checks if it triggers proper events.
+     */
+    @Test
+    public void testCreateAndUpdateInstancePort() {
+        target.createInstancePort(instancePort1);
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertEquals("Instance port did not match", PORT_NUM_1,
+                target.instancePort(PORT_ID_1).portNumber());
+
+        HostLocation location = new HostLocation(DEV_ID_2, PORT_NUM_2, TIME_2);
+
+        DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
+                .set(ANNOTATION_NETWORK_ID, NETWORK_ID_2)
+                .set(ANNOTATION_PORT_ID, PORT_ID_1)
+                .set(ANNOTATION_CREATE_TIME, String.valueOf(TIME_2));
+
+        Host host = new DefaultHost(PROVIDER_ID, HOST_ID_2, MAC_ADDRESS_2,
+                VLAN_ID, location, ImmutableSet.of(IP_ADDRESS_2),
+                annotations.build());
+
+        final InstancePort updated = DefaultInstancePort.from(host, ACTIVE);
+        target.updateInstancePort(updated);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertEquals("Instance port did not match", PORT_NUM_2,
+                target.instancePort(PORT_ID_1).portNumber());
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED, OPENSTACK_INSTANCE_PORT_UPDATED);
+    }
+
+    /**
+     * Tests if creating a null instance port fails with an exception.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testCreateNullInstancePort() {
+        target.createInstancePort(null);
+    }
+
+    /**
+     * Tests if creating a duplicated instance port fails with an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testCreateDuplicateInstancePort() {
+        target.createInstancePort(instancePort1);
+        target.createInstancePort(instancePort1);
+    }
+
+    /**
+     * Tests if removing instance port with null ID fails with an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testRemoveInstancePortWithNull() {
+        target.removeInstancePort(null);
+    }
+
+    /**
+     * Tests if updating an unregistered instance port fails with an exception.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testUpdateUnregisteredInstancePort() {
+        target.updateInstancePort(instancePort1);
+    }
+
+    /**
+     * Tests if it triggers the instance termination event.
+     */
+    @Test
+    public void testTerminateInstance() {
+        InstancePort instancePort = instancePort1;
+        target.createInstancePort(instancePort);
+
+        InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
+        target.updateInstancePort(inactiveInstancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_TERMINATED);
+    }
+
+    /**
+     * Tests if it triggers the instance restart event.
+     */
+    @Test
+    public void testRestartInstance() {
+        InstancePort instancePort = instancePort1;
+        InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
+
+        target.createInstancePort(inactiveInstancePort);
+        target.updateInstancePort(instancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_RESTARTED);
+    }
+
+    /**
+     * Tests if it triggers the instance migration start event.
+     */
+    @Test
+    public void testMigrateInstanceStart() {
+        InstancePort instancePort = instancePort1;
+        target.createInstancePort(instancePort);
+
+        InstancePort inactiveInstancePort = instancePort.updateState(MIGRATING);
+        target.updateInstancePort(inactiveInstancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_MIGRATION_STARTED);
+    }
+
+    /**
+     * Tests if it triggers the instance migration end event.
+     */
+    @Test
+    public void testMigrateInstanceEnd() {
+        InstancePort instancePort = instancePort1;
+        InstancePort inactiveInstancePort = instancePort.updateState(MIGRATING);
+
+        target.createInstancePort(inactiveInstancePort);
+        target.updateInstancePort(instancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_MIGRATION_ENDED);
+    }
+
+    /**
+     * Tests if it triggers the instance removal event from termination status.
+     */
+    @Test
+    public void testRemoveInstanceFromTermination() {
+        InstancePort instancePort = instancePort1;
+        target.createInstancePort(instancePort);
+
+        InstancePort inactiveInstancePort = instancePort.updateState(INACTIVE);
+        target.updateInstancePort(inactiveInstancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        target.removeInstancePort(PORT_ID_1);
+
+        assertEquals("Number of instance port did not match",
+                0, target.instancePorts().size());
+        assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_TERMINATED,
+                OPENSTACK_INSTANCE_PORT_VANISHED);
+    }
+
+    /**
+     * Tests if it triggers the instance removal event from migration status.
+     */
+    @Test
+    public void testRemoveInstanceFromMigration() {
+        InstancePort instancePort = instancePort1;
+        target.createInstancePort(instancePort);
+
+        InstancePort inactiveInstancePort = instancePort.updateState(MIGRATING);
+        target.updateInstancePort(inactiveInstancePort);
+
+        assertEquals("Number of instance port did not match",
+                1, target.instancePorts().size());
+        assertNotNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        target.removeInstancePort(PORT_ID_1);
+
+        assertEquals("Number of instance port did not match",
+                0, target.instancePorts().size());
+        assertNull("Instance port did not match", target.instancePort(PORT_ID_1));
+
+        validateEvents(OPENSTACK_INSTANCE_PORT_DETECTED,
+                OPENSTACK_INSTANCE_PORT_UPDATED, OPENSTACK_INSTANCE_MIGRATION_STARTED,
+                OPENSTACK_INSTANCE_PORT_VANISHED);
+    }
+
+    private void createBasicInstancePorts() {
+        target.createInstancePort(instancePort1);
+        target.createInstancePort(instancePort2);
+    }
+
+    private static class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return TEST_APP_ID;
+        }
+    }
+
+    private static class TestHostService extends HostServiceAdapter {
+    }
+
+    private static class TestInstancePortListener implements InstancePortListener {
+        private List<InstancePortEvent> events = Lists.newArrayList();
+
+        @Override
+        public void event(InstancePortEvent event) {
+            events.add(event);
+        }
+    }
+
+    private void validateEvents(Enum... types) {
+        int i = 0;
+        assertEquals("Number of events did not match", types.length,
+                                        testInstancePortListener.events.size());
+        for (Event event : testInstancePortListener.events) {
+            assertEquals("Incorrect event received", types[i], event.type());
+            i++;
+        }
+        testInstancePortListener.events.clear();
+    }
+}
