[ONOS-5916] Add various MappingAddress impl classes with unit tests

Change-Id: Ie373601d1406d161e8071e78cd584e5cc8b8f5af
diff --git a/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/addresses/MappingAddressesTest.java b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/addresses/MappingAddressesTest.java
new file mode 100644
index 0000000..d55bba7
--- /dev/null
+++ b/apps/mappingmanagement/api/src/test/java/org/onosproject/mapping/addresses/MappingAddressesTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.mapping.addresses;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.junit.UtilityClassChecker.assertThatClassIsUtility;
+
+/**
+ * Unit tests for various mapping address implementation classes.
+ */
+public class MappingAddressesTest {
+
+    private final String asn1 = "1";
+    private final String asn2 = "2";
+    private MappingAddress asMa1 = MappingAddresses.asMappingAddress(asn1);
+    private MappingAddress sameAsAsMa1 = MappingAddresses.asMappingAddress(asn1);
+    private MappingAddress asMa2 = MappingAddresses.asMappingAddress(asn2);
+
+    private final String dn1 = "1";
+    private final String dn2 = "2";
+    private MappingAddress dnMa1 = MappingAddresses.dnMappingAddress(dn1);
+    private MappingAddress sameAsDnMa1 = MappingAddresses.dnMappingAddress(dn1);
+    private MappingAddress dnMa2 = MappingAddresses.dnMappingAddress(dn2);
+
+    private static final String MAC1 = "00:00:00:00:00:01";
+    private static final String MAC2 = "00:00:00:00:00:02";
+    private MacAddress mac1 = MacAddress.valueOf(MAC1);
+    private MacAddress mac2 = MacAddress.valueOf(MAC2);
+    private MappingAddress ethMa1 = MappingAddresses.ethMappingAddress(mac1);
+    private MappingAddress sameAsEthMa1 = MappingAddresses.ethMappingAddress(mac1);
+    private MappingAddress ethMa2 = MappingAddresses.ethMappingAddress(mac2);
+
+    private static final String IP1 = "1.2.3.4/24";
+    private static final String IP2 = "5.6.7.8/24";
+    private static final String IPV61 = "fe80::1/64";
+    private static final String IPV62 = "fc80::2/64";
+    private IpPrefix ip1 = IpPrefix.valueOf(IP1);
+    private IpPrefix ip2 = IpPrefix.valueOf(IP2);
+    private IpPrefix ipv61 = IpPrefix.valueOf(IPV61);
+    private IpPrefix ipv62 = IpPrefix.valueOf(IPV62);
+    private MappingAddress ipMa1 = MappingAddresses.ipv4MappingAddress(ip1);
+    private MappingAddress sameAsIpMa1 = MappingAddresses.ipv4MappingAddress(ip1);
+    private MappingAddress ipMa2 = MappingAddresses.ipv4MappingAddress(ip2);
+    private MappingAddress ipv6Ma1 = MappingAddresses.ipv6MappingAddress(ipv61);
+    private MappingAddress sameAsIpv6Ma1 = MappingAddresses.ipv6MappingAddress(ipv61);
+    private MappingAddress ipv6Ma2 = MappingAddresses.ipv6MappingAddress(ipv62);
+
+    /**
+     * Checks that a MappingAddress object has the proper type, and then converts
+     * it to the proper type.
+     *
+     * @param address MappingAddress object to convert
+     * @param type    Enumerated type value for the MappingAddress class
+     * @param clazz   Desired MappingAddress class
+     * @param <T>     The type the caller wants returned
+     * @return converted object
+     */
+    @SuppressWarnings("unchecked")
+    private <T> T checkAndConvert(MappingAddress address, MappingAddress.Type type, Class clazz) {
+        assertThat(address, is(notNullValue()));
+        assertThat(address.type(), is(equalTo(type)));
+        assertThat(address, instanceOf(clazz));
+        return (T) address;
+    }
+
+    /**
+     * Checks the equals() and toString() methods of a MappingAddress class.
+     *
+     * @param c1      first object to compare
+     * @param c1match object that should be equal to the first
+     * @param c2      object that should not be equal to the first
+     * @param <T>     type of the arguments
+     */
+    private <T extends MappingAddress> void checkEqualsAndToString(T c1,
+                                                                   T c1match,
+                                                                   T c2) {
+        new EqualsTester()
+                .addEqualityGroup(c1, c1match)
+                .addEqualityGroup(c2)
+                .testEquals();
+    }
+
+    /**
+     * Checks that the MappingAddresses class is a valid utility class.
+     */
+    @Test
+    public void testMappingAddressesUtility() {
+        assertThatClassIsUtility(MappingAddresses.class);
+    }
+
+    /**
+     * Checks that the mapping address implementations are immutable.
+     */
+    @Test
+    public void testMappingAddressesImmutability() {
+        assertThatClassIsImmutable(ASMappingAddress.class);
+        assertThatClassIsImmutable(DNMappingAddress.class);
+        assertThatClassIsImmutable(EthMappingAddress.class);
+        assertThatClassIsImmutable(ExtensionMappingAddress.class);
+        assertThatClassIsImmutable(IPMappingAddress.class);
+    }
+
+    /**
+     * Tests the asMappingAddress method.
+     */
+    @Test
+    public void testAsMappingAddressMethod() {
+        String asn = "1";
+        MappingAddress mappingAddress = MappingAddresses.asMappingAddress(asn);
+        ASMappingAddress asMappingAddress =
+                checkAndConvert(mappingAddress,
+                                MappingAddress.Type.AS,
+                                ASMappingAddress.class);
+        assertThat(asMappingAddress.asNumber(), is(equalTo(asn)));
+    }
+
+    /**
+     * Tests the equals() method of the ASMappingAddress class.
+     */
+    @Test
+    public void testAsMappingAddressEquals() {
+        checkEqualsAndToString(asMa1, sameAsAsMa1, asMa2);
+    }
+
+    /**
+     * Tests the dnMappingAddress method.
+     */
+    @Test
+    public void testDnMappingAddressMethod() {
+        String dn = "1";
+        MappingAddress mappingAddress = MappingAddresses.dnMappingAddress(dn);
+        DNMappingAddress dnMappingAddress =
+                checkAndConvert(mappingAddress,
+                                MappingAddress.Type.DN,
+                                DNMappingAddress.class);
+        assertThat(dnMappingAddress.name(), is(equalTo(dn)));
+    }
+
+    /**
+     * Tests the equals() method of the DNMappingAddress class.
+     */
+    @Test
+    public void testDnMappingAddressEquals() {
+        checkEqualsAndToString(dnMa1, sameAsDnMa1, dnMa2);
+    }
+
+    /**
+     * Tests the ethMappingAddress method.
+     */
+    @Test
+    public void testEthMappingAddressMethod() {
+        MacAddress mac = MacAddress.valueOf("00:00:00:00:00:01");
+        MappingAddress mappingAddress = MappingAddresses.ethMappingAddress(mac);
+        EthMappingAddress ethMappingAddress =
+                checkAndConvert(mappingAddress,
+                                MappingAddress.Type.ETH,
+                                EthMappingAddress.class);
+        assertThat(ethMappingAddress.mac(), is(equalTo(mac)));
+    }
+
+    /**
+     * Tests the equals() method of the EthMappingAddress class.
+     */
+    @Test
+    public void testEthMappingAddressEquals() {
+        checkEqualsAndToString(ethMa1, sameAsEthMa1, ethMa2);
+    }
+
+    /**
+     * Tests the ipv4MappingAddress method.
+     */
+    @Test
+    public void testIpv4MappingAddressMethod() {
+        IpPrefix ip = IpPrefix.valueOf("1.2.3.4/24");
+        MappingAddress mappingAddress = MappingAddresses.ipv4MappingAddress(ip);
+        IPMappingAddress ipMappingAddress =
+                checkAndConvert(mappingAddress,
+                                MappingAddress.Type.IPV4,
+                                IPMappingAddress.class);
+        assertThat(ipMappingAddress.ip(), is(equalTo(ip)));
+    }
+
+    /**
+     * Tests the equals() method of the IPMappingAddress class.
+     */
+    @Test
+    public void testIpv4MappingAddressEquals() {
+        checkEqualsAndToString(ipMa1, sameAsIpMa1, ipMa2);
+    }
+
+    /**
+     * Tests the ipv6MappingAddress method.
+     */
+    @Test
+    public void testIpv6MappingAddressMethod() {
+        IpPrefix ipv6 = IpPrefix.valueOf("fe80::1/64");
+        MappingAddress mappingAddress = MappingAddresses.ipv6MappingAddress(ipv6);
+        IPMappingAddress ipMappingAddress =
+                checkAndConvert(mappingAddress,
+                                MappingAddress.Type.IPV6,
+                                IPMappingAddress.class);
+        assertThat(ipMappingAddress.ip(), is(equalTo(ipv6)));
+    }
+
+    /**
+     * Tests the equals() method of the IPMappingAddress class.
+     */
+    @Test
+    public void testIpv6MappingAddressEquals() {
+        checkEqualsAndToString(ipv6Ma1, sameAsIpv6Ma1, ipv6Ma2);
+    }
+}