Merge branch 'master' of github.com:floodlight/loxigen

Conflicts:
	java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
new file mode 100644
index 0000000..25fc943
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPAddressTest.java
@@ -0,0 +1,54 @@
+package org.projectfloodlight.openflow.types;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Most tests are in IPv4AddressTest and IPv6AddressTest
+ * Just exception testing here
+ * @author gregor
+ *
+ */
+public class IPAddressTest {
+    @Test
+    public void testOfException() {
+        try {
+            IPAddress.of("Foobar");
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            IPAddressWithMask.of("Foobar");
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            IPAddress.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPAddressWithMask.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPAddress.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPAddressWithMask.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
+
+}
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
index c00fad4..334ec0d 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv4AddressTest.java
@@ -3,7 +3,10 @@
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import org.hamcrest.CoreMatchers;
@@ -39,6 +42,7 @@
             "1.2..3.4",
             "1.2.3.4.",
             "257.11.225.1",
+            "256.11.225.1",
             "-1.2.3.4",
             "1.2.3.4.5",
             "1.x.3.4",
@@ -50,7 +54,10 @@
                             "192.168.130.140/255.255.192.0",
                             "127.0.0.1/8",
                             "8.8.8.8",
-                            "0.0.0.0/0"
+                            "8.8.8.8/32",
+                            "0.0.0.0/0",
+                            "192.168.130.140/255.0.255.0",
+                            "1.2.3.4/0.127.0.255"
     };
 
     boolean[] hasMask = {
@@ -58,6 +65,9 @@
                          true,
                          true,
                          false,
+                         false,
+                         true,
+                         true,
                          true
     };
 
@@ -65,8 +75,32 @@
                              new byte[][] { new byte[] { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04 }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0x00 } },
                              new byte[][] { new byte[] { (byte)0xC0, (byte)0xA8, (byte)0x82, (byte)0x8C }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xC0, (byte)0x00 } },
                              new byte[][] { new byte[] { (byte)0x7F, (byte)0x00, (byte)0x00, (byte)0x01 }, new byte[] { (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0x00 } },
-                             new byte[][] { new byte[] { (byte)0x08, (byte)0x08, (byte)0x08, (byte)0x08 }, null },
-                             new byte[][] { new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 } }
+                             new byte[][] { new byte[] { (byte)0x08, (byte)0x08, (byte)0x08, (byte)0x08 }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF } },
+                             new byte[][] { new byte[] { (byte)0x08, (byte)0x08, (byte)0x08, (byte)0x08 }, new byte[] { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF } },
+                             new byte[][] { new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 } },
+                             new byte[][] { new byte[] { (byte)0xC0, (byte)0xA8, (byte)0x82, (byte)0x8C }, new byte[] { (byte)0xFF, (byte)0x00, (byte)0xFF, (byte)0x00 } },
+                             new byte[][] { new byte[] { (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04 }, new byte[] { (byte)0x00, (byte)0x7F, (byte)0x00, (byte)0xFF } }
+    };
+
+    int[] ipsWithMaskLengths = {
+                                24,
+                                18,
+                                8,
+                                32,
+                                32,
+                                0,
+                                -1,
+                                -1
+    };
+
+    String[] invalidIpsWithMask = {
+                                   "asdf",
+                                   "1.2.3.4/33",
+                                   "1.2.3.4/34",
+                                   "1.2.3.4/-1",
+                                   "1.2.3.4/256.0.0.0",
+                                   "1.256.3.4/255.255.0.0",
+                                   "1.2.3.4/255.255.0.0.0",
     };
 
     @Test
@@ -118,6 +152,35 @@
 
 
     @Test
+    public void testConstants() {
+        byte[] zeros = { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };
+        byte[] ones =  { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
+        // Make sure class initializtation and static assignment don't get
+        // messed up. Test everything twice for cached values
+        assertTrue(IPv4Address.NONE.isCidrMask());
+        assertEquals(0, IPv4Address.NONE.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv4Address.NONE.getBytes());
+        assertTrue(IPv4Address.NONE.isCidrMask());
+        assertEquals(0, IPv4Address.NONE.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv4Address.NONE.getBytes());
+
+        assertTrue(IPv4Address.NO_MASK.isCidrMask());
+        assertEquals(32, IPv4Address.NO_MASK.asCidrMaskLength());
+        assertArrayEquals(ones, IPv4Address.NO_MASK.getBytes());
+        assertTrue(IPv4Address.NO_MASK.isCidrMask());
+        assertEquals(32, IPv4Address.NO_MASK.asCidrMaskLength());
+        assertArrayEquals(ones, IPv4Address.NO_MASK.getBytes());
+
+        assertTrue(IPv4Address.FULL_MASK.isCidrMask());
+        assertEquals(0, IPv4Address.FULL_MASK.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv4Address.FULL_MASK.getBytes());
+        assertTrue(IPv4Address.FULL_MASK.isCidrMask());
+        assertEquals(0, IPv4Address.FULL_MASK.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv4Address.FULL_MASK.getBytes());
+    }
+
+
+    @Test
     public void testOfString() {
         for(int i=0; i < testAddresses.length; i++ ) {
             IPv4Address ip = IPv4Address.of(testStrings[i]);
@@ -167,18 +230,111 @@
             if (!hasMask[i]) {
                 IPv4Address ip = value.getValue();
                 assertArrayEquals(ipsWithMaskValues[i][0], ip.getBytes());
-            } else if (hasMask[i]) {
-                byte[] ipBytes = new byte[4];
-                System.arraycopy(ipsWithMaskValues[i][0], 0, ipBytes, 0, 4);
-                assertEquals(ipBytes.length, value.getValue().getBytes().length);
-                for (int j = 0; j < ipBytes.length; j++) {
-                    ipBytes[j] &= ipsWithMaskValues[i][1][j];
-                }
-
-                assertArrayEquals(ipBytes, value.getValue().getBytes());
-                assertThat(String.format("Byte comparison for mask of %s (%s)", ipsWithMask[i], value),
-                        value.getMask().getBytes(), CoreMatchers.equalTo(ipsWithMaskValues[i][1]));
             }
+            IPv4Address mask = value.getMask();
+            if (ipsWithMaskLengths[i] == -1) {
+                assertFalse(mask.isCidrMask());
+                try {
+                    mask.asCidrMaskLength();
+                    fail("Expected IllegalStateException not thrown");
+                } catch(IllegalStateException e) {
+                    //expected
+                }
+            } else {
+                assertTrue(mask.isCidrMask());
+                assertEquals(ipsWithMaskLengths[i], mask.asCidrMaskLength());
+            }
+            assertArrayEquals(ipsWithMaskValues[i][1], mask.getBytes());
+            byte[] ipBytes = new byte[4];
+            System.arraycopy(ipsWithMaskValues[i][0], 0, ipBytes, 0, 4);
+            assertEquals(ipBytes.length, value.getValue().getBytes().length);
+            for (int j = 0; j < ipBytes.length; j++) {
+                ipBytes[j] &= ipsWithMaskValues[i][1][j];
+            }
+
+            assertArrayEquals(ipBytes, value.getValue().getBytes());
+            assertThat(String.format("Byte comparison for mask of %s (%s)", ipsWithMask[i], value),
+                    value.getMask().getBytes(), CoreMatchers.equalTo(ipsWithMaskValues[i][1]));
+        }
+    }
+
+    @Test
+    public void testOfMaskedInvalid() throws Exception {
+        for(String invalid : invalidIpsWithMask) {
+            try {
+                IPv4Address.of(invalid);
+                fail("Invalid IP "+invalid+ " should have raised IllegalArgumentException");
+            } catch(IllegalArgumentException e) {
+                // ok
+            }
+        }
+    }
+
+    @Test
+    public void testSuperclass() throws Exception {
+        for(String ipString: testStrings) {
+            IPAddress<?> superIp = IPAddress.of(ipString);
+            assertEquals(IPVersion.IPv4, superIp.getIpVersion());
+            assertEquals(IPv4Address.of(ipString), superIp);
+        }
+
+        for(String ipMaskedString: ipsWithMask) {
+            IPAddressWithMask<?> superIp = IPAddressWithMask.of(ipMaskedString);
+            assertEquals(IPVersion.IPv4, superIp.getIpVersion());
+            assertEquals(IPv4AddressWithMask.of(ipMaskedString), superIp);
+        }
+    }
+
+    @Test
+    public void testOfExceptions() {
+        // We check if the message of a caught NPE is set to a useful message
+        // as a hacky way of verifying that we got an NPE thrown by use rather
+        // than one the JVM created for a null access.
+        try {
+            String s = null;
+            IPv4Address.of(s);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            byte[] b = null;
+            IPv4Address.of(b);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            byte[] b = new byte[3];
+            IPv4Address.of(b);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            byte[] b = new byte[5];
+            IPv4Address.of(b);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            IPv4AddressWithMask.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPv4AddressWithMask.of(IPv4Address.of("1.2.3.4"), null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPv4AddressWithMask.of(null, IPv4Address.of("255.0.0.0"));
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
         }
     }
 }
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
index 6eb5743..c521292 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/IPv6AddressTest.java
@@ -1,9 +1,6 @@
 package org.projectfloodlight.openflow.types;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -31,6 +28,7 @@
     private class WithMaskTaskCase {
         final String input;
         boolean hasMask;
+        int expectedMaskLength = 128;
         byte[] expectedMask = hex.decode("ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff".replaceAll(" ", ""));
 
         public WithMaskTaskCase(String input) {
@@ -45,22 +43,73 @@
             return this;
         }
 
+        public WithMaskTaskCase expectedMaskLength(int expectedLength) {
+            this.expectedMaskLength = expectedLength;
+            return this;
+        }
+
     }
 
     WithMaskTaskCase[] withMasks = new WithMaskTaskCase[] {
             new WithMaskTaskCase("1::1/80")
-                .maskHex("ff ff ff ff ff ff ff ff ff ff 00 00 00 00 00 00"),
+                .maskHex("ff ff ff ff ff ff ff ff ff ff 00 00 00 00 00 00")
+                .expectedMaskLength(80),
 
             new WithMaskTaskCase("ffff:ffee:1::/ff00:ff00:ff00:ff00::")
-                .maskHex("ff 00 ff 00 ff 00 ff 00 00 00 00 00 00 00 00 00"),
+                .maskHex("ff 00 ff 00 ff 00 ff 00 00 00 00 00 00 00 00 00")
+                .expectedMaskLength(-1),
+            new WithMaskTaskCase("1:2:3:4:5:6:7:8/1::ff00:ff00")
+                .maskHex("00 01 00 00 00 00 00 00 00 00 00 00 ff 00 ff 00")
+                .expectedMaskLength(-1),
+            new WithMaskTaskCase("1:2:3:4:5:6:7:8/::ff00:ff00")
+                .maskHex("00 00 00 00 00 00 00 00 00 00 00 00 ff 00 ff 00")
+                .expectedMaskLength(-1),
+            new WithMaskTaskCase("1:2:3:4:5:6:7:8/ffff:ffff:ffff:ffff:ffff::ff00:ff00")
+                .maskHex("ff ff ff ff ff ff ff ff ff ff 00 00 ff 00 ff 00")
+                .expectedMaskLength(-1),
             new WithMaskTaskCase("8:8:8:8:8:8:8:8"),
             new WithMaskTaskCase("8:8:8:8:8:8:8:8"),
             new WithMaskTaskCase("1:2:3:4:5:6:7:8/128"),
             new WithMaskTaskCase("::/0")
                 .maskHex("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00")
+                .expectedMaskLength(0),
     };
 
     @Test
+    public void testConstants() {
+        byte[] zeros = { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
+                         (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 };
+        byte[] ones = { (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
+                        (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
+                        (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF,
+                        (byte)0xFF, (byte)0xFF, (byte)0xFF, (byte)0xFF };
+        // Make sure class initializtation and static assignment don't get
+        // messed up. Test everything twice for cached values
+        assertTrue(IPv6Address.NONE.isCidrMask());
+        assertEquals(0, IPv6Address.NONE.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv6Address.NONE.getBytes());
+        assertTrue(IPv6Address.NONE.isCidrMask());
+        assertEquals(0, IPv6Address.NONE.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv6Address.NONE.getBytes());
+
+        assertTrue(IPv6Address.NO_MASK.isCidrMask());
+        assertEquals(128, IPv6Address.NO_MASK.asCidrMaskLength());
+        assertArrayEquals(ones, IPv6Address.NO_MASK.getBytes());
+        assertTrue(IPv6Address.NO_MASK.isCidrMask());
+        assertEquals(128, IPv6Address.NO_MASK.asCidrMaskLength());
+        assertArrayEquals(ones, IPv6Address.NO_MASK.getBytes());
+
+        assertTrue(IPv6Address.FULL_MASK.isCidrMask());
+        assertEquals(0, IPv6Address.FULL_MASK.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv6Address.FULL_MASK.getBytes());
+        assertTrue(IPv6Address.FULL_MASK.isCidrMask());
+        assertEquals(0, IPv6Address.FULL_MASK.asCidrMaskLength());
+        assertArrayEquals(zeros, IPv6Address.FULL_MASK.getBytes());
+    }
+
+    @Test
     public void testMasked() throws UnknownHostException {
         for(WithMaskTaskCase w: withMasks) {
             IPv6AddressWithMask value = IPv6AddressWithMask.of(w.input);
@@ -70,19 +119,37 @@
 
                 assertArrayEquals(ip.getBytes(), inetAddress.getAddress());
                 assertEquals(w.input.split("/")[0], ip.toString());
-            } else {
-                InetAddress inetAddress = InetAddress.getByName(w.input.substring(0, w.input.indexOf('/')));
-
-                byte[] address = inetAddress.getAddress();
-                assertEquals(address.length, value.getValue().getBytes().length);
-
-                for (int j = 0; j < address.length; j++) {
-                    address[j] &= w.expectedMask[j];
-                }
-
-                assertThat("Address bytes for input " + w.input + ", value=" + value, value.getValue().getBytes(), CoreMatchers.equalTo(address));
-                assertThat("mask check for input " + w.input + ", value=" + value, value.getMask().getBytes(), CoreMatchers.equalTo(w.expectedMask));
             }
+            InetAddress inetAddress = InetAddress.getByName(w.input.split("/")[0]);
+
+            if (w.expectedMaskLength == -1) {
+                assertFalse(value.getMask().isCidrMask());
+                try {
+                    value.getMask().asCidrMaskLength();
+                    fail("Expected IllegalStateException not thrown");
+                } catch(IllegalStateException e) {
+                    //expected
+                }
+            } else {
+                assertTrue(value.getMask().isCidrMask());
+                assertEquals("Input " + w.input, w.expectedMaskLength,
+                             value.getMask().asCidrMaskLength());
+            }
+
+            byte[] address = inetAddress.getAddress();
+            assertEquals(address.length, value.getValue().getBytes().length);
+
+            for (int j = 0; j < address.length; j++) {
+                address[j] &= w.expectedMask[j];
+            }
+
+            assertThat("Address bytes for input " + w.input + ", value=" + value, value.getValue().getBytes(), CoreMatchers.equalTo(address));
+            assertThat("mask check for input " + w.input + ", value=" + value, value.getMask().getBytes(), CoreMatchers.equalTo(w.expectedMask));
+        }
+        for (int i = 0; i <= 128; i++) {
+            String ipString = String.format("8001:2::1/%d", i);
+            IPv6AddressWithMask value = IPv6AddressWithMask.of(ipString);
+            assertEquals("Input " + ipString, i, value.getMask().asCidrMaskLength());
         }
     }
 
@@ -150,4 +217,70 @@
         assertEquals("1::4:5:6:0:8", IPv6Address.of("1:0:0:4:5:6:0:8").toString(true, false));
         assertEquals("1:0:0:4::8", IPv6Address.of("1:0:0:4:0:0:0:8").toString(true, false));
     }
+
+    @Test
+    public void testSuperclass() throws Exception {
+        for(String ipString: testStrings) {
+            IPAddress<?> superIp = IPAddress.of(ipString);
+            assertEquals(IPVersion.IPv6, superIp.getIpVersion());
+            assertEquals(IPv6Address.of(ipString), superIp);
+        }
+
+        for(WithMaskTaskCase w: withMasks) {
+            String ipMaskedString = w.input;
+            IPAddressWithMask<?> superIp = IPAddressWithMask.of(ipMaskedString);
+            assertEquals(IPVersion.IPv6, superIp.getIpVersion());
+            assertEquals(IPv6AddressWithMask.of(ipMaskedString), superIp);
+        }
+    }
+
+    @Test
+    public void testOfExceptions() throws Exception {
+        try {
+            IPv6AddressWithMask.of(null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            String s = null;
+            IPv6Address.of(s);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            byte[] b = null;
+            IPv6Address.of(b);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            byte[] b = new byte[7];
+            IPv6Address.of(b);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            byte[] b = new byte[9];
+            IPv6Address.of(b);
+            fail("Should have thrown IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        try {
+            IPv6AddressWithMask.of(IPv6Address.of("1::"), null);
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+        try {
+            IPv6AddressWithMask.of(null, IPv6Address.of("255::"));
+            fail("Should have thrown NullPointerException");
+        } catch (NullPointerException e) {
+            assertNotNull(e.getMessage());
+        }
+    }
 }