Jonathan Hart

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

Change-Id: If37283da60d59558c87e2997690b4578952ad3bf
......@@ -234,6 +234,7 @@ import java.util.concurrent.atomic.AtomicLong;
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 @@ public final class KryoNamespaces {
/**
* 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 @@ public final class KryoNamespaces {
.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 @@ public final class KryoNamespaces {
.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() {
......
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);
}
}
......@@ -79,7 +79,6 @@ public final class KryoNamespace implements KryoFactory, KryoPool {
private final boolean registrationRequired;
private final String friendlyName;
/**
* KryoNamespace builder.
*/
......@@ -406,6 +405,17 @@ public final class KryoNamespace implements KryoFactory, KryoPool {
}
/**
* 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
......