OPNFLWPLUG-1032: Neon-MRI: Bump odlparent, yangtools, mdsal
[openflowplugin.git] / openflowjava / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / multipart / MultipartRequestTableFeaturesTest.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.openflowjava.protocol.impl.serialization.factories.multipart;
9
10 import static org.mockito.ArgumentMatchers.any;
11
12 import io.netty.buffer.ByteBuf;
13 import io.netty.buffer.UnpooledByteBufAllocator;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17 import org.junit.Assert;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.mockito.Mock;
22 import org.mockito.Mockito;
23 import org.mockito.runners.MockitoJUnitRunner;
24 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
25 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
26 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
27 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
28 import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
29 import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory;
30 import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest;
31 import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper;
32 import org.opendaylight.openflowjava.util.ByteBufUtils;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeatureProperty;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeaturePropertyBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCaseBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpProto;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
72 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;
73 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;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
76
77 /**
78  * Unit tests for MultipartRequestTableFeatures.
79  *
80  * @author michal.polkorab
81  */
82 @RunWith(MockitoJUnitRunner.class)
83 public class MultipartRequestTableFeaturesTest {
84
85     private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE =
86             MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE;
87     private SerializerRegistry registry;
88     private OFSerializer<MultipartRequestInput> multipartFactory;
89
90     @Mock SerializerRegistry mockRegistry;
91     @Mock OFSerializer<TableFeatureProperties> serializer;
92
93     /**
94      * Initializes serializer registry and stores correct factory in field.
95      */
96     @Before
97     public void startUp() {
98         Mockito.when(mockRegistry.getSerializer((MessageTypeKey<?>)any())).thenReturn(serializer);
99         registry = new SerializerRegistryImpl();
100         registry.init();
101         multipartFactory = registry.getSerializer(
102                 new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class));
103     }
104
105     /**
106      * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO.
107      */
108     @Test
109     public void testMultipartRequestTableFeaturesMessageFactory() throws Exception {
110         MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
111         BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
112         builder.setType(MultipartType.forValue(12));
113         builder.setFlags(new MultipartRequestFlags(true));
114         final MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
115         final MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();
116         TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
117         tableFeaturesBuilder.setTableId((short) 8);
118         tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
119         tableFeaturesBuilder.setMetadataMatch(new BigInteger(
120                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
121         tableFeaturesBuilder.setMetadataWrite(new BigInteger(
122                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
123         tableFeaturesBuilder.setConfig(new TableConfig(true));
124         tableFeaturesBuilder.setMaxEntries(65L);
125         TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();
126         propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES);
127         NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder =
128                 new NextTableRelatedTableFeaturePropertyBuilder();
129         List<NextTableIds> nextIds = new ArrayList<>();
130         nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build());
131         nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build());
132         nextPropBuilder.setNextTableIds(nextIds);
133         propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());
134         List<TableFeatureProperties> properties = new ArrayList<>();
135         properties.add(propBuilder.build());
136         propBuilder = new TableFeaturePropertiesBuilder();
137         propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS);
138         nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder();
139         nextIds = new ArrayList<>();
140         nextPropBuilder.setNextTableIds(nextIds);
141         propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build());
142         properties.add(propBuilder.build());
143         propBuilder = new TableFeaturePropertiesBuilder();
144         propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS);
145         List<Instruction> insIds = new ArrayList<>();
146         InstructionBuilder insBuilder = new InstructionBuilder();
147         insBuilder.setInstructionChoice(new WriteActionsCaseBuilder().build());
148         insIds.add(insBuilder.build());
149         insBuilder = new InstructionBuilder();
150         insBuilder.setInstructionChoice(new GotoTableCaseBuilder().build());
151         insIds.add(insBuilder.build());
152         InstructionRelatedTableFeaturePropertyBuilder insPropBuilder =
153                 new InstructionRelatedTableFeaturePropertyBuilder();
154         insPropBuilder.setInstruction(insIds);
155         propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());
156         properties.add(propBuilder.build());
157         propBuilder = new TableFeaturePropertiesBuilder();
158         propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS);
159         insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder();
160         insIds = new ArrayList<>();
161         insBuilder = new InstructionBuilder();
162         insBuilder.setInstructionChoice(new WriteMetadataCaseBuilder().build());
163         insIds.add(insBuilder.build());
164         insBuilder = new InstructionBuilder();
165         insBuilder.setInstructionChoice(new ApplyActionsCaseBuilder().build());
166         insIds.add(insBuilder.build());
167         insBuilder = new InstructionBuilder();
168         insBuilder.setInstructionChoice(new MeterCaseBuilder().build());
169         insIds.add(insBuilder.build());
170         insBuilder = new InstructionBuilder();
171         insBuilder.setInstructionChoice(new ClearActionsCaseBuilder().build());
172         insIds.add(insBuilder.build());
173         insBuilder = new InstructionBuilder();
174         insBuilder.setInstructionChoice(new GotoTableCaseBuilder().build());
175         insIds.add(insBuilder.build());
176         insPropBuilder.setInstruction(insIds);
177         propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build());
178         properties.add(propBuilder.build());
179         tableFeaturesBuilder.setTableFeatureProperties(properties);
180         List<TableFeatures> tableFeaturesList = new ArrayList<>();
181         tableFeaturesList.add(tableFeaturesBuilder.build());
182         tableFeaturesBuilder = new TableFeaturesBuilder();
183         tableFeaturesBuilder.setTableId((short) 8);
184         tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
185         tableFeaturesBuilder.setMetadataMatch(new BigInteger(
186                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
187         tableFeaturesBuilder.setMetadataWrite(new BigInteger(
188                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
189         tableFeaturesBuilder.setConfig(new TableConfig(true));
190         tableFeaturesBuilder.setMaxEntries(67L);
191         properties = new ArrayList<>();
192         propBuilder = new TableFeaturePropertiesBuilder();
193         propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONS);
194         ActionRelatedTableFeaturePropertyBuilder actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
195         List<Action> actions = new ArrayList<>();
196         ActionBuilder actionBuilder = new ActionBuilder();
197         actionBuilder.setActionChoice(new OutputActionCaseBuilder().build());
198         actions.add(actionBuilder.build());
199         actBuilder.setAction(actions);
200         propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
201         properties.add(propBuilder.build());
202         propBuilder = new TableFeaturePropertiesBuilder();
203         propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS);
204         actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
205         actions = new ArrayList<>();
206         actBuilder.setAction(actions);
207         propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
208         properties.add(propBuilder.build());
209         propBuilder = new TableFeaturePropertiesBuilder();
210         propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONS);
211         actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
212         actions = new ArrayList<>();
213         actBuilder.setAction(actions);
214         propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
215         properties.add(propBuilder.build());
216         propBuilder = new TableFeaturePropertiesBuilder();
217         propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS);
218         actBuilder = new ActionRelatedTableFeaturePropertyBuilder();
219         actions = new ArrayList<>();
220         actBuilder.setAction(actions);
221         propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build());
222         properties.add(propBuilder.build());
223         propBuilder = new TableFeaturePropertiesBuilder();
224         propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH);
225         MatchEntryBuilder entriesBuilder = new MatchEntryBuilder();
226         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
227         entriesBuilder.setOxmMatchField(InPhyPort.class);
228         entriesBuilder.setHasMask(false);
229         List<MatchEntry> entries = new ArrayList<>();
230         entries.add(entriesBuilder.build());
231         entriesBuilder = new MatchEntryBuilder();
232         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
233         entriesBuilder.setOxmMatchField(InPort.class);
234         entriesBuilder.setHasMask(false);
235         entries.add(entriesBuilder.build());
236         OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
237         oxmBuilder.setMatchEntry(entries);
238         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
239         properties.add(propBuilder.build());
240         propBuilder = new TableFeaturePropertiesBuilder();
241         propBuilder.setType(TableFeaturesPropType.OFPTFPTWILDCARDS);
242         oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
243         entries = new ArrayList<>();
244         oxmBuilder.setMatchEntry(entries);
245         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
246         properties.add(propBuilder.build());
247         propBuilder = new TableFeaturePropertiesBuilder();
248         propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELD);
249         oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
250         entries = new ArrayList<>();
251         oxmBuilder.setMatchEntry(entries);
252         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
253         properties.add(propBuilder.build());
254         propBuilder = new TableFeaturePropertiesBuilder();
255         propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS);
256         oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
257         entries = new ArrayList<>();
258         oxmBuilder.setMatchEntry(entries);
259         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
260         properties.add(propBuilder.build());
261         propBuilder = new TableFeaturePropertiesBuilder();
262         propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD);
263         oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
264         entries = new ArrayList<>();
265         entriesBuilder = new MatchEntryBuilder();
266         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
267         entriesBuilder.setOxmMatchField(IpProto.class);
268         entriesBuilder.setHasMask(false);
269         entries.add(entriesBuilder.build());
270         entriesBuilder = new MatchEntryBuilder();
271         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
272         entriesBuilder.setOxmMatchField(IpEcn.class);
273         entriesBuilder.setHasMask(false);
274         entries.add(entriesBuilder.build());
275         oxmBuilder.setMatchEntry(entries);
276         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
277         properties.add(propBuilder.build());
278         propBuilder = new TableFeaturePropertiesBuilder();
279         propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS);
280         oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
281         entries = new ArrayList<>();
282         oxmBuilder.setMatchEntry(entries);
283         propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
284         properties.add(propBuilder.build());
285         tableFeaturesBuilder.setTableFeatureProperties(properties);
286         tableFeaturesList.add(tableFeaturesBuilder.build());
287         featuresBuilder.setTableFeatures(tableFeaturesList);
288         caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());
289         builder.setMultipartRequestBody(caseBuilder.build());
290         MultipartRequestInput message = builder.build();
291
292         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
293         multipartFactory.serialize(message, out);
294
295         BufferHelper.checkHeaderV13(out, (byte) 18, 296);
296         Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());
297         Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());
298         out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
299         Assert.assertEquals("Wrong length", 120, out.readUnsignedShort());
300         Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
301         out.skipBytes(5);
302         Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
303                 ByteBufUtils.decodeNullTerminatedString(out, 32));
304         byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
305         out.readBytes(metadataMatch);
306         Assert.assertArrayEquals("Wrong metadata-match",
307                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
308         byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
309         out.readBytes(metadataWrite);
310         Assert.assertArrayEquals("Wrong metadata-write",
311                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
312         Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
313         Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());
314         Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort());
315         Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort());
316         Assert.assertEquals("Wrong next-registry-id", 1, out.readUnsignedByte());
317         Assert.assertEquals("Wrong next-registry-id", 2, out.readUnsignedByte());
318         out.skipBytes(2);
319         Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort());
320         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
321         out.skipBytes(4);
322         Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort());
323         Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
324         Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort());
325         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
326         Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());
327         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
328         out.skipBytes(4);
329         Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort());
330         Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort());
331         Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort());
332         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
333         Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort());
334         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
335         Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort());
336         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
337         Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort());
338         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
339         Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort());
340         Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort());
341         Assert.assertEquals("Wrong length", 160, out.readUnsignedShort());
342         Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
343         out.skipBytes(5);
344         Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
345                 ByteBufUtils.decodeNullTerminatedString(out, 32));
346         metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
347         out.readBytes(metadataMatch);
348         Assert.assertArrayEquals("Wrong metadata-match",
349                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
350         metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
351         out.readBytes(metadataWrite);
352         Assert.assertArrayEquals("Wrong metadata-write",
353                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
354         Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
355         Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt());
356         Assert.assertEquals("Wrong property type", 4, out.readUnsignedShort());
357         Assert.assertEquals("Wrong property length", 8, out.readUnsignedShort());
358         Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort());
359         Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort());
360         Assert.assertEquals("Wrong property type", 5, out.readUnsignedShort());
361         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
362         out.skipBytes(4);
363         Assert.assertEquals("Wrong property type", 6, out.readUnsignedShort());
364         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
365         out.skipBytes(4);
366         Assert.assertEquals("Wrong property type", 7, out.readUnsignedShort());
367         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
368         out.skipBytes(4);
369         Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort());
370         Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
371         Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
372         Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte());
373         Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());
374         Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
375         Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte());
376         Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte());
377         out.skipBytes(4);
378         Assert.assertEquals("Wrong property type", 10, out.readUnsignedShort());
379         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
380         out.skipBytes(4);
381         Assert.assertEquals("Wrong property type", 12, out.readUnsignedShort());
382         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
383         out.skipBytes(4);
384         Assert.assertEquals("Wrong property type", 13, out.readUnsignedShort());
385         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
386         out.skipBytes(4);
387         Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort());
388         Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort());
389         Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
390         Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte());
391         Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());
392         Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort());
393         Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte());
394         Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte());
395         out.skipBytes(4);
396         Assert.assertEquals("Wrong property type", 15, out.readUnsignedShort());
397         Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort());
398         out.skipBytes(4);
399         Assert.assertTrue("Unread data", out.readableBytes() == 0);
400     }
401
402     /**
403      * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO.
404      */
405     @Test
406     public void testMultipartRequestTableFeaturesExperimenter() throws Exception {
407         MultipartRequestInputFactory factory = new MultipartRequestInputFactory();
408         factory.injectSerializerRegistry(mockRegistry);
409         MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
410         BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID);
411         builder.setType(MultipartType.forValue(12));
412         builder.setFlags(new MultipartRequestFlags(true));
413         TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder();
414         tableFeaturesBuilder.setTableId((short) 8);
415         tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG");
416         tableFeaturesBuilder.setMetadataMatch(new BigInteger(
417                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}));
418         tableFeaturesBuilder.setMetadataWrite(new BigInteger(
419                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}));
420         tableFeaturesBuilder.setConfig(new TableConfig(true));
421         tableFeaturesBuilder.setMaxEntries(65L);
422         TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder();
423         propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTER);
424         ExperimenterIdTableFeaturePropertyBuilder expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();
425         expBuilder.setExperimenter(new ExperimenterId(42L));
426         propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());
427         List<TableFeatureProperties> properties = new ArrayList<>();
428         properties.add(propBuilder.build());
429         propBuilder = new TableFeaturePropertiesBuilder();
430         propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS);
431         expBuilder = new ExperimenterIdTableFeaturePropertyBuilder();
432         expBuilder.setExperimenter(new ExperimenterId(43L));
433         propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build());
434         properties.add(propBuilder.build());
435         tableFeaturesBuilder.setTableFeatureProperties(properties);
436         List<TableFeatures> tableFeaturesList = new ArrayList<>();
437         tableFeaturesList.add(tableFeaturesBuilder.build());
438         MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder();
439         featuresBuilder.setTableFeatures(tableFeaturesList);
440         MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
441         caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build());
442         builder.setMultipartRequestBody(caseBuilder.build());
443         MultipartRequestInput message = builder.build();
444
445         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
446         factory.serialize(message, out);
447
448         BufferHelper.checkHeaderV13(out, (byte) 18, 80);
449         Assert.assertEquals("Wrong type", 12, out.readUnsignedShort());
450         Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort());
451         out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE);
452         Assert.assertEquals("Wrong length", 64, out.readUnsignedShort());
453         Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte());
454         out.skipBytes(5);
455         Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG",
456                 ByteBufUtils.decodeNullTerminatedString(out, 32));
457         byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
458         out.readBytes(metadataMatch);
459         Assert.assertArrayEquals("Wrong metadata-match",
460                 new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch);
461         byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
462         out.readBytes(metadataWrite);
463         Assert.assertArrayEquals("Wrong metadata-write",
464                 new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite);
465         Assert.assertEquals("Wrong config", 8, out.readUnsignedInt());
466         Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt());
467         Mockito.verify(serializer, Mockito.times(2)).serialize(any(TableFeatureProperties.class),
468                 any(ByteBuf.class));
469     }
470 }