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