/* * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowplugin.impl.protocol.deserialization.multipart; import static org.junit.Assert.assertEquals; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; 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.TableFeaturesPropType; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.multipart.reply.multipart.reply.body.MultipartReplyTableFeatures; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplyActions; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplyActionsMiss; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplySetfield; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.ApplySetfieldMiss; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.InstructionsMiss; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.NextTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.NextTableMiss; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.Wildcards; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteActions; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteActionsMiss; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteSetfield; import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature.prop.type.WriteSetfieldMiss; public class MultipartReplyTableFeaturesDeserializerTest extends AbstractMultipartDeserializerTest { private static final byte PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES = 5; private static final byte MAX_TABLE_NAME_LENGTH = 32; private static final byte TABLE_ID = 1; private static final long METADATA_MATCH = 2; private static final long METADATA_WRITE = 3; private static final int TABLE_CONFIG= 3; private static final int MAX_ENTRIES= 3; private static final int OFPTFPT_INSTRUCTIONS = 0; private static final int OFPTFPT_INSTRUCTIONS_MISS = 1; private static final int OFPTFPT_NEXT_TABLES = 2; private static final int OFPTFPT_NEXT_TABLES_MISS = 3; private static final int OFPTFPT_WRITE_ACTIONS = 4; private static final int OFPTFPT_WRITE_ACTIONS_MISS = 5; private static final int OFPTFPT_APPLY_ACTIONS = 6; private static final int OFPTFPT_APPLY_ACTIONS_MISS = 7; private static final int OFPTFPT_MATCH = 8; private static final int OFPTFPT_WILDCARDS = 10; private static final int OFPTFPT_WRITE_SETFIELD = 12; private static final int OFPTFPT_WRITE_SETFIELD_MISS = 13; private static final int OFPTFPT_APPLY_SETFIELD = 14; private static final int OFPTFPT_APPLY_SETFIELD_MISS = 15; @Test public void deserialize() throws Exception { ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.buffer(); writeValues(buffer, OFPTFPT_INSTRUCTIONS); MultipartReplyTableFeatures reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(TABLE_ID, reply.getTableFeatures().get(0).getTableId().byteValue()); assertEquals(METADATA_MATCH, reply.getTableFeatures().get(0).getMetadataMatch().longValue()); assertEquals(METADATA_WRITE, reply.getTableFeatures().get(0).getMetadataWrite().longValue()); assertEquals(MAX_ENTRIES, reply.getTableFeatures().get(0).getMaxEntries().longValue()); assertEquals(MAX_ENTRIES, reply.getTableFeatures().get(0).getMaxEntries().longValue()); assertEquals(Instructions.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_INSTRUCTIONS_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(InstructionsMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_NEXT_TABLES); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(NextTable.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_NEXT_TABLES_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(NextTableMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_WRITE_ACTIONS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(WriteActions.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_WRITE_ACTIONS_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(WriteActionsMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_APPLY_ACTIONS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(ApplyActions.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_APPLY_ACTIONS_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(ApplyActionsMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_MATCH); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(Match.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_WILDCARDS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(Wildcards.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_WRITE_SETFIELD); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(WriteSetfield.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_WRITE_SETFIELD_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(WriteSetfieldMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_APPLY_SETFIELD); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(ApplySetfield.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); writeValues(buffer, OFPTFPT_APPLY_SETFIELD_MISS); reply = (MultipartReplyTableFeatures) deserializeMultipart(buffer); assertEquals(ApplySetfieldMiss.class, reply.getTableFeatures().get(0).getTableProperties() .getTableFeatureProperties().get(0).getTableFeaturePropType().getImplementedInterface()); assertEquals(0, buffer.readableBytes()); } private void writeValues(ByteBuf buffer, int propertyType) { TableFeaturesPropType propType = TableFeaturesPropType.forValue(propertyType); buffer.clear(); int replyIndex = buffer.readerIndex(); buffer.writeShort(EncodeConstants.EMPTY_LENGTH); buffer.writeByte(TABLE_ID); buffer.writeZero(PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES); buffer.writeZero(MAX_TABLE_NAME_LENGTH); buffer.writeLong(METADATA_MATCH); buffer.writeLong(METADATA_WRITE); buffer.writeInt(TABLE_CONFIG); buffer.writeInt(MAX_ENTRIES); int propIndex = buffer.writerIndex(); buffer.writeShort(propertyType); int propLengthIndex = buffer.writerIndex(); buffer.writeShort(EncodeConstants.EMPTY_LENGTH); switch (propType) { case OFPTFPTINSTRUCTIONS: case OFPTFPTINSTRUCTIONSMISS: int instructionStartIndex = buffer.writerIndex(); buffer.writeShort(InstructionConstants.APPLY_ACTIONS_TYPE); int instructionLengthIndex = buffer.writerIndex(); buffer.writeShort(EncodeConstants.EMPTY_LENGTH); buffer.setShort(instructionLengthIndex, buffer.writerIndex() - instructionStartIndex); break; case OFPTFPTNEXTTABLES: case OFPTFPTNEXTTABLESMISS: buffer.writeByte(1); buffer.writeByte(2); break; case OFPTFPTWRITEACTIONS: case OFPTFPTWRITEACTIONSMISS: buffer.writeShort(InstructionConstants.WRITE_ACTIONS_TYPE); buffer.writeShort(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTAPPLYACTIONS: case OFPTFPTAPPLYACTIONSMISS: buffer.writeShort(InstructionConstants.APPLY_ACTIONS_TYPE); buffer.writeShort(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTMATCH: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ARP_OP << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTWILDCARDS: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ARP_SHA << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTWRITESETFIELD: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ARP_SPA << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTWRITESETFIELDMISS: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ARP_THA << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTAPPLYSETFIELD: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ARP_TPA << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; case OFPTFPTAPPLYSETFIELDMISS: buffer.writeShort(OxmMatchConstants.OPENFLOW_BASIC_CLASS); buffer.writeByte(OxmMatchConstants.ETH_TYPE << 1); buffer.writeByte(EncodeConstants.EMPTY_LENGTH); break; default: break; } int propLength = buffer.writerIndex() - propIndex; buffer.setShort(propLengthIndex, buffer.writerIndex() - propIndex); int paddingRemainder = propLength % EncodeConstants.PADDING; int result = 0; if (paddingRemainder != 0) { result = EncodeConstants.PADDING - paddingRemainder; } buffer.writeZero(result); buffer.setShort(replyIndex, buffer.writerIndex() - replyIndex); } @Override protected int getType() { return MultipartType.OFPMPTABLEFEATURES.getIntValue(); } }