Bug 2756 - Action model update
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / FlowModInputMessageFactoryTest.java
index 6a9ee5623f1e317d50c563a8f16a8860fff6b0b0..4c3caa4d98ab110fa18ff9b9744a3afa48cc1163 100644 (file)
@@ -16,36 +16,46 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactoryTest;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
 import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
-import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataInstructionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstruction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TableIdInstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionsInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionsInstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.MetadataInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.MetadataInstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.TableIdInstruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.TableIdInstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.ApplyActions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.GotoTable;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.WriteMetadata;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.Instructions;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Nxm0Class;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntries;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.MatchEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.phy.port._case.InPhyPortBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.match.grouping.MatchBuilder;
 
 /**
  * @author timotej.kubas
@@ -53,19 +63,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
  */
 public class FlowModInputMessageFactoryTest {
     private static final byte PADDING_IN_FLOW_MOD_MESSAGE = 2;
-    
+    private SerializerRegistry registry;
+    private OFSerializer<FlowModInput> flowModFactory;
+
+    /**
+     * Initializes serializer registry and stores correct factory in field
+     */
+    @Before
+    public void startUp() {
+        registry = new SerializerRegistryImpl();
+        registry.init();
+        flowModFactory = registry.getSerializer(new MessageTypeKey<>(
+                EncodeConstants.OF13_VERSION_ID, FlowModInput.class));
+    }
+
     /**
-     * @throws Exception 
+     * @throws Exception
      * Testing of {@link FlowModInputMessageFactory} for correct translation from POJO
      */
     @Test
     public void testFlowModInputMessageFactory() throws Exception {
         FlowModInputBuilder builder = new FlowModInputBuilder();
         BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
-        byte[] cookie = new byte[]{0x00, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01};
-        builder.setCookie(new BigInteger(cookie));
-        byte[] cookieMask = new byte[]{0x01, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30};
-        builder.setCookieMask(new BigInteger(cookieMask));
+        byte[] cookie = new byte[]{(byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01};
+        builder.setCookie(new BigInteger(1, cookie));
+        byte[] cookieMask = new byte[]{(byte) 0xFF, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30};
+        builder.setCookieMask(new BigInteger(1, cookieMask));
         builder.setTableId(new TableId(65L));
         builder.setCommand(FlowModCommand.forValue(2));
         builder.setIdleTimeout(12);
@@ -77,26 +100,30 @@ public class FlowModInputMessageFactoryTest {
         builder.setFlags(new FlowModFlags(true, false, true, false, true));
         MatchBuilder matchBuilder = new MatchBuilder();
         matchBuilder.setType(OxmMatchType.class);
-        List<MatchEntries> entries = new ArrayList<>();
-        MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
+        List<MatchEntry> entries = new ArrayList<>();
+        MatchEntryBuilder entriesBuilder = new MatchEntryBuilder();
         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
         entriesBuilder.setOxmMatchField(InPhyPort.class);
         entriesBuilder.setHasMask(false);
-        PortNumberMatchEntryBuilder portNumberBuilder = new PortNumberMatchEntryBuilder();
-        portNumberBuilder.setPortNumber(new PortNumber(42L));
-        entriesBuilder.addAugmentation(PortNumberMatchEntry.class, portNumberBuilder.build());
+        InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder();
+        InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder();
+        inPhyPortBuilder.setPortNumber(new PortNumber(42L));
+        inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build());
+        entriesBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build());
         entries.add(entriesBuilder.build());
-        entriesBuilder.setOxmClass(Nxm0Class.class);
+        entriesBuilder.setOxmClass(OpenflowBasicClass.class);
         entriesBuilder.setOxmMatchField(IpEcn.class);
         entriesBuilder.setHasMask(false);
-        EcnMatchEntryBuilder ecnBuilder = new EcnMatchEntryBuilder();
-        ecnBuilder.setEcn((short) 4);
-        entriesBuilder.addAugmentation(EcnMatchEntry.class, ecnBuilder.build());
+        IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder();
+        IpEcnBuilder ipEcnBuilder = new IpEcnBuilder();
+        ipEcnBuilder.setEcn((short) 4);
+        ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build());
+        entriesBuilder.setMatchEntryValue(ipEcnCaseBuilder.build());
         entries.add(entriesBuilder.build());
-        matchBuilder.setMatchEntries(entries);
+        matchBuilder.setMatchEntry(entries);
         builder.setMatch(matchBuilder.build());
-        List<Instructions> instructions = new ArrayList<>();
-        InstructionsBuilder insBuilder = new InstructionsBuilder();
+        List<Instruction> instructions = new ArrayList<>();
+        InstructionBuilder insBuilder = new InstructionBuilder();
         insBuilder.setType(GotoTable.class);
         TableIdInstructionBuilder idBuilder = new TableIdInstructionBuilder();
         idBuilder.setTableId((short) 43);
@@ -108,16 +135,34 @@ public class FlowModInputMessageFactoryTest {
         metaBuilder.setMetadataMask(cookieMask);
         insBuilder.addAugmentation(MetadataInstruction.class, metaBuilder.build());
         instructions.add(insBuilder.build());
-        builder.setInstructions(instructions);
+        insBuilder = new InstructionBuilder();
+        insBuilder.setType(ApplyActions.class);
+        List<Action> actions = new ArrayList<>();
+        ActionBuilder actionBuilder = new ActionBuilder();
+        OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder();
+        OutputActionBuilder outputBuilder = new OutputActionBuilder();
+        outputBuilder.setPort(new PortNumber(42L));
+        outputBuilder.setMaxLength(52);
+        caseBuilder.setOutputAction(outputBuilder.build());
+        actionBuilder.setActionChoice(caseBuilder.build());
+        actions.add(actionBuilder.build());
+        ActionsInstructionBuilder actionInstructionBuilder = new ActionsInstructionBuilder();
+        actionInstructionBuilder.setAction(actions);
+        insBuilder.addAugmentation(ActionsInstruction.class, actionInstructionBuilder.build());
+        instructions.add(insBuilder.build());
+        builder.setInstruction(instructions);
         FlowModInput message = builder.build();
-        
+
         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
-        FlowModInputMessageFactory factory = FlowModInputMessageFactory.getInstance();
-        factory.messageToBuffer(HelloMessageFactoryTest.VERSION_YET_SUPPORTED, out, message);
-        
-        BufferHelper.checkHeaderV13(out, factory.getMessageType(), factory.computeLength(message));
-        Assert.assertEquals("Wrong cookie", message.getCookie().longValue(), out.readLong());
-        Assert.assertEquals("Wrong cookieMask", message.getCookieMask().longValue(), out.readLong());
+        flowModFactory.serialize(message, out);
+
+        BufferHelper.checkHeaderV13(out,(byte) 14, 128);
+        cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(cookie);
+        Assert.assertEquals("Wrong cookie", message.getCookie(), new BigInteger(1, cookie));
+        cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
+        out.readBytes(cookieMask);
+        Assert.assertEquals("Wrong cookieMask", message.getCookieMask(), new BigInteger(1,  cookieMask));
         Assert.assertEquals("Wrong tableId", message.getTableId().getValue().intValue(), out.readUnsignedByte());
         Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readUnsignedByte());
         Assert.assertEquals("Wrong idleTimeOut", message.getIdleTimeout().intValue(), out.readShort());
@@ -136,7 +181,7 @@ public class FlowModInputMessageFactoryTest {
         Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1);
         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
         Assert.assertEquals("Wrong oxm value", 42, out.readUnsignedInt());
-        Assert.assertEquals("Wrong oxm class", 0, out.readUnsignedShort());
+        Assert.assertEquals("Wrong oxm class", 0x8000, out.readUnsignedShort());
         fieldAndMask = out.readUnsignedByte();
         Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1);
         Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1);
@@ -155,13 +200,22 @@ public class FlowModInputMessageFactoryTest {
         byte[] cookieMaskRead = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
         out.readBytes(cookieMaskRead);
         Assert.assertArrayEquals("Wrong metadata", cookie, cookieRead);
-        Assert.assertArrayEquals("Wrong metadata mask", cookieMask, cookieMaskRead); 
+        Assert.assertArrayEquals("Wrong metadata mask", cookieMask, cookieMaskRead);
+        Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort());
+        Assert.assertEquals("Wrong instruction length", 24, out.readUnsignedShort());
+        out.skipBytes(4);
+        Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort());
+        Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort());
+        Assert.assertEquals("Wrong port", 42, out.readUnsignedInt());
+        Assert.assertEquals("Wrong max-length", 52, out.readUnsignedShort());
+        out.skipBytes(6);
+        Assert.assertTrue("Unread data", out.readableBytes() == 0);
     }
-    
+
     private static FlowModFlags createFlowModFlagsFromBitmap(int input){
         final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0;
         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0;
-        final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0; 
+        final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0;
         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0;
         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0;
         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, _oFPFFSENDFLOWREM);