Merge remote-tracking branch 'liblldp/master'
[openflowplugin.git] / openflowplugin-impl / src / test / java / org / opendaylight / openflowplugin / impl / 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.impl.util;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
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.rev130715.Ipv4Address;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.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.rev150225.OxmMatchType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.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 MAC_ADDRESS = new MacAddress("00:00:00:00:00:00");
40     private static final Ipv4Address IPV_4_ADDRESS = new Ipv4Address("0.0.0.0");
41
42     /**
43      * Test method for
44      * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder)}.
45      */
46     @Test
47     public void testSetWildcardedFlowMatch_1_0() {
48         MultipartRequestFlowBuilder multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
49         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestFlowBuilder);
50         MultipartRequestFlow multipartRequestFlow = multipartRequestFlowBuilder.build();
51         assertMatch(multipartRequestFlow.getMatchV10());
52
53         multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
54         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestFlowBuilder);
55         multipartRequestFlow = multipartRequestFlowBuilder.build();
56         assertMatch(multipartRequestFlow.getMatch());
57     }
58
59     /**
60      * Test method for
61      * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder)}.
62      */
63     @Test
64     public void testSetWildcardedFlowMatch_() {
65         MultipartRequestAggregateBuilder multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
66         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestAggregateBuilder);
67         MultipartRequestAggregate multipartRequestAggregate = multipartRequestAggregateBuilder.build();
68         assertMatch(multipartRequestAggregate.getMatchV10());
69
70         multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
71         FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestAggregateBuilder);
72         multipartRequestAggregate = multipartRequestAggregateBuilder.build();
73         assertMatch(multipartRequestAggregate.getMatch());
74
75
76     }
77
78     /**
79      * Test method for
80      * {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
81      */
82     @Test
83     public void testCanModifyFlow() {
84         final Short of10 = Short.valueOf(OFConstants.OFP_VERSION_1_0);
85         final Short of13 = Short.valueOf(OFConstants.OFP_VERSION_1_3);
86         final Short[] versions = {null, of10, of13};
87         final Boolean[] bools = {null, Boolean.TRUE, Boolean.FALSE};
88
89         final Integer defPri = Integer.valueOf(0x8000);
90         final Integer defIdle = Integer.valueOf(0);
91         final Integer defHard = Integer.valueOf(0);
92         final FlowModFlags defFlags = FlowModFlags.getDefaultInstance("sENDFLOWREM");
93         final FlowModFlags flags = new FlowModFlags(false, true, false, true, false);
94         final FlowCookie defCookie = new FlowCookie(BigInteger.ZERO);
95         final FlowCookie cookie = new FlowCookie(BigInteger.valueOf(0x12345L));
96         final FlowCookie cookie1 = new FlowCookie(BigInteger.valueOf(0x67890L));
97         final FlowCookie cookieMask = new FlowCookie(BigInteger.valueOf(0xffff00L));
98
99         for (final Short ver : versions) {
100             final OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
101             final UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
102             canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
103
104             // Default value tests.
105             canModifyFlowTest(true, new OriginalFlowBuilder().setPriority(defPri), updatedBuilder, ver);
106             canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setPriority(defPri), ver);
107             canModifyFlowTest(true, new OriginalFlowBuilder().setIdleTimeout(defIdle), updatedBuilder, ver);
108             canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setIdleTimeout(defIdle), ver);
109             canModifyFlowTest(true, new OriginalFlowBuilder().setHardTimeout(defHard), updatedBuilder, ver);
110             canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setHardTimeout(defHard), ver);
111             canModifyFlowTest(false, new OriginalFlowBuilder().setFlags(defFlags), updatedBuilder, ver);
112             canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder().setFlags(defFlags), ver);
113             canModifyFlowTest(true, new OriginalFlowBuilder().setCookie(defCookie), updatedBuilder, ver);
114             canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setCookie(defCookie), ver);
115
116             // Set non-default values.
117             canModifyFlowTest(true, originalBuilder.setMatch(createMatch(0x800L)),
118                               updatedBuilder.setMatch(createMatch(0x800L)), ver);
119             canModifyFlowTest(true, originalBuilder.setIdleTimeout(600), updatedBuilder.setIdleTimeout(600), ver);
120             canModifyFlowTest(true, originalBuilder.setHardTimeout(1200), updatedBuilder.setHardTimeout(1200), ver);
121             canModifyFlowTest(true, originalBuilder.setPriority(100), updatedBuilder.setPriority(100), ver);
122             canModifyFlowTest(true, originalBuilder.setFlags(flags), updatedBuilder.setFlags(flags), ver);
123             canModifyFlowTest(true, originalBuilder.setCookie(cookie), updatedBuilder.setCookie(cookie), ver);
124
125             final OriginalFlow org = originalBuilder.build();
126             final UpdatedFlow upd = updatedBuilder.build();
127
128             // Set different match.
129             final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match[] matches
130                     = {null, createMatch(0x86ddL)};
131             for (final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match m : matches) {
132                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setMatch(m), ver);
133                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setMatch(m), updatedBuilder, ver);
134             }
135
136             // Set different idle-timeout, hard-timeout, priority.
137             final Integer[] integers = {null, Integer.valueOf(3600)};
138             for (final Integer i : integers) {
139                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setIdleTimeout(i), ver);
140                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setIdleTimeout(i), updatedBuilder, ver);
141
142                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setHardTimeout(i), ver);
143                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setHardTimeout(i), updatedBuilder, ver);
144
145                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setPriority(i), ver);
146                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setPriority(i), updatedBuilder, ver);
147             }
148
149             // Set different FLOW_MOD flags.
150             final FlowModFlags[] flowModFlags = {null, defFlags, new FlowModFlags(true, true, true, true, true),};
151             for (final FlowModFlags f : flowModFlags) {
152                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setFlags(f), ver);
153                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setFlags(f), updatedBuilder, ver);
154             }
155
156             // Set different cookie.
157             final FlowCookie[] cookies = {null, defCookie, new FlowCookie(BigInteger.valueOf(0x123456L)),};
158             for (final FlowCookie c : cookies) {
159                 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setCookie(c), ver);
160                 canModifyFlowTest(false, new OriginalFlowBuilder(org).setCookie(c), updatedBuilder, ver);
161             }
162
163             // Cookie mask test.
164             // Cookie mask is used by OF13 non-strict MODIFY command.
165             updatedBuilder.setCookie(cookie1);
166             for (final Boolean strict : bools) {
167                 updatedBuilder.setCookieMask(null).setStrict(strict);
168                 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
169
170                 updatedBuilder.setCookieMask(defCookie);
171                 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
172
173                 updatedBuilder.setCookieMask(cookieMask);
174                 final boolean expected = (of13.equals(ver) && !Boolean.TRUE.equals(strict));
175                 canModifyFlowTest(expected, originalBuilder, updatedBuilder, ver);
176             }
177         }
178     }
179
180     /**
181      * Test method for
182      * {@link FlowCreatorUtil#equalsFlowModFlags(FlowModFlags, FlowModFlags)}.
183      */
184     @Test
185     public void testEqualsFlowModFlags() {
186         final FlowModFlags[] defaults = {null, new FlowModFlags(false, false, false, false, false), new FlowModFlags(
187                 false, null, false, null, Boolean.FALSE),};
188         final FlowModFlags all = new FlowModFlags(true, true, true, true, true);
189         final FlowModFlags none = new FlowModFlags(null, null, null, null, null);
190
191         for (final FlowModFlags f : defaults) {
192             assertTrue(FlowCreatorUtil.equalsFlowModFlags(f, (FlowModFlags) null));
193             assertTrue(FlowCreatorUtil.equalsFlowModFlags((FlowModFlags) null, f));
194             assertFalse(FlowCreatorUtil.equalsFlowModFlags((FlowModFlags) null, all));
195             assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, (FlowModFlags) null));
196             assertTrue(FlowCreatorUtil.equalsFlowModFlags((FlowModFlags) null, none));
197             assertTrue(FlowCreatorUtil.equalsFlowModFlags(none, (FlowModFlags) null));
198         }
199
200         final String[] bitNames = {"cHECKOVERLAP", "nOBYTCOUNTS", "nOPKTCOUNTS", "rESETCOUNTS", "sENDFLOWREM"};
201         int bit = 0;
202         for (final String name : bitNames) {
203             final FlowModFlags flags = FlowModFlags.getDefaultInstance(name);
204             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, all));
205             assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, flags));
206             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, none));
207             assertFalse(FlowCreatorUtil.equalsFlowModFlags(none, flags));
208
209             for (final String nm : bitNames) {
210                 final FlowModFlags f = FlowModFlags.getDefaultInstance(nm);
211                 final boolean expected = nm.equals(name);
212                 assertEquals(expected, FlowCreatorUtil.equalsFlowModFlags(flags, f));
213                 assertEquals(expected, FlowCreatorUtil.equalsFlowModFlags(f, flags));
214             }
215
216             final boolean overlap = (bit == 0);
217             final boolean noByte = (bit == 1);
218             final boolean noPacket = (bit == 2);
219             final boolean reset = (bit == 3);
220             final boolean flowRem = (bit == 4);
221             FlowModFlags flowModFlags = new FlowModFlags(overlap, noByte, noPacket, reset, flowRem);
222             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
223             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flowModFlags, flags));
224             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flowModFlags, new FlowModFlags(flowModFlags)));
225
226             flowModFlags = new FlowModFlags(!overlap, noByte, noPacket, reset, flowRem);
227             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
228             flowModFlags = new FlowModFlags(overlap, !noByte, noPacket, reset, flowRem);
229             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
230             flowModFlags = new FlowModFlags(overlap, noByte, !noPacket, reset, flowRem);
231             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
232             flowModFlags = new FlowModFlags(overlap, noByte, noPacket, !reset, flowRem);
233             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
234             flowModFlags = new FlowModFlags(overlap, noByte, noPacket, reset, !flowRem);
235             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
236
237             bit++;
238         }
239     }
240
241     /**
242      * Test method for
243      * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
244      */
245     @Test
246     public void testEqualsWithDefault() {
247         // Boolean
248         for (final Boolean def : new Boolean[]{Boolean.TRUE, Boolean.FALSE}) {
249             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
250             assertTrue(FlowCreatorUtil.equalsWithDefault(def, null, def));
251             assertTrue(FlowCreatorUtil.equalsWithDefault(null, def, def));
252
253             final Boolean inv = Boolean.valueOf(!def.booleanValue());
254             assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
255             assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
256         }
257
258         // Integer
259         final Integer[] integers = {Integer.valueOf(-100), Integer.valueOf(0), Integer.valueOf(100),};
260         for (final Integer def : integers) {
261             final Integer same = new Integer(def.intValue());
262             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
263             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
264             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
265
266             final Integer diff = new Integer(def.intValue() + 1);
267             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
268             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
269         }
270
271         // String
272         final String[] strings = {"", "test string 1", "test string 2",};
273         for (final String def : strings) {
274             final String same = new String(def);
275             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
276             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
277             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
278
279             final String diff = def + "-1";
280             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
281             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
282         }
283     }
284
285     private static void assertMatch(final Match match) {
286         assertTrue(match.getType().getClass().isInstance(OxmMatchType.class));
287     }
288
289     private static void assertMatch(final MatchV10 matchV10) {
290         assertEquals(matchV10.getDlDst(), MAC_ADDRESS);
291         assertEquals(matchV10.getDlSrc(), MAC_ADDRESS);
292
293         assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
294         assertTrue(matchV10.getNwDstMask().shortValue() == 0);
295
296         assertTrue(matchV10.getInPort().intValue() == 0);
297         assertTrue(matchV10.getDlVlan().intValue() == 0);
298         assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
299         assertTrue(matchV10.getDlType().intValue() == 0);
300
301         assertTrue(matchV10.getNwTos().shortValue() == 0);
302         assertTrue(matchV10.getNwProto().shortValue() == 0);
303
304         assertEquals(matchV10.getNwSrc(), IPV_4_ADDRESS);
305         assertEquals(matchV10.getNwDst(), IPV_4_ADDRESS);
306
307         assertTrue(matchV10.getTpSrc().intValue() == 0);
308         assertTrue(matchV10.getTpDst().intValue() == 0);
309     }
310
311     /**
312      * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
313      * returns expected value.
314      *
315      * @param expected An expected return value.
316      * @param org      A original flow builder that contains original flow to be tested.
317      * @param upd      An updated flow builder that contains updated flow to be tested.
318      * @param version  OpenFlow protocol version.
319      */
320     private static void canModifyFlowTest(final boolean expected, final OriginalFlowBuilder org,
321                                           final UpdatedFlowBuilder upd, final Short version) {
322         final boolean result = FlowCreatorUtil.canModifyFlow(org.build(), upd.build(), version);
323         assertEquals(expected, result);
324     }
325
326     /**
327      * Create a flow match that specifies ethernet type.
328      *
329      * @param etherType An ethernet type value.
330      * @return A flow match that specifies the given ethernet type.
331      */
332     private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match createMatch(
333             final long etherType) {
334         final EthernetTypeBuilder ethType = new EthernetTypeBuilder().setType(new EtherType(etherType));
335         final EthernetMatchBuilder ether = new EthernetMatchBuilder().setEthernetType(ethType.build());
336         return new MatchBuilder().setEthernetMatch(ether.build()).build();
337     }
338 }