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