Add unit test for openstack switching host provider

Change-Id: If2ff5cf7d361d3857aca14b67e8d66ced0aacaa6
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());
+    }
+}