9b7182a94bfb89ce77638c3a61569416d1ece979
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / util / FlowCreatorUtilTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. 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.openflowplugin.openflow.md.util;
9
10 import static junit.framework.Assert.assertTrue;
11 import static junit.framework.Assert.assertFalse;
12 import static junit.framework.Assert.assertEquals;
13
14 import java.math.BigInteger;
15 import org.junit.Test;
16 import org.opendaylight.openflowplugin.api.OFConstants;
17 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregate;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
36
37 public class FlowCreatorUtilTest {
38
39     private static final MacAddress macAddress = new MacAddress("00:00:00:00:00:00");
40     private static final Ipv4Address ipv4Address = new Ipv4Address("0.0.0.0");
41
42     /**
43      * Test method for {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder)}.
44      */
45     @Test
46     public void testSetWildcardedFlowMatch_1_0() {
47         MultipartRequestFlowBuilder multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
48         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestFlowBuilder);
49         MultipartRequestFlow multipartRequestFlow = multipartRequestFlowBuilder.build();
50         assertMatch(multipartRequestFlow.getMatchV10());
51
52         multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
53         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestFlowBuilder);
54         multipartRequestFlow = multipartRequestFlowBuilder.build();
55         assertMatch(multipartRequestFlow.getMatch());
56     }
57
58     /**
59      * Test method for {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder)}.
60      */
61     @Test
62     public void testSetWildcardedFlowMatch_() {
63         MultipartRequestAggregateBuilder multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
64         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestAggregateBuilder);
65         MultipartRequestAggregate multipartRequestAggregate = multipartRequestAggregateBuilder.build();
66         assertMatch(multipartRequestAggregate.getMatchV10());
67
68         multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
69         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestAggregateBuilder);
70         multipartRequestAggregate = multipartRequestAggregateBuilder.build();
71         assertMatch(multipartRequestAggregate.getMatch());
72
73
74     }
75
76     /**
77      * Test method for
78      * {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
79      */
80     @Test
81     public void testCanModifyFlow() {
82         Short of10 = Short.valueOf(OFConstants.OFP_VERSION_1_0);
83         Short of13 = Short.valueOf(OFConstants.OFP_VERSION_1_3);
84         Short[] versions = {null, of10, of13};
85         Boolean[] bools = {null, Boolean.TRUE, Boolean.FALSE};
86
87         Integer defPri = Integer.valueOf(0x8000);
88         Integer defIdle = Integer.valueOf(300);
89         Integer defHard = Integer.valueOf(600);
90         FlowModFlags defFlags = FlowModFlags.getDefaultInstance("sENDFLOWREM");
91         FlowModFlags flags = new FlowModFlags(false, true, false, true, false);
92         FlowCookie defCookie = new FlowCookie(BigInteger.ZERO);
93         FlowCookie cookie = new FlowCookie(BigInteger.valueOf(0x12345L));
94         FlowCookie cookie1 = new FlowCookie(BigInteger.valueOf(0x67890L));
95         FlowCookie cookieMask = new FlowCookie(BigInteger.valueOf(0xffff00L));
96
97         for (Short ver: versions) {
98             OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
99             UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
100             canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
101
102             // Default value tests.
103             canModifyFlowTest(true,
104                               new OriginalFlowBuilder().setPriority(defPri),
105                               updatedBuilder, ver);
106             canModifyFlowTest(true, originalBuilder,
107                               new UpdatedFlowBuilder().setPriority(defPri),
108                               ver);
109             canModifyFlowTest(true,
110                               new OriginalFlowBuilder().setIdleTimeout(defIdle),
111                               updatedBuilder, ver);
112             canModifyFlowTest(true, originalBuilder,
113                               new UpdatedFlowBuilder().setIdleTimeout(defIdle),
114                               ver);
115             canModifyFlowTest(true,
116                               new OriginalFlowBuilder().setHardTimeout(defHard),
117                               updatedBuilder, ver);
118             canModifyFlowTest(true, originalBuilder,
119                               new UpdatedFlowBuilder().setHardTimeout(defHard),
120                               ver);
121             canModifyFlowTest(true,
122                               new OriginalFlowBuilder().setFlags(defFlags),
123                               updatedBuilder, ver);
124             canModifyFlowTest(true, originalBuilder,
125                               new UpdatedFlowBuilder().setFlags(defFlags),
126                               ver);
127             canModifyFlowTest(true,
128                               new OriginalFlowBuilder().setCookie(defCookie),
129                               updatedBuilder, ver);
130             canModifyFlowTest(true, originalBuilder,
131                               new UpdatedFlowBuilder().setCookie(defCookie),
132                               ver);
133
134             // Set non-default values.
135             canModifyFlowTest(true,
136                               originalBuilder.setMatch(createMatch(0x800L)),
137                               updatedBuilder.setMatch(createMatch(0x800L)),
138                               ver);
139             canModifyFlowTest(true, originalBuilder.setIdleTimeout(600),
140                               updatedBuilder.setIdleTimeout(600), ver);
141             canModifyFlowTest(true, originalBuilder.setHardTimeout(1200),
142                               updatedBuilder.setHardTimeout(1200), ver);
143             canModifyFlowTest(true, originalBuilder.setPriority(100),
144                               updatedBuilder.setPriority(100), ver);
145             canModifyFlowTest(true, originalBuilder.setFlags(flags),
146                               updatedBuilder.setFlags(flags), ver);
147             canModifyFlowTest(true, originalBuilder.setCookie(cookie),
148                               updatedBuilder.setCookie(cookie), ver);
149
150             OriginalFlow org = originalBuilder.build();
151             UpdatedFlow upd = updatedBuilder.build();
152
153             // Set different match.
154             org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match[] matches = {null, createMatch(0x86ddL)};
155             for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match m: matches) {
156                 canModifyFlowTest(false, originalBuilder,
157                                   new UpdatedFlowBuilder(upd).setMatch(m),
158                                   ver);
159                 canModifyFlowTest(false,
160                                   new OriginalFlowBuilder(org).setMatch(m),
161                                   updatedBuilder, ver);
162             }
163
164             // Set different idle-timeout, hard-timeout, priority.
165             Integer[] integers = {null, Integer.valueOf(3600)};
166             for (Integer i: integers) {
167                 canModifyFlowTest(false, originalBuilder,
168                                   new UpdatedFlowBuilder(upd).setIdleTimeout(i),
169                                   ver);
170                 canModifyFlowTest(false,
171                                   new OriginalFlowBuilder(org).setIdleTimeout(i),
172                                   updatedBuilder, ver);
173
174                 canModifyFlowTest(false, originalBuilder,
175                                   new UpdatedFlowBuilder(upd).setHardTimeout(i),
176                                   ver);
177                 canModifyFlowTest(false,
178                                   new OriginalFlowBuilder(org).setHardTimeout(i),
179                                   updatedBuilder, ver);
180
181                 canModifyFlowTest(false, originalBuilder,
182                                   new UpdatedFlowBuilder(upd).setPriority(i),
183                                   ver);
184                 canModifyFlowTest(false,
185                                   new OriginalFlowBuilder(org).setPriority(i),
186                                   updatedBuilder, ver);
187             }
188
189             // Set different FLOW_MOD flags.
190             FlowModFlags[] flowModFlags = {
191                 null,
192                 defFlags,
193                 new FlowModFlags(true, true, true, true, true),
194             };
195             for (FlowModFlags f: flowModFlags) {
196                 canModifyFlowTest(false, originalBuilder,
197                                   new UpdatedFlowBuilder(upd).setFlags(f),
198                                   ver);
199                 canModifyFlowTest(false,
200                                   new OriginalFlowBuilder(org).setFlags(f),
201                                   updatedBuilder, ver);
202             }
203
204             // Set different cookie.
205             FlowCookie[] cookies = {
206                 null,
207                 defCookie,
208                 new FlowCookie(BigInteger.valueOf(0x123456L)),
209             };
210             for (FlowCookie c: cookies) {
211                 canModifyFlowTest(false, originalBuilder,
212                                   new UpdatedFlowBuilder(upd).setCookie(c),
213                                   ver);
214                 canModifyFlowTest(false,
215                                   new OriginalFlowBuilder(org).setCookie(c),
216                                   updatedBuilder, ver);
217             }
218
219             // Cookie mask test.
220             // Cookie mask is used by OF13 non-strict MODIFY command.
221             updatedBuilder.setCookie(cookie1);
222             for (Boolean strict: bools) {
223                 updatedBuilder.setCookieMask(null).setStrict(strict);
224                 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
225
226                 updatedBuilder.setCookieMask(defCookie);
227                 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
228
229                 updatedBuilder.setCookieMask(cookieMask);
230                 boolean expected = (of13.equals(ver) &&
231                                     !Boolean.TRUE.equals(strict));
232                 canModifyFlowTest(expected, originalBuilder, updatedBuilder,
233                                   ver);
234             }
235         }
236     }
237
238     /**
239      * Test method for
240      * {@link FlowCreatorUtil#equalsFlowModFlags(FlowModFlags, FlowModFlags)}.
241      */
242     @Test
243     public void testEqualsFlowModFlags() {
244         FlowModFlags[] defaults = {
245             null,
246             FlowModFlags.getDefaultInstance("sENDFLOWREM"),
247             new FlowModFlags(false, false, false, false, true),
248             new FlowModFlags(false, null, false, null, Boolean.TRUE),
249         };
250         FlowModFlags all = new FlowModFlags(true, true, true, true, true);
251         FlowModFlags none = new FlowModFlags(null, null, null, null, null);
252
253         for (FlowModFlags f: defaults) {
254             assertTrue(FlowCreatorUtil.
255                        equalsFlowModFlags(f, (FlowModFlags)null));
256             assertTrue(FlowCreatorUtil.
257                        equalsFlowModFlags((FlowModFlags)null, f));
258             assertFalse(FlowCreatorUtil.
259                         equalsFlowModFlags((FlowModFlags)null, all));
260             assertFalse(FlowCreatorUtil.
261                         equalsFlowModFlags(all, (FlowModFlags)null));
262             assertFalse(FlowCreatorUtil.
263                         equalsFlowModFlags((FlowModFlags)null, none));
264             assertFalse(FlowCreatorUtil.
265                         equalsFlowModFlags(none, (FlowModFlags)null));
266         }
267
268         String[] bitNames = {
269             "cHECKOVERLAP",
270             "nOBYTCOUNTS",
271             "nOPKTCOUNTS",
272             "rESETCOUNTS",
273             "sENDFLOWREM"
274         };
275         int bit = 0;
276         for (String name: bitNames) {
277             FlowModFlags flags = FlowModFlags.getDefaultInstance(name);
278             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, all));
279             assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, flags));
280             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, none));
281             assertFalse(FlowCreatorUtil.equalsFlowModFlags(none, flags));
282
283             for (String nm: bitNames) {
284                 FlowModFlags f = FlowModFlags.getDefaultInstance(nm);
285                 boolean expected = nm.equals(name);
286                 assertEquals(expected,
287                              FlowCreatorUtil.equalsFlowModFlags(flags, f));
288                 assertEquals(expected,
289                              FlowCreatorUtil.equalsFlowModFlags(f, flags));
290             }
291
292             boolean overlap = (bit == 0);
293             boolean noByte = (bit == 1);
294             boolean noPacket = (bit == 2);
295             boolean reset = (bit == 3);
296             boolean flowRem = (bit == 4);
297             FlowModFlags f =
298                 new FlowModFlags(overlap, noByte, noPacket, reset, flowRem);
299             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flags, f));
300             assertTrue(FlowCreatorUtil.equalsFlowModFlags(f, flags));
301             assertTrue(FlowCreatorUtil.
302                        equalsFlowModFlags(f, new FlowModFlags(f)));
303
304             f = new FlowModFlags(!overlap, noByte, noPacket, reset, flowRem);
305             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
306             f = new FlowModFlags(overlap, !noByte, noPacket, reset, flowRem);
307             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
308             f = new FlowModFlags(overlap, noByte, !noPacket, reset, flowRem);
309             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
310             f = new FlowModFlags(overlap, noByte, noPacket, !reset, flowRem);
311             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
312             f = new FlowModFlags(overlap, noByte, noPacket, reset, !flowRem);
313             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
314
315             bit++;
316         }
317     }
318
319     /**
320      * Test method for
321      * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
322      */
323     @Test
324     public void testEqualsWithDefault() {
325         // Boolean
326         for (Boolean def: new Boolean[]{Boolean.TRUE, Boolean.FALSE}) {
327             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
328             assertTrue(FlowCreatorUtil.equalsWithDefault(def, null, def));
329             assertTrue(FlowCreatorUtil.equalsWithDefault(null, def, def));
330
331             Boolean inv = Boolean.valueOf(!def.booleanValue());
332             assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
333             assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
334         }
335
336         // Integer
337         Integer[] integers = {
338             Integer.valueOf(-100),
339             Integer.valueOf(0),
340             Integer.valueOf(100),
341         };
342         for (Integer def: integers) {
343             Integer same = new Integer(def.intValue());
344             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
345             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
346             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
347
348             Integer diff = new Integer(def.intValue() +1);
349             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
350             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
351         }
352
353         // String
354         String[] strings = {
355             "",
356             "test string 1",
357             "test string 2",
358         };
359         for (String def: strings) {
360             String same = new String(def);
361             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
362             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
363             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
364
365             String diff = def + "-1";
366             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
367             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
368         }
369     }
370
371     private void assertMatch(Match match) {
372         assertTrue(match.getType().getClass().isInstance(OxmMatchType.class));
373     }
374
375     private void assertMatch(MatchV10 matchV10) {
376         assertEquals(matchV10.getDlDst(), macAddress);
377         assertEquals(matchV10.getDlSrc(), macAddress);
378
379         assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
380         assertTrue(matchV10.getNwDstMask().shortValue() == 0);
381
382         assertTrue(matchV10.getInPort().intValue() == 0);
383         assertTrue(matchV10.getDlVlan().intValue() == 0);
384         assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
385         assertTrue(matchV10.getDlType().intValue() == 0);
386
387         assertTrue(matchV10.getNwTos().shortValue() == 0);
388         assertTrue(matchV10.getNwProto().shortValue() == 0);
389
390         assertEquals(matchV10.getNwSrc(), ipv4Address);
391         assertEquals(matchV10.getNwDst(), ipv4Address);
392
393         assertTrue(matchV10.getTpSrc().intValue() == 0);
394         assertTrue(matchV10.getTpDst().intValue() == 0);
395     }
396
397     /**
398      * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
399      * returns expected value.
400      *
401      * @param expected
402      *     An expected return value.
403      * @param org
404      *     A original flow builder that contains original flow to be tested.
405      * @param upd
406      *     An updated flow builder that contains updated flow to be tested.
407      * @param version
408      *     OpenFlow protocol version.
409      */
410     private void canModifyFlowTest(boolean expected, OriginalFlowBuilder org,
411                                    UpdatedFlowBuilder upd, Short version) {
412         boolean result = FlowCreatorUtil.
413             canModifyFlow(org.build(), upd.build(), version);
414         assertEquals(expected, result);
415     }
416
417     /**
418      * Create a flow match that specifies ethernet type.
419      *
420      * @param etherType  An ethernet type value.
421      * @return  A flow match that specifies the given ethernet type.
422      */
423     private org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match createMatch(long etherType) {
424         EthernetTypeBuilder ethType = new EthernetTypeBuilder().
425             setType(new EtherType(etherType));
426         EthernetMatchBuilder ether = new EthernetMatchBuilder().
427             setEthernetType(ethType.build());
428         return new MatchBuilder().setEthernetMatch(ether.build()).build();
429     }
430 }