Unit test for Kryo namespaces to prevent people overflowing the namespaces.

Change-Id: If37283da60d59558c87e2997690b4578952ad3bf
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 67d9df1..76167eb 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -234,6 +234,7 @@
 
 public final class KryoNamespaces {
 
+    public static final int BASIC_MAX_SIZE = 50;
     public static final KryoNamespace BASIC = KryoNamespace.newBuilder()
             .nextId(KryoNamespace.FLOATING_ID)
             .register(byte[].class)
@@ -284,6 +285,7 @@
     /**
      * KryoNamespace which can serialize ON.lab misc classes.
      */
+    public static final int MISC_MAX_SIZE = 30;
     public static final KryoNamespace MISC = KryoNamespace.newBuilder()
             .nextId(KryoNamespace.FLOATING_ID)
             .register(new IpPrefixSerializer(), IpPrefix.class)
@@ -302,20 +304,15 @@
             .build("MISC");
 
     /**
-     * Kryo registration Id for user custom registration.
-     */
-    public static final int BEGIN_USER_CUSTOM_ID = 500;
-
-    // TODO: Populate other classes
-    /**
      * KryoNamespace which can serialize API bundle classes.
      */
+    public static final int API_MAX_SIZE = 499;
     public static final KryoNamespace API = KryoNamespace.newBuilder()
             .nextId(KryoNamespace.INITIAL_ID)
             .register(BASIC)
-            .nextId(KryoNamespace.INITIAL_ID + 50)
+            .nextId(KryoNamespace.INITIAL_ID + BASIC_MAX_SIZE)
             .register(MISC)
-            .nextId(KryoNamespace.INITIAL_ID + 50 + 30)
+            .nextId(KryoNamespace.INITIAL_ID + BASIC_MAX_SIZE + MISC_MAX_SIZE)
             .register(
                     Instructions.MeterInstruction.class,
                     MeterId.class,
@@ -552,6 +549,10 @@
             .register(new ImmutableByteSequenceSerializer(), ImmutableByteSequence.class)
             .build("API");
 
+    /**
+     * Kryo registration Id for user custom registration.
+     */
+    public static final int BEGIN_USER_CUSTOM_ID = API_MAX_SIZE + 1;
 
     // not to be instantiated
     private KryoNamespaces() {
diff --git a/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoNamespacesTest.java b/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoNamespacesTest.java
new file mode 100644
index 0000000..4187569
--- /dev/null
+++ b/core/store/serializers/src/test/java/org/onosproject/store/serializers/KryoNamespacesTest.java
@@ -0,0 +1,42 @@
+package org.onosproject.store.serializers;
+
+import org.junit.Test;
+import org.onlab.util.KryoNamespace;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests pre-defined Kryo namespaces to catch basic errors such as someone
+ * adding too many registrations which may flow into another namespace.
+ */
+public class KryoNamespacesTest {
+
+    /**
+     * Verifies that the BASIC namespace has not exceeded its allocated size.
+     */
+    @Test
+    public void basicNamespaceSizeTest() {
+        testNamespaceSize(KryoNamespaces.BASIC, KryoNamespaces.BASIC_MAX_SIZE);
+    }
+
+    /**
+     * Verifies that the MISC namespace has not exceeded its allocated size.
+     */
+    @Test
+    public void miscNamespaceSizeTest() {
+        testNamespaceSize(KryoNamespaces.MISC, KryoNamespaces.MISC_MAX_SIZE);
+    }
+
+    /**
+     * Verifies that the API namespace has not exceeded its allocated size.
+     */
+    @Test
+    public void apiNamespaceSizeTest() {
+        testNamespaceSize(KryoNamespaces.API, KryoNamespaces.API_MAX_SIZE);
+    }
+
+    private void testNamespaceSize(KryoNamespace namespace, int maxSize) {
+        assertTrue("Kryo namespace has exceeded its allocated size",
+                namespace.size() < maxSize);
+    }
+}
diff --git a/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java b/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java
index d1f95c0..5fb1afc 100644
--- a/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java
+++ b/utils/misc/src/main/java/org/onlab/util/KryoNamespace.java
@@ -79,7 +79,6 @@
     private final boolean registrationRequired;
     private final String friendlyName;
 
-
     /**
      * KryoNamespace builder.
      */
@@ -406,6 +405,17 @@
     }
 
     /**
+     * Gets the number of classes registered in this Kryo namespace.
+     *
+     * @return size of namespace
+     */
+    public int size() {
+        return (int) registeredBlocks.stream()
+                .flatMap(block -> block.types().stream())
+                .count();
+    }
+
+    /**
      * Creates a Kryo instance.
      *
      * @return Kryo instance