29d1fcd443be313cbf9ec9f17b2f7dff389728e3
[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 = {
192             null,
193             new FlowModFlags(false, false, false, false, false),
194             new FlowModFlags(false, false, false, false, false)
195         };
196         final FlowModFlags all = new FlowModFlags(true, true, true, true, true);
197         final FlowModFlags none = new FlowModFlags(false, false, false, false, false);
198
199         for (final FlowModFlags f : defaults) {
200             assertTrue(FlowCreatorUtil.equalsFlowModFlags(f, null));
201             assertTrue(FlowCreatorUtil.equalsFlowModFlags(null, f));
202             assertFalse(FlowCreatorUtil.equalsFlowModFlags(null, all));
203             assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, null));
204             assertTrue(FlowCreatorUtil.equalsFlowModFlags(null, none));
205             assertTrue(FlowCreatorUtil.equalsFlowModFlags(none, null));
206         }
207
208         final String[] bitNames = {"cHECKOVERLAP", "nOBYTCOUNTS", "nOPKTCOUNTS", "rESETCOUNTS", "sENDFLOWREM"};
209         int bit = 0;
210         for (final String name : bitNames) {
211             final FlowModFlags flags = FlowModFlags.getDefaultInstance(name);
212             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, all));
213             assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, flags));
214             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, none));
215             assertFalse(FlowCreatorUtil.equalsFlowModFlags(none, flags));
216
217             for (final String nm : bitNames) {
218                 final FlowModFlags f = FlowModFlags.getDefaultInstance(nm);
219                 final boolean expected = nm.equals(name);
220                 assertEquals(expected, FlowCreatorUtil.equalsFlowModFlags(flags, f));
221                 assertEquals(expected, FlowCreatorUtil.equalsFlowModFlags(f, flags));
222             }
223
224             final boolean overlap = bit == 0;
225             final boolean noByte = bit == 1;
226             final boolean noPacket = bit == 2;
227             final boolean reset = bit == 3;
228             final boolean flowRem = bit == 4;
229             FlowModFlags flowModFlags = new FlowModFlags(overlap, noByte, noPacket, reset, flowRem);
230             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
231             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flowModFlags, flags));
232             assertTrue(FlowCreatorUtil.equalsFlowModFlags(flowModFlags, new FlowModFlags(flowModFlags)));
233
234             flowModFlags = new FlowModFlags(!overlap, noByte, noPacket, reset, flowRem);
235             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
236             flowModFlags = new FlowModFlags(overlap, !noByte, noPacket, reset, flowRem);
237             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
238             flowModFlags = new FlowModFlags(overlap, noByte, !noPacket, reset, flowRem);
239             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
240             flowModFlags = new FlowModFlags(overlap, noByte, noPacket, !reset, flowRem);
241             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
242             flowModFlags = new FlowModFlags(overlap, noByte, noPacket, reset, !flowRem);
243             assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, flowModFlags));
244
245             bit++;
246         }
247     }
248
249     /**
250      * Test method for
251      * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
252      */
253     @Test
254     public void testEqualsWithDefault() {
255         // Boolean
256         for (final Boolean def : new Boolean[]{Boolean.TRUE, Boolean.FALSE}) {
257             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
258             assertTrue(FlowCreatorUtil.equalsWithDefault(def, null, def));
259             assertTrue(FlowCreatorUtil.equalsWithDefault(null, def, def));
260
261             final Boolean inv = !def.booleanValue();
262             assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
263             assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
264         }
265
266         // Integer
267         final Integer[] integers = {-100, 0, 100,};
268         for (final Integer def : integers) {
269             final Integer same = new Integer(def);
270             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
271             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
272             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
273
274             final Integer diff = new Integer(def.intValue() + 1);
275             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
276             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
277         }
278
279         // String
280         final String[] strings = {"", "test string 1", "test string 2",};
281         for (final String def : strings) {
282             final String same = new String(def);
283             assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
284             assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
285             assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
286
287             final String diff = def + "-1";
288             assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
289             assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
290         }
291     }
292
293     private static void assertMatch(final Match match) {
294         assertEquals(OxmMatchType.VALUE, match.getType());
295     }
296
297     private static void assertMatch(final MatchV10 matchV10) {
298         assertEquals(matchV10.getDlDst(), MAC_ADDRESS);
299         assertEquals(matchV10.getDlSrc(), MAC_ADDRESS);
300
301         assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
302         assertTrue(matchV10.getNwDstMask().shortValue() == 0);
303
304         assertTrue(matchV10.getInPort().intValue() == 0);
305         assertTrue(matchV10.getDlVlan().intValue() == 0);
306         assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
307         assertTrue(matchV10.getDlType().intValue() == 0);
308
309         assertTrue(matchV10.getNwTos().shortValue() == 0);
310         assertTrue(matchV10.getNwProto().shortValue() == 0);
311
312         assertEquals(matchV10.getNwSrc(), IPV_4_ADDRESS);
313         assertEquals(matchV10.getNwDst(), IPV_4_ADDRESS);
314
315         assertTrue(matchV10.getTpSrc().intValue() == 0);
316         assertTrue(matchV10.getTpDst().intValue() == 0);
317     }
318
319     /**
320      * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
321      * returns expected value.
322      *
323      * @param expected An expected return value.
324      * @param org      A original flow builder that contains original flow to be tested.
325      * @param upd      An updated flow builder that contains updated flow to be tested.
326      * @param version  OpenFlow protocol version.
327      */
328     private static void canModifyFlowTest(final boolean expected, final OriginalFlowBuilder org,
329                                           final UpdatedFlowBuilder upd, final Uint8 version) {
330         final boolean result = FlowCreatorUtil.canModifyFlow(org.build(), upd.build(), version);
331         assertEquals(expected, result);
332     }
333
334     /**
335      * Create a flow match that specifies ethernet type.
336      *
337      * @param etherType An ethernet type value.
338      * @return A flow match that specifies the given ethernet type.
339      */
340     private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match createMatch(
341             final long etherType) {
342         final EthernetTypeBuilder ethType = new EthernetTypeBuilder().setType(new EtherType(Uint32.valueOf(etherType)));
343         final EthernetMatchBuilder ether = new EthernetMatchBuilder().setEthernetType(ethType.build());
344         return new MatchBuilder().setEthernetMatch(ether.build()).build();
345     }
346 }