diff --git a/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProviderTest.java b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProviderTest.java
new file mode 100644
index 0000000..e968d26
--- /dev/null
+++ b/apps/openstacknetworking/app/src/test/java/org/onosproject/openstacknetworking/impl/OpenstackSwitchingHostProviderTest.java
@@ -0,0 +1,368 @@
+/*
+ * 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.Maps;
+import com.google.common.collect.Sets;
+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.mastership.MastershipServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+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.device.DeviceServiceAdapter;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
+import org.openstack4j.model.network.Port;
+import org.openstack4j.openstack.networking.domain.NeutronNetwork;
+import org.openstack4j.openstack.networking.domain.NeutronPort;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_NETWORK_ID;
+import static org.onosproject.openstacknetworking.api.Constants.ANNOTATION_PORT_ID;
+
+/**
+ * Unit tests for Openstack Switching Host Provider.
+ */
+public class OpenstackSwitchingHostProviderTest {
+
+    private static final String PORT_ID = "65c0ee9f-d634-4522-8954-51021b570b0d";
+    private static final String NETWORK_ID = "396f12f8-521e-4b91-8e21-2e003500433a";
+    private static final String IP_ADDRESS = "10.10.10.2";
+    private static final String SUBNET_ID = "d32019d3-bc6e-4319-9c1d-6722fc136a22";
+    private static final String MAC_ADDRESS = "00:11:22:33:44:55";
+    private static final String MAC_ADDRESS2 = "11:22:33:44:55:66";
+
+    private static final ProviderId PID = new ProviderId("of", "foo");
+    private static final DefaultAnnotations ANNOTATIONS =
+                                    DefaultAnnotations.builder()
+                                            .set(ANNOTATION_NETWORK_ID, NETWORK_ID)
+                                            .set(ANNOTATION_PORT_ID, PORT_ID).build();
+
+    // Host Mac, VLAN
+    private static final ProviderId PROVIDER_ID = ProviderId.NONE;
+    private static final MacAddress HOST_MAC = MacAddress.valueOf(MAC_ADDRESS);
+    private static final MacAddress HOST_MAC2 = MacAddress.valueOf(MAC_ADDRESS2);
+
+    private static final VlanId HOST_VLAN_UNTAGGED = VlanId.NONE;
+    private static final HostId HOST_ID_UNTAGGED = HostId.hostId(HOST_MAC, HOST_VLAN_UNTAGGED);
+
+    private static final String SEGMENT_ID = "1";
+
+    // Host IP
+    private static final IpAddress HOST_IP11 = IpAddress.valueOf("10.0.1.1");
+
+    // Device
+    private static final DeviceId DEV_ID1 = DeviceId.deviceId("of:0000000000000001");
+    private static final DeviceId DEV_ID2 = DeviceId.deviceId("of:0000000000000002");
+
+    private static final Device DEV1 =
+            new DefaultDevice(PID, DEV_ID1, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Device DEV2 =
+            new DefaultDevice(PID, DEV_ID2, Device.Type.SWITCH, "", "", "", "", null);
+
+    // Port
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+
+    // Connect Point
+    private static final ConnectPoint CP11 = new ConnectPoint(DEV_ID1, P1);
+    private static final HostLocation HOST_LOC11 = new HostLocation(CP11, 0);
+    private static final ConnectPoint CP12 = new ConnectPoint(DEV_ID1, P2);
+    private static final HostLocation HOST_LOC12 = new HostLocation(CP12, 0);
+    private static final ConnectPoint CP21 = new ConnectPoint(DEV_ID2, P1);
+
+    private Map<HostId, Host> hostMap = Maps.newHashMap();
+    private Map<ConnectPoint, MacAddress> macMap = Maps.newHashMap();
+
+    private OpenstackSwitchingHostProvider target;
+
+    private HostDescription resultHostDesc;
+    private HostId resultHostId;
+    private HostLocation resultHostLocation;
+
+    /**
+     * Initial setup for this unit test.
+     */
+    @Before
+    public void setUp() {
+        target = new OpenstackSwitchingHostProvider();
+        TestUtils.setField(target, "coreService", new TestCoreService());
+        TestUtils.setField(target, "deviceService", new TestDeviceService());
+        TestUtils.setField(target, "hostService", new TestHostService());
+        TestUtils.setField(target, "mastershipService", new TestMastershipService());
+        TestUtils.setField(target, "osNodeService", new TestOpenstackNodeService());
+        TestUtils.setField(target, "osNetworkService", new TestOpenstackNetworkService());
+        TestUtils.setField(target, "hostProviderRegistry", new TestHostProviderRegistry());
+        TestUtils.setField(target, "executor", MoreExecutors.newDirectExecutorService());
+
+        Host host1 = new DefaultHost(PROVIDER_ID, HOST_ID_UNTAGGED, HOST_MAC, HOST_VLAN_UNTAGGED,
+                Sets.newHashSet(HOST_LOC11), Sets.newHashSet(HOST_IP11), false);
+        hostMap.put(HOST_ID_UNTAGGED, host1);
+
+        macMap.put(CP11, HOST_MAC);
+        macMap.put(CP12, HOST_MAC);
+        macMap.put(CP21, HOST_MAC2);
+
+        target.activate();
+    }
+
+    /**
+     * Tears down this unit test.
+     */
+    @After
+    public void tearDown() {
+        target.deactivate();
+        target = null;
+    }
+
+    /**
+     * Tests the process port added method for new addition case.
+     */
+    @Test
+    public void testProcessPortAddedForNewAddition() {
+        org.onosproject.net.Port port = new DefaultPort(DEV2, P1, true, ANNOTATIONS);
+        target.processPortAdded(port);
+
+        HostId hostId = HostId.hostId(HOST_MAC2);
+        HostDescription hostDesc = new DefaultHostDescription(
+                HOST_MAC2,
+                VlanId.NONE,
+                new HostLocation(CP21, System.currentTimeMillis()),
+                ImmutableSet.of(),
+                ANNOTATIONS
+
+        );
+
+        verifyHostResult(hostId, hostDesc);
+    }
+
+    /**
+     * Tests the process port added method for updating case.
+     */
+    @Test
+    public void testProcessPortAddedForUpdate() {
+        org.onosproject.net.Port port = new DefaultPort(DEV1, P1, true, ANNOTATIONS);
+        target.processPortAdded(port);
+
+        HostId hostId = HostId.hostId(HOST_MAC);
+        HostDescription hostDesc = new DefaultHostDescription(
+                HOST_MAC,
+                VlanId.NONE,
+                new HostLocation(CP11, System.currentTimeMillis()),
+                ImmutableSet.of(),
+                ANNOTATIONS
+        );
+
+        verifyHostResult(hostId, hostDesc);
+    }
+
+    /**
+     * Tests the process port added method for migration case.
+     */
+    @Test
+    public void testProcessPortAddedForMigration() {
+        org.onosproject.net.Port port = new DefaultPort(DEV1, P2, true, ANNOTATIONS);
+        target.processPortAdded(port);
+
+        HostId hostId = HostId.hostId(HOST_MAC);
+
+        verifyHostLocationResult(hostId, HOST_LOC12);
+    }
+
+    /**
+     * Mocks the CoreService.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new DefaultApplicationId(100, "hostProviderTestApp");
+        }
+    }
+
+    /**
+     * Mocks the DeviceService.
+     */
+    private class TestDeviceService extends DeviceServiceAdapter {
+    }
+
+    /**
+     * Mocks the HostService.
+     */
+    private class TestHostService extends HostServiceAdapter {
+
+        @Override
+        public Host getHost(HostId hostId) {
+            return hostMap.get(hostId);
+        }
+    }
+
+    /**
+     * Mocks the HostProviderService.
+     */
+    private class TestHostProviderService implements HostProviderService {
+
+        @Override
+        public void hostDetected(HostId hostId, HostDescription hostDescription,
+                                 boolean replaceIps) {
+            resultHostId = hostId;
+            resultHostDesc = hostDescription;
+        }
+
+        @Override
+        public void hostVanished(HostId hostId) {
+
+        }
+
+        @Override
+        public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
+
+        }
+
+        @Override
+        public void removeLocationFromHost(HostId hostId, HostLocation location) {
+
+        }
+
+        @Override
+        public void addLocationToHost(HostId hostId, HostLocation location) {
+            resultHostId = hostId;
+            resultHostLocation = location;
+        }
+
+        @Override
+        public HostProvider provider() {
+            return null;
+        }
+    }
+
+    /**
+     * Mocks the HostProviderRegistry.
+     */
+    private class TestHostProviderRegistry implements HostProviderRegistry {
+
+        @Override
+        public HostProviderService register(HostProvider provider) {
+            return new TestHostProviderService();
+        }
+
+        @Override
+        public void unregister(HostProvider provider) {
+
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+    }
+
+    /**
+     * Mocks the MastershipService.
+     */
+    private class TestMastershipService extends MastershipServiceAdapter {
+    }
+
+    /**
+     * Mocks the OpenstackNodeService.
+     */
+    private class TestOpenstackNodeService extends OpenstackNodeServiceAdapter {
+    }
+
+    /**
+     * Mocks the OpenstackNetworkService.
+     */
+    private class TestOpenstackNetworkService extends OpenstackNetworkServiceAdapter {
+
+        @Override
+        public Port port(org.onosproject.net.Port port) {
+            Port osPort = NeutronPort.builder()
+                                        .networkId(NETWORK_ID)
+                                        .fixedIp(IP_ADDRESS, SUBNET_ID)
+                                        .macAddress(macMap.get(
+                                                new ConnectPoint(port.element().id(),
+                                                        port.number())).toString())
+                                        .build();
+            osPort.setId(PORT_ID);
+
+            return osPort;
+        }
+
+        @Override
+        public Network network(String networkId) {
+            Network osNetwork = NeutronNetwork.builder()
+                                        .networkType(NetworkType.VXLAN)
+                                        .segmentId(SEGMENT_ID)
+                                        .build();
+            osNetwork.setId(NETWORK_ID);
+            return osNetwork;
+        }
+    }
+
+    /**
+     * Verifies the HostId and HostDescription.
+     *
+     * @param hostId        host identifier
+     * @param hostDesc      host description
+     */
+    private void verifyHostResult(HostId hostId, HostDescription hostDesc) {
+        assertEquals(hostId, resultHostId);
+        assertEquals(hostDesc.hwAddress(), resultHostDesc.hwAddress());
+        assertEquals(hostDesc.annotations().value(NETWORK_ID),
+                resultHostDesc.annotations().value(NETWORK_ID));
+    }
+
+    /**
+     * Verifies the HostId and HostLocation.
+     *
+     * @param hostId        host identifier
+     * @param hostLocation  host location
+     */
+    private void verifyHostLocationResult(HostId hostId, HostLocation hostLocation) {
+        assertEquals(hostId, resultHostId);
+        assertEquals(hostLocation.deviceId(), resultHostLocation.deviceId());
+        assertEquals(hostLocation.port(), resultHostLocation.port());
+    }
+}
