Improved unit test coverage (covered some untested branches)
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / util / OF13MatchSerializerTest.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
9 package org.opendaylight.openflowjava.protocol.impl.util;
10
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.UnpooledByteBufAllocator;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.junit.Assert;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.opendaylight.openflowjava.protocol.api.extensibility.MessageTypeKey;
21 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
22 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
23 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
24 import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl;
25 import org.opendaylight.openflowjava.util.ByteBufUtils;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntry;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Src;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 /**
52  * @author michal.polkorab
53  *
54  */
55 public class OF13MatchSerializerTest {
56
57     private static final Logger LOG = LoggerFactory
58             .getLogger(OF13MatchSerializerTest.class);
59     private SerializerRegistry registry;
60     private OFSerializer<Match> matchSerializer;
61
62     /**
63      * Initializes serializer table and stores correct factory in field
64      */
65     @Before
66     public void startUp() {
67         registry = new SerializerRegistryImpl();
68         registry.init();
69         matchSerializer = registry.getSerializer(
70                 new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Match.class));
71     }
72
73     /**
74      * Test for correct serialization of Ipv4Address match entry
75      */
76     @Test
77     public void testIpv4Src() {
78         MatchBuilder builder = new MatchBuilder();
79         builder.setType(OxmMatchType.class);
80         List<MatchEntries> entries = new ArrayList<>();
81         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
82         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
83         entriesBuilder.setOxmMatchField(Ipv4Src.class);
84         entriesBuilder.setHasMask(false);
85         Ipv4AddressMatchEntryBuilder addressBuilder = new Ipv4AddressMatchEntryBuilder();
86         addressBuilder.setIpv4Address(new Ipv4Address("1.2.3.4"));
87         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, addressBuilder.build());
88         entries.add(entriesBuilder.build());
89         builder.setMatchEntries(entries);
90         Match match = builder.build();
91         
92         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
93         matchSerializer.serialize(match, out);
94         
95         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
96         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
97         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
98         Assert.assertEquals("Wrong field and mask", 22, out.readUnsignedByte());
99         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
100         Assert.assertEquals("Wrong ip address (first number)", 1, out.readUnsignedByte());
101         Assert.assertEquals("Wrong ip address (second number)", 2, out.readUnsignedByte());
102         Assert.assertEquals("Wrong ip address (third number)", 3, out.readUnsignedByte());
103         Assert.assertEquals("Wrong ip address (fourth number)", 4, out.readUnsignedByte());
104     }
105     
106     /**
107      * Test for correct serialization of Ipv6Address match entry
108      */
109     @Test(expected=IllegalStateException.class)
110     public void testIpv6Various() {
111         MatchBuilder builder = new MatchBuilder();
112         builder.setType(OxmMatchType.class);
113         List<MatchEntries> entries = new ArrayList<>();
114         // ipv6 match entry with correct Ipv6 address
115         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
116         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
117         entriesBuilder.setOxmMatchField(Ipv6Src.class);
118         entriesBuilder.setHasMask(false);
119         Ipv6AddressMatchEntryBuilder addressBuilder = new Ipv6AddressMatchEntryBuilder();
120         addressBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8"));
121         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
122         entries.add(entriesBuilder.build());
123         // ipv6 match entry with abbreviated Ipv6 address
124         entriesBuilder = new MatchEntriesBuilder();
125         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
126         entriesBuilder.setOxmMatchField(Ipv6NdTarget.class);
127         entriesBuilder.setHasMask(false);
128         addressBuilder = new Ipv6AddressMatchEntryBuilder();
129         addressBuilder.setIpv6Address(new Ipv6Address("1:2::6:7:8"));
130         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
131         entries.add(entriesBuilder.build());
132         // ipv6 match entry with abbreviated Ipv6 address
133         entriesBuilder = new MatchEntriesBuilder();
134         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
135         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
136         entriesBuilder.setHasMask(false);
137         addressBuilder = new Ipv6AddressMatchEntryBuilder();
138         addressBuilder.setIpv6Address(new Ipv6Address("1::8"));
139         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
140         entries.add(entriesBuilder.build());
141         // ipv6 match entry with abbreviated Ipv6 address
142         entriesBuilder = new MatchEntriesBuilder();
143         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
144         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
145         entriesBuilder.setHasMask(false);
146         addressBuilder = new Ipv6AddressMatchEntryBuilder();
147         addressBuilder.setIpv6Address(new Ipv6Address("::1"));
148         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
149         entries.add(entriesBuilder.build());
150         // ipv6 match entry with abbreviated Ipv6 address
151         entriesBuilder = new MatchEntriesBuilder();
152         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
153         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
154         entriesBuilder.setHasMask(false);
155         addressBuilder = new Ipv6AddressMatchEntryBuilder();
156         addressBuilder.setIpv6Address(new Ipv6Address("::"));
157         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
158         entries.add(entriesBuilder.build());
159         // ipv6 match entry with incorrect Ipv6 address (longer)
160         entriesBuilder = new MatchEntriesBuilder();
161         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
162         entriesBuilder.setOxmMatchField(Ipv6Dst.class);
163         entriesBuilder.setHasMask(false);
164         addressBuilder = new Ipv6AddressMatchEntryBuilder();
165         addressBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8:9"));
166         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
167         entries.add(entriesBuilder.build());
168         // ipv6 match entry with too abbreviated Ipv6 address
169         entriesBuilder = new MatchEntriesBuilder();
170         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
171         entriesBuilder.setOxmMatchField(Ipv6NdTarget.class);
172         entriesBuilder.setHasMask(false);
173         addressBuilder = new Ipv6AddressMatchEntryBuilder();
174         addressBuilder.setIpv6Address(new Ipv6Address("1:2::::8"));
175         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, addressBuilder.build());
176         entries.add(entriesBuilder.build());
177         builder.setMatchEntries(entries);
178         Match match = builder.build();
179         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
180         matchSerializer.serialize(match, out);
181         
182         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
183         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
184         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
185         Assert.assertEquals("Wrong field and mask", 52, out.readUnsignedByte());
186         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
187         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
188         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
189         Assert.assertEquals("Wrong ipv6 address", 3, out.readUnsignedShort());
190         Assert.assertEquals("Wrong ipv6 address", 4, out.readUnsignedShort());
191         Assert.assertEquals("Wrong ipv6 address", 5, out.readUnsignedShort());
192         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
193         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
194         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
195         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
196         Assert.assertEquals("Wrong field and mask", 62, out.readUnsignedByte());
197         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
198         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
199         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
200         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
201         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
202         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
203         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
204         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
205         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
206         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
207         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
208         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
209         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
210         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
211         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
212         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
213         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
214         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
215         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
216         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
217         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
218         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
219         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
220         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
221         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
222         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
223         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
224         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
225         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
226         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
227         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
228         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
229         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
230         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
231         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
232         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
233         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
234         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
235         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
236         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
237         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
238         Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort());
239         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
240         Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte());
241         Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte());
242         Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort());
243         Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort());
244         Assert.assertEquals("Wrong ipv6 address", 3, out.readUnsignedShort());
245         Assert.assertEquals("Wrong ipv6 address", 4, out.readUnsignedShort());
246         Assert.assertEquals("Wrong ipv6 address", 5, out.readUnsignedShort());
247         Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort());
248         Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort());
249         Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort());
250     }
251     
252     /**
253      * Test for correct serialization of Ipv4Address match entry
254      */
255     @Test
256     public void testIpv6Flabel() {
257         Match match = buildIpv6FLabelMatch(0x0f9e8dL, false, null);
258         
259         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
260         matchSerializer.serialize(match, out);
261         
262         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
263         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
264         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
265         Assert.assertEquals("Wrong field and mask", 28<<1, out.readUnsignedByte());
266         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
267         byte[] label = new byte[4];
268         out.readBytes(label);
269         
270         LOG.debug("label: "+ ByteBufUtils.bytesToHexString(label));
271         Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label);
272     }
273     
274     /**
275      * Test for correct serialization of Ipv4Address match entry with mask
276      */
277     @Test
278     public void testIpv6FlabelWithMask() {
279         Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0, 0x0c, 0x7b, 0x6a});
280         
281         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
282         matchSerializer.serialize(match, out);
283         
284         Assert.assertEquals("Wrong type", 1, out.readUnsignedShort());
285         out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
286         Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort());
287         Assert.assertEquals("Wrong field and mask", 28<<1 | 1, out.readUnsignedByte());
288         out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES);
289         byte[] labelAndMask = new byte[8];
290         out.readBytes(labelAndMask);
291         
292         LOG.debug("label: "+ByteBufUtils.bytesToHexString(labelAndMask));
293         Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d, 0, 0x0c, 0x7b, 0x6a}, labelAndMask);
294     }
295     
296     /**
297      * Test for correct serialization of Ipv4Address match entry with wrong mask
298      */
299     @Test
300     public void testIpv6FlabelWithMaskBad() {
301         Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0x0c, 0x7b, 0x6a});
302         
303         ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
304         
305         try {
306             matchSerializer.serialize(match, out);
307             Assert.fail("incorrect length of mask ignored");
308         } catch (IllegalArgumentException e) {
309             //expected
310         }
311     }
312
313     /**
314      * @param labelValue ipv6 flow label
315      * @param hasMask
316      * @param mask ipv6 flow label mask
317      * @return
318      */
319     private static Match buildIpv6FLabelMatch(long labelValue, boolean hasMask, byte[] mask) {
320         MatchBuilder builder = new MatchBuilder();
321         builder.setType(OxmMatchType.class);
322         List<MatchEntries> entries = new ArrayList<>();
323         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();
324         entriesBuilder.setOxmClass(OpenflowBasicClass.class);
325         entriesBuilder.setOxmMatchField(Ipv6Flabel.class);
326         entriesBuilder.setHasMask(hasMask);
327         Ipv6FlabelMatchEntryBuilder ip6FLabelBuilder = new Ipv6FlabelMatchEntryBuilder();
328         ip6FLabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(labelValue));
329         entriesBuilder.addAugmentation(Ipv6FlabelMatchEntry.class, ip6FLabelBuilder.build());
330         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
331         maskBuilder.setMask(mask);
332         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
333         entries.add(entriesBuilder.build());
334         builder.setMatchEntries(entries);
335         Match match = builder.build();
336         return match;
337     }
338     
339     
340
341 }