Experimenter support for TableFeatures 80/4180/4
authorMichal Polkorab <michal.polkorab@pantheon.sk>
Thu, 9 Jan 2014 15:42:20 +0000 (16:42 +0100)
committerMichal Polkorab <michal.polkorab@pantheon.sk>
Tue, 14 Jan 2014 08:43:25 +0000 (09:43 +0100)
+ deserialization fix
+ MatchIdsReader renamed to MatchIdsDeserializer
+ MatchIdsWriter renamed to MatchIdsSerializer

Change-Id: I86dc16b7cc8c1d83e5212f3c3cd8502bb0f8335d
Signed-off-by: Michal Polkorab <michal.polkorab@pantheon.sk>
13 files changed:
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsSerializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/EncodeConstants.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsDeserializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsSerializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsDeserializer.java [moved from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsReader.java with 96% similarity]
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsSerializer.java [moved from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsWriter.java with 98% similarity]
openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchSerializer.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java
openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java [new file with mode: 0644]

index 628d388d5bd588359296d6f02e2538a8ec3d1e30..eb0669166a2380a0101453d74eff30aa61fc6af6 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.openflowjava.protocol.impl.util.MatchDeserializer;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeaturePropertyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeaturePropertyBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder;
@@ -426,6 +427,13 @@ public class MultipartReplyMessageFactory implements OFDeserializer<MultipartRep
                 ExperimenterRelatedTableFeaturePropertyBuilder expBuilder = new ExperimenterRelatedTableFeaturePropertyBuilder();
                 expBuilder.setExperimenter(input.readUnsignedInt());
                 expBuilder.setExpType(input.readUnsignedInt());
+                int dataLength = propertyLength - COMMON_PROPERTY_LENGTH - 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES;
+                if (dataLength > 0) {
+                    byte[] data = new byte[dataLength];
+                    input.readBytes(data);
+                    expBuilder.setData(data);
+                }
+                builder.addAugmentation(ExperimenterRelatedTableFeatureProperty.class, expBuilder.build());
             }
             if (paddingRemainder != 0) {
                 input.skipBytes(EncodeConstants.PADDING - paddingRemainder);
index c1e37fba1167030858b1b1876e54cac62aaf2cb5..ac4a3105df3be1c964eb7509d8d5e5b041187854 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.ActionsList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Experimenter;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
@@ -480,7 +481,13 @@ public class MultipartRequestInputFactory implements OFSerializer<MultipartReque
         int length = TABLE_FEAT_HEADER_LENGTH;
         int padding = 0;
         if (instructions != null) {
-            length += instructions.size() * STRUCTURE_HEADER_LENGTH;
+            for (Instructions instruction : instructions) {
+                if (instruction.getType().isAssignableFrom(Experimenter.class)) {
+                    length += EncodeConstants.EXPERIMENTER_IDS_LENGTH;
+                } else {
+                    length += STRUCTURE_HEADER_LENGTH;
+                }
+            }
             padding = paddingNeeded(length);
             output.writeShort(length);
             InstructionsSerializer.encodeInstructionIds(instructions, output);
@@ -529,6 +536,13 @@ public class MultipartRequestInputFactory implements OFSerializer<MultipartReque
         int length = TABLE_FEAT_HEADER_LENGTH;
         int padding = 0;
         if (actions != null) {
+            for (ActionsList action : actions) {
+                if (action.getAction().getType().isAssignableFrom(Experimenter.class)) {
+                    length += EncodeConstants.EXPERIMENTER_IDS_LENGTH;
+                } else {
+                    length += STRUCTURE_HEADER_LENGTH;
+                }
+            }
             length += actions.size() * STRUCTURE_HEADER_LENGTH;
             padding += paddingNeeded(length);
             output.writeShort(length);
@@ -548,6 +562,7 @@ public class MultipartRequestInputFactory implements OFSerializer<MultipartReque
         int length = TABLE_FEAT_HEADER_LENGTH;
         int padding = 0;
         if (entries != null) {
+            // experimenter length / definition ?
             length += entries.size() * STRUCTURE_HEADER_LENGTH;
             padding = paddingNeeded(length);
             output.writeShort(length);
@@ -566,16 +581,20 @@ public class MultipartRequestInputFactory implements OFSerializer<MultipartReque
                 getAugmentation(ExperimenterRelatedTableFeatureProperty.class);
         byte[] data = exp.getData();
         int length = TABLE_FEAT_HEADER_LENGTH + 2 * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
+        int padding = 0;
         if (data != null) {
             output.writeShort(length + data.length);
+            padding = paddingNeeded(length + data.length);
             output.writeInt(exp.getExperimenter().intValue());
             output.writeInt(exp.getExpType().intValue());
             output.writeBytes(data);
         } else {
             output.writeShort(length);
+            padding = paddingNeeded(length);
             output.writeInt(exp.getExperimenter().intValue());
             output.writeInt(exp.getExpType().intValue());
         }
+        ByteBufUtils.padBuffer(padding, output);
     }
 
     private static int createTableConfigBitmask(TableConfig tableConfig) {
index ff8d2942f54a2328edd27f3636be7cb8eecc0520..f4227fdcf978739815d70ce565efda7308f0e297 100644 (file)
@@ -208,6 +208,9 @@ public abstract class ActionsDeserializer {
                 break;
             case 0xFFFF:
                 builder.setType(Experimenter.class);
+                ExperimenterActionBuilder experimenter = new ExperimenterActionBuilder();
+                experimenter.setExperimenter(input.readUnsignedInt());
+                builder.addAugmentation(ExperimenterAction.class, experimenter.build());
                 break;
             default: 
                 break;
index 31754dcf995160a21d7048a7ab2596294b24649c..51a3359faa566fc617c4bfafd6c3a8ff43d1b1ac 100644 (file)
@@ -82,7 +82,6 @@ public abstract class ActionsSerializer {
     private static final byte PADDING_IN_ACTION_HEADER = 4;
     private static final byte ETHERTYPE_ACTION_PADDING = 2;
     private static final byte ACTION_IDS_LENGTH = 4;
-    
 
 
     /**
@@ -178,7 +177,9 @@ public abstract class ActionsSerializer {
             } else if (action.getType().isAssignableFrom(PopPbb.class)) {
                 writeTypeAndLength(outBuffer, POP_PBB_CODE, ACTION_IDS_LENGTH);
             } else if (action.getType().isAssignableFrom(Experimenter.class)) {
-                writeTypeAndLength(outBuffer, EXPERIMENTER_CODE, ACTION_IDS_LENGTH);
+                writeTypeAndLength(outBuffer, EXPERIMENTER_CODE, EncodeConstants.EXPERIMENTER_IDS_LENGTH);
+                ExperimenterAction experimenter = action.getAugmentation(ExperimenterAction.class);
+                outBuffer.writeInt(experimenter.getExperimenter().intValue());
             } 
         }
     }
index c07ae1de4ed1c566d221f4c05598701149451b37..0615b182960b8b77fa3ac21c88f8bc1666387d1e 100644 (file)
@@ -44,4 +44,6 @@ public abstract class EncodeConstants {
 
     /** OF v1.0 maximal port name length */
     public static final byte MAX_PORT_NAME_LENGTH = 16;
+    /** OF v1.3 lenght of experimenter_ids - see Multipart TableFeatures (properties) message */
+    public static final byte EXPERIMENTER_IDS_LENGTH = 8;
 }
index a8cb2803b25a5a37a8b92ffc927e28df8f8425e4..d5adc97a3fcc80e4057357de33e8fa33b0394fea 100644 (file)
@@ -143,6 +143,9 @@ public abstract class InstructionsDeserializer {
                     break;
                 case 65535:
                     builder.setType(Experimenter.class);
+                    ExperimenterInstructionBuilder expBuilder = new ExperimenterInstructionBuilder();
+                    expBuilder.setExperimenter(input.readUnsignedInt());
+                    builder.addAugmentation(ExperimenterInstruction.class, expBuilder.build());
                     break;
                 default:
                     break;
index 196a7246314fc17e43bde66737e2f884851f3d59..be90d891142335745fe427afd8bf469033d73fe1 100644 (file)
@@ -117,7 +117,9 @@ public abstract class InstructionsSerializer {
                 } else if (type.isAssignableFrom(Meter.class)) {
                     writeTypeAndLength(out, METER_TYPE, INSTRUCTION_IDS_LENGTH);
                 } else if (type.isAssignableFrom(Experimenter.class)) {
-                    writeTypeAndLength(out, EXPERIMENTER_TYPE, EXPERIMENTER_LENGTH);
+                    ExperimenterInstruction experimenter = instruction.getAugmentation(ExperimenterInstruction.class);
+                    writeTypeAndLength(out, EXPERIMENTER_TYPE, EncodeConstants.EXPERIMENTER_IDS_LENGTH);
+                    out.writeInt(experimenter.getExperimenter().intValue());
                 }
             }
         }
index 6eec7b56d7a4f8e36416e2cb4b97019750a0809b..06d8d583f07da6d67003fa0f45206efec9fac362 100644 (file)
@@ -492,7 +492,7 @@ public abstract class MatchDeserializer {
      * @return list of match ids
      */
     public static List<MatchEntries> createMatchIds(ByteBuf in, int matchLength) {
-        return MatchIdsReader.createOxmIds(in, matchLength);
+        return MatchIdsDeserializer.createOxmIds(in, matchLength);
     }
 
     private static void addMaskAugmentation(MatchEntriesBuilder builder, ByteBuf in, int matchEntryLength) {
similarity index 96%
rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsReader.java
rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsDeserializer.java
index 9ecdc0cc3c72b8c8dcd64359e70b8fd00e22c574..6961ed87a7c1705359217c3f67a9859265e14026 100644 (file)
@@ -63,7 +63,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.
  * Encodes match ids (oxm_ids) needed in Multipart-TableFeatures messages\r
  * @author michal.polkorab\r
  */\r
-public abstract class MatchIdsReader {\r
+public abstract class MatchIdsDeserializer {\r
 \r
     /** Decodes oxm ids\r
      * @param in input ByteBuf\r
@@ -96,9 +96,9 @@ public abstract class MatchIdsReader {
             boolean hasMask = (fieldAndMask & 1) != 0;\r
             matchEntriesBuilder.setHasMask(hasMask);\r
             int matchField =  fieldAndMask >> 1;\r
-            int matchEntryLength = in.readUnsignedByte();\r
+            in.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);\r
             currLength += EncodeConstants.SIZE_OF_SHORT_IN_BYTES +\r
-                    (2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES) + matchEntryLength;\r
+                    (2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES);\r
 \r
             switch(matchField) {\r
             case 0:\r
similarity index 98%
rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsWriter.java
rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchIdsSerializer.java
index e3961078037b8299e3d03cfc2d7e4ee7ebb26730..85d92adf88aee3ad1c1d226f84e99e60046df4a7 100644 (file)
@@ -56,7 +56,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.
  * Encodes match ids (oxm_ids) needed in Multipart-TableFeatures messages\r
  * @author michal.polkorab\r
  */\r
-public abstract class MatchIdsWriter {\r
+public abstract class MatchIdsSerializer {\r
 \r
     /**\r
      * Encodes oxm headers (without values) \r
index e54087c869fdf162f6e6f9e08965eb8044d34a6d..adae1e243e2a9f880459b9fe8afd6b19fd068c94 100644 (file)
@@ -166,7 +166,7 @@ public abstract class MatchSerializer {
         }
         for (MatchEntries entry : matchEntries) {
             encodeClass(entry.getOxmClass(), out);
-            MatchIdsWriter.encodeIdsRest(entry, out);
+            MatchIdsSerializer.encodeIdsRest(entry, out);
         }
     }
 
index d18def9c46e190e0ac2d22230f64b8b68154ecc9..fe50e8789d07094e661cd6bb3317b865989e1952 100644 (file)
@@ -12,11 +12,8 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.UnpooledByteBufAllocator;
 
 import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.Assert;
 
+import org.junit.Assert;
 import org.junit.Test;
 import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest;
 import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
@@ -25,7 +22,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody;
@@ -46,8 +42,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
@@ -57,17 +51,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;
 
 /**
  * @author timotej.kubas
  * @author michal.polkorab
  */
 public class MultipartRequestInputFactoryTest {
-    private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;
+    /** padding in MultipartRequest message */
+    public static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4;
 
     /**
      * @throws Exception
@@ -497,83 +488,4 @@ public class MultipartRequestInputFactoryTest {
         return caseBuilder.build();
     }
 
-    /**
-     * @throws Exception
-     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO
-     */
-    @Test
-    public void testMultipartRequestTableFeaturesMessageFactory() throws Exception {
-        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
-        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
-        builder.setType(MultipartType.forValue(12));
-        builder.setFlags(new MultipartRequestFlags(true));
-        builder.setMultipartRequestBody(createRequestTableFeatures());
-        MultipartRequestInput message = builder.build();
-
-        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
-        MultipartRequestInputFactory factory = MultipartRequestInputFactory.getInstance();
-        factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message);
-
-        BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message));
-        Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readUnsignedShort());
-        Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort()));
-        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
-        MultipartRequestTableFeaturesCase messageTableFeaturesCase = (MultipartRequestTableFeaturesCase) message.getMultipartRequestBody();
-        MultipartRequestTableFeatures messageTableFeatures = messageTableFeaturesCase.getMultipartRequestTableFeatures();
-        Assert.assertEquals("Wrong tableFeaturesBody", messageTableFeatures.getTableFeatures(), decodeRequestTableFeatures(out).
-                getMultipartRequestTableFeatures().getTableFeatures());
-    }
-
-    private static MultipartRequestTableFeaturesCase createRequestTableFeatures() {
-        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
-        MultipartRequestTableFeaturesBuilder builder = new MultipartRequestTableFeaturesBuilder();
-        List<TableFeatures> tableFeaturesList = new ArrayList<>();
-        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
-        tableFeaturesBuilder.setTableId((short) 8);
-        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
-        tableFeaturesBuilder.setMetadataMatch(new BigInteger(1, new byte[] {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}));
-        tableFeaturesBuilder.setMetadataWrite(new BigInteger(1, new byte[] {0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}));
-        tableFeaturesBuilder.setConfig(new TableConfig(true));
-        tableFeaturesBuilder.setMaxEntries(65L);
-        TableFeatures tableFeature = tableFeaturesBuilder.build();
-        tableFeaturesList.add(tableFeature);
-        builder.setTableFeatures(tableFeaturesList);
-        caseBuilder.setMultipartRequestTableFeatures(builder.build());
-        return caseBuilder.build();
-    }
-
-    private static MultipartRequestTableFeaturesCase decodeRequestTableFeatures(ByteBuf output) {
-        final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5;
-        final byte OFP_MAX_TABLE_NAME_LEN = 32;
-        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
-        MultipartRequestTableFeaturesBuilder builder = new MultipartRequestTableFeaturesBuilder();
-        List<TableFeatures> tableFeaturesList = new ArrayList<>();
-        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
-        output.skipBytes(2);
-        tableFeaturesBuilder.setTableId(output.readUnsignedByte());
-        output.skipBytes(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY);
-        byte[] tableNameBytes = new byte[OFP_MAX_TABLE_NAME_LEN];
-        output.readBytes(tableNameBytes);
-        String tableName = new String(tableNameBytes);
-        tableFeaturesBuilder.setName(tableName.trim());
-        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
-        output.readBytes(metadataMatch);
-        tableFeaturesBuilder.setMetadataMatch(new BigInteger(1, metadataMatch));
-        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
-        output.readBytes(metadataWrite);
-        tableFeaturesBuilder.setMetadataWrite(new BigInteger(1, metadataWrite));
-        tableFeaturesBuilder.setConfig(decodeTableConfig(output.readInt()));
-        tableFeaturesBuilder.setMaxEntries(output.readUnsignedInt());
-        TableFeatures tableFeature = tableFeaturesBuilder.build();
-        tableFeaturesList.add(tableFeature);
-        builder.setTableFeatures(tableFeaturesList);
-        caseBuilder.setMultipartRequestTableFeatures(builder.build());
-        return caseBuilder.build();
-    }
-
-    private static TableConfig decodeTableConfig(int input) {
-        final Boolean _oFPTCDEPRECATEDMASK = (input & (1 << 3)) > 0;
-        return new TableConfig(_oFPTCDEPRECATEDMASK);
-    }
-
 }
diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/TableFeaturesTest.java
new file mode 100644 (file)
index 0000000..a8843e5
--- /dev/null
@@ -0,0 +1,284 @@
+/*\r
+ * Copyright (c) 2013 Pantheon Technologies s.r.o. and others.  All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+package org.opendaylight.openflowjava.protocol.impl.serialization.factories.multipart;\r
+\r
+import io.netty.buffer.ByteBuf;\r
+import io.netty.buffer.UnpooledByteBufAllocator;\r
+\r
+import java.math.BigInteger;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest;\r
+import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory;\r
+import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest;\r
+import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;\r
+import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;\r
+import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeaturePropertyBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ClearActions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.Meter;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteActions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm1Class;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeatureProperties;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.TableFeaturePropertiesBuilder;\r
+\r
+/**\r
+ * @author michal.polkorab\r
+ *\r
+ */\r
+public class TableFeaturesTest {\r
+    private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE =\r
+            MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE;\r
+\r
+    /**\r
+     * @throws Exception\r
+     * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO\r
+     */\r
+    @Test\r
+    public void testMultipartRequestTableFeaturesMessageFactory() throws Exception {\r
+        MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();\r
+        BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);\r
+        builder.setType(MultipartType.forValue(12));\r
+        builder.setFlags(new MultipartRequestFlags(true));\r
+        MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();\r
+        MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();\r
+        List<TableFeatures> tableFeaturesList = new ArrayList<>();\r
+        TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();\r
+        tableFeaturesBuilder.setTableId((short) 8);\r
+        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");\r
+        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));\r
+        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));\r
+        tableFeaturesBuilder.setConfig(new TableConfig(true));\r
+        tableFeaturesBuilder.setMaxEntries(65L);\r
+        List<TableFeatureProperties> properties = new ArrayList<>();\r
+        TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES);\r
+        NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder =\r
+                new NextTableRelatedTableFeaturePropertyBuilder();\r
+        List<NextTableIds> nextIds = new ArrayList<>();\r
+        nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build());\r
+        nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build());\r
+        nextPropBuilder.setNextTableIds(nextIds);\r
+        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS);\r
+        nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder();\r
+        nextIds = new ArrayList<>();\r
+        nextIds.add(new NextTableIdsBuilder().setTableId((short) 3).build());\r
+        nextPropBuilder.setNextTableIds(nextIds);\r
+        propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS);\r
+        InstructionRelatedTableFeaturePropertyBuilder insPropBuilder =\r
+                new InstructionRelatedTableFeaturePropertyBuilder();\r
+        List<Instructions> insIds = new ArrayList<>();\r
+        InstructionsBuilder insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(WriteActions.class);\r
+        insIds.add(insBuilder.build());\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(GotoTable.class);\r
+        insIds.add(insBuilder.build());\r
+        insPropBuilder.setInstructions(insIds);\r
+        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS);\r
+        insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder();\r
+        insIds = new ArrayList<>();\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(WriteMetadata.class);\r
+        insIds.add(insBuilder.build());\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(ApplyActions.class);\r
+        insIds.add(insBuilder.build());\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(Meter.class);\r
+        insIds.add(insBuilder.build());\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(ClearActions.class);\r
+        insIds.add(insBuilder.build());\r
+        insBuilder = new InstructionsBuilder();\r
+        insBuilder.setType(GotoTable.class);\r
+        insIds.add(insBuilder.build());\r
+        insPropBuilder.setInstructions(insIds);\r
+        propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        tableFeaturesBuilder.setTableFeatureProperties(properties);\r
+        tableFeaturesList.add(tableFeaturesBuilder.build());\r
+        tableFeaturesBuilder = new TableFeaturesBuilder();\r
+        tableFeaturesBuilder.setTableId((short) 8);\r
+        tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");\r
+        tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));\r
+        tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));\r
+        tableFeaturesBuilder.setConfig(new TableConfig(true));\r
+        tableFeaturesBuilder.setMaxEntries(67L);\r
+        properties = new ArrayList<>();\r
+        propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH);\r
+        OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
+        List<MatchEntries> entries = new ArrayList<>();\r
+        MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+        entriesBuilder.setOxmMatchField(InPhyPort.class);\r
+        entriesBuilder.setHasMask(false);\r
+        entries.add(entriesBuilder.build());\r
+        entriesBuilder = new MatchEntriesBuilder();\r
+        entriesBuilder.setOxmClass(Nxm0Class.class);\r
+        entriesBuilder.setOxmMatchField(InPort.class);\r
+        entriesBuilder.setHasMask(false);\r
+        entries.add(entriesBuilder.build());\r
+        oxmBuilder.setMatchEntries(entries);\r
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        propBuilder = new TableFeaturePropertiesBuilder();\r
+        propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD);\r
+        oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();\r
+        entries = new ArrayList<>();\r
+        entriesBuilder = new MatchEntriesBuilder();\r
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
+        entriesBuilder.setOxmMatchField(IpProto.class);\r
+        entriesBuilder.setHasMask(false);\r
+        entries.add(entriesBuilder.build());\r
+        entriesBuilder = new MatchEntriesBuilder();\r
+        entriesBuilder.setOxmClass(Nxm1Class.class);\r
+        entriesBuilder.setOxmMatchField(IpEcn.class);\r
+        entriesBuilder.setHasMask(false);\r
+        entries.add(entriesBuilder.build());\r
+        oxmBuilder.setMatchEntries(entries);\r
+        propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());\r
+        properties.add(propBuilder.build());\r
+        tableFeaturesBuilder.setTableFeatureProperties(properties);\r
+        tableFeaturesList.add(tableFeaturesBuilder.build());\r
+        featuresBuilder.setTableFeatures(tableFeaturesList);\r
+        caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());\r
+        builder.setMultipartRequestBody(caseBuilder.build());\r
+        MultipartRequestInput message = builder.build();\r
+\r
+        ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();\r
+        MultipartRequestInputFactory factory = MultipartRequestInputFactory.getInstance();\r
+        factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message);\r
+\r
+        BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message));\r
+        Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());\r
+        out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);\r
+        Assert.assertEquals("Wrong length", 120, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong table-id", 8, out.readUnsignedByte());\r
+        out.skipBytes(5);\r
+        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",\r
+                ByteBufUtils.decodeNullTerminatedString(out, 32));\r
+        byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
+        out.readBytes(metadataMatch);\r
+        Assert.assertArrayEquals("Wrong metadata-match",\r
+                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);\r
+        byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
+        out.readBytes(metadataWrite);\r
+        Assert.assertArrayEquals("Wrong metadata-write",\r
+                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);\r
+        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());\r
+        Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());\r
+        Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong next-table-id", 1, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong next-table-id", 2, out.readUnsignedByte());\r
+        out.skipBytes(2);\r
+        Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 5, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong next-table-id", 3, out.readUnsignedByte());\r
+        out.skipBytes(3);\r
+        Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        out.skipBytes(4);\r
+        Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong length", 96, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong table-id", 8, out.readUnsignedByte());\r
+        out.skipBytes(5);\r
+        Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",\r
+                ByteBufUtils.decodeNullTerminatedString(out, 32));\r
+        metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
+        out.readBytes(metadataMatch);\r
+        Assert.assertArrayEquals("Wrong metadata-match",\r
+                new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);\r
+        metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];\r
+        out.readBytes(metadataWrite);\r
+        Assert.assertArrayEquals("Wrong metadata-write",\r
+                new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);\r
+        Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());\r
+        Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt());\r
+        Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match class", 0, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());\r
+        out.skipBytes(4);\r
+        Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match class", 1, out.readUnsignedShort());\r
+        Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte());\r
+        Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());\r
+        out.skipBytes(4);\r
+        Assert.assertTrue("Unread data", out.readableBytes() == 0);\r
+    }\r
+\r
+}\r