2 * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.impl.protocol.deserialization.messages;
11 import static org.junit.Assert.assertEquals;
13 import io.netty.buffer.ByteBuf;
14 import io.netty.buffer.UnpooledByteBufAllocator;
15 import org.junit.Test;
16 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
17 import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants;
18 import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants;
19 import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
20 import org.opendaylight.openflowjava.util.ByteBufUtils;
21 import org.opendaylight.openflowplugin.impl.protocol.deserialization.AbstractDeserializerTest;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopPbbActionCase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowMessage;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand;
29 public class FlowMessageDeserializerTest extends AbstractDeserializerTest {
31 private static final byte PADDING = 2;
33 private static final int TYPE = 14;
34 private static final int XID = 42;
35 private static final FlowModCommand COMMAND = FlowModCommand.OFPFCADD;
36 private static final int BUFFER_ID = 26;
37 private static final int OUT_PORT = 22;
38 private static final int OUT_GROUP = 25;
40 private static final boolean SEND_FLOWREM = true;
41 private static final boolean RESET_COUNTS = false;
42 private static final boolean NO_PKTCOUNTS = true;
43 private static final boolean NO_BYTCOUNTS = true;
44 private static final boolean CHECK_OVERLAP = false;
46 private static final FlowModFlags FLAGS = new FlowModFlags(
47 CHECK_OVERLAP, NO_BYTCOUNTS, NO_PKTCOUNTS, RESET_COUNTS, SEND_FLOWREM);
48 private static final long COOKIE = 12;
49 private static final long COOKIE_MASK = 14;
50 private static final int TABLE_ID = 2;
51 private static final int IDLE_TIMEOUT = 20;
52 private static final int HARD_TIMEOUT = 35;
53 private static final int PRIORITY = 100;
54 private static final int OXM_MATCH_TYPE_CODE = 1;
55 private static final int MPLS_LABEL = 135;
57 private ByteBuf buffer;
60 protected void init() {
61 buffer = UnpooledByteBufAllocator.DEFAULT.buffer();
65 public void deserialize() {
67 buffer.writeByte(TYPE);
68 buffer.writeShort(EncodeConstants.EMPTY_LENGTH);
70 buffer.writeLong(COOKIE);
71 buffer.writeLong(COOKIE_MASK);
72 buffer.writeByte(TABLE_ID);
73 buffer.writeByte(COMMAND.getIntValue());
74 buffer.writeShort(IDLE_TIMEOUT);
75 buffer.writeShort(HARD_TIMEOUT);
76 buffer.writeShort(PRIORITY);
77 buffer.writeInt(BUFFER_ID);
78 buffer.writeInt(OUT_PORT);
79 buffer.writeInt(OUT_GROUP);
80 buffer.writeShort(ByteBufUtils.fillBitMask(0,
81 FLAGS.isSENDFLOWREM(),
82 FLAGS.isCHECKOVERLAP(),
83 FLAGS.isRESETCOUNTS(),
84 FLAGS.isNOPKTCOUNTS(),
85 FLAGS.isNOBYTCOUNTS()));
86 buffer.writeZero(PADDING);
89 int matchStartIndex = buffer.writerIndex();
90 buffer.writeShort(OXM_MATCH_TYPE_CODE);
91 int matchLengthIndex = buffer.writerIndex();
92 buffer.writeShort(EncodeConstants.EMPTY_LENGTH);
95 buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS);
96 buffer.writeByte(OxmMatchConstants.MPLS_LABEL << 1);
97 buffer.writeByte(EncodeConstants.SIZE_OF_INT_IN_BYTES);
98 buffer.writeInt(MPLS_LABEL);
101 int matchLength = buffer.writerIndex() - matchStartIndex;
102 buffer.setShort(matchLengthIndex, matchLength);
103 int paddingRemainder = matchLength % EncodeConstants.PADDING;
104 if (paddingRemainder != 0) {
105 buffer.writeZero(EncodeConstants.PADDING - paddingRemainder);
108 // Instructions header
109 int instructionStartIndex = buffer.writerIndex();
110 buffer.writeShort(InstructionConstants.APPLY_ACTIONS_TYPE);
111 int instructionLengthIndex = buffer.writerIndex();
112 buffer.writeShort(EncodeConstants.EMPTY_LENGTH);
113 buffer.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION);
116 buffer.writeShort(ActionConstants.POP_PBB_CODE);
117 buffer.writeShort(ActionConstants.GENERAL_ACTION_LENGTH);
118 buffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER);
120 // Count total length of instructions
121 buffer.setShort(instructionLengthIndex, buffer.writerIndex() - instructionStartIndex);
123 // Deserialize and check everything
124 final FlowMessage message = (FlowMessage) getFactory()
125 .deserialize(buffer, EncodeConstants.OF13_VERSION_ID);
127 assertEquals(XID, message.getXid().intValue());
128 assertEquals(COMMAND.getIntValue(), message.getCommand().getIntValue());
129 assertEquals(MPLS_LABEL, message.getMatch().getProtocolMatchFields().getMplsLabel().intValue());
130 assertEquals(1, message.getInstructions().getInstruction().size());
132 final Instruction instruction = message.getInstructions().nonnullInstruction().values().iterator().next()
134 assertEquals(ApplyActionsCase.class, instruction.implementedInterface());
136 final ApplyActionsCase applyActions = (ApplyActionsCase) instruction;
137 assertEquals(1, applyActions.getApplyActions().getAction().size());
138 assertEquals(PopPbbActionCase.class, applyActions.getApplyActions().nonnullAction().values().iterator().next()
139 .getAction().implementedInterface());