2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.openflowplugin.impl.util;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13 import java.math.BigInteger;
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;
36 public class FlowCreatorUtilTest {
38 private static final MacAddress macAddress = new MacAddress("00:00:00:00:00:00");
39 private static final Ipv4Address ipv4Address = new Ipv4Address("0.0.0.0");
42 * Test method for {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder)}.
45 public void testSetWildcardedFlowMatch_1_0() {
46 MultipartRequestFlowBuilder multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
47 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestFlowBuilder);
48 MultipartRequestFlow multipartRequestFlow = multipartRequestFlowBuilder.build();
49 assertMatch(multipartRequestFlow.getMatchV10());
51 multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
52 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestFlowBuilder);
53 multipartRequestFlow = multipartRequestFlowBuilder.build();
54 assertMatch(multipartRequestFlow.getMatch());
58 * Test method for {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder)}.
61 public void testSetWildcardedFlowMatch_() {
62 MultipartRequestAggregateBuilder multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
63 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_0, multipartRequestAggregateBuilder);
64 MultipartRequestAggregate multipartRequestAggregate = multipartRequestAggregateBuilder.build();
65 assertMatch(multipartRequestAggregate.getMatchV10());
67 multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
68 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestAggregateBuilder);
69 multipartRequestAggregate = multipartRequestAggregateBuilder.build();
70 assertMatch(multipartRequestAggregate.getMatch());
77 * {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
80 public void testCanModifyFlow() {
81 final Short of10 = Short.valueOf(OFConstants.OFP_VERSION_1_0);
82 final Short of13 = Short.valueOf(OFConstants.OFP_VERSION_1_3);
83 final Short[] versions = {null, of10, of13};
84 final Boolean[] bools = {null, Boolean.TRUE, Boolean.FALSE};
86 final Integer defPri = Integer.valueOf(0x8000);
87 final Integer defIdle = Integer.valueOf(0);
88 final Integer defHard = Integer.valueOf(0);
89 final FlowModFlags defFlags = FlowModFlags.getDefaultInstance("sENDFLOWREM");
90 final FlowModFlags flags = new FlowModFlags(false, true, false, true, false);
91 final FlowCookie defCookie = new FlowCookie(BigInteger.ZERO);
92 final FlowCookie cookie = new FlowCookie(BigInteger.valueOf(0x12345L));
93 final FlowCookie cookie1 = new FlowCookie(BigInteger.valueOf(0x67890L));
94 final FlowCookie cookieMask = new FlowCookie(BigInteger.valueOf(0xffff00L));
96 for (final Short ver: versions) {
97 final OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
98 final UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
99 canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
101 // Default value tests.
102 canModifyFlowTest(true,
103 new OriginalFlowBuilder().setPriority(defPri),
104 updatedBuilder, ver);
105 canModifyFlowTest(true, originalBuilder,
106 new UpdatedFlowBuilder().setPriority(defPri),
108 canModifyFlowTest(true,
109 new OriginalFlowBuilder().setIdleTimeout(defIdle),
110 updatedBuilder, ver);
111 canModifyFlowTest(true, originalBuilder,
112 new UpdatedFlowBuilder().setIdleTimeout(defIdle),
114 canModifyFlowTest(true,
115 new OriginalFlowBuilder().setHardTimeout(defHard),
116 updatedBuilder, ver);
117 canModifyFlowTest(true, originalBuilder,
118 new UpdatedFlowBuilder().setHardTimeout(defHard),
120 canModifyFlowTest(false,
121 new OriginalFlowBuilder().setFlags(defFlags),
122 updatedBuilder, ver);
123 canModifyFlowTest(false, originalBuilder,
124 new UpdatedFlowBuilder().setFlags(defFlags),
126 canModifyFlowTest(true,
127 new OriginalFlowBuilder().setCookie(defCookie),
128 updatedBuilder, ver);
129 canModifyFlowTest(true, originalBuilder,
130 new UpdatedFlowBuilder().setCookie(defCookie),
133 // Set non-default values.
134 canModifyFlowTest(true,
135 originalBuilder.setMatch(createMatch(0x800L)),
136 updatedBuilder.setMatch(createMatch(0x800L)),
138 canModifyFlowTest(true, originalBuilder.setIdleTimeout(600),
139 updatedBuilder.setIdleTimeout(600), ver);
140 canModifyFlowTest(true, originalBuilder.setHardTimeout(1200),
141 updatedBuilder.setHardTimeout(1200), ver);
142 canModifyFlowTest(true, originalBuilder.setPriority(100),
143 updatedBuilder.setPriority(100), ver);
144 canModifyFlowTest(true, originalBuilder.setFlags(flags),
145 updatedBuilder.setFlags(flags), ver);
146 canModifyFlowTest(true, originalBuilder.setCookie(cookie),
147 updatedBuilder.setCookie(cookie), ver);
149 final OriginalFlow org = originalBuilder.build();
150 final UpdatedFlow upd = updatedBuilder.build();
152 // Set different match.
153 final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match[] matches = {null, createMatch(0x86ddL)};
154 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match m: matches) {
155 canModifyFlowTest(false, originalBuilder,
156 new UpdatedFlowBuilder(upd).setMatch(m),
158 canModifyFlowTest(false,
159 new OriginalFlowBuilder(org).setMatch(m),
160 updatedBuilder, ver);
163 // Set different idle-timeout, hard-timeout, priority.
164 final Integer[] integers = {null, Integer.valueOf(3600)};
165 for (final Integer i: integers) {
166 canModifyFlowTest(false, originalBuilder,
167 new UpdatedFlowBuilder(upd).setIdleTimeout(i),
169 canModifyFlowTest(false,
170 new OriginalFlowBuilder(org).setIdleTimeout(i),
171 updatedBuilder, ver);
173 canModifyFlowTest(false, originalBuilder,
174 new UpdatedFlowBuilder(upd).setHardTimeout(i),
176 canModifyFlowTest(false,
177 new OriginalFlowBuilder(org).setHardTimeout(i),
178 updatedBuilder, ver);
180 canModifyFlowTest(false, originalBuilder,
181 new UpdatedFlowBuilder(upd).setPriority(i),
183 canModifyFlowTest(false,
184 new OriginalFlowBuilder(org).setPriority(i),
185 updatedBuilder, ver);
188 // Set different FLOW_MOD flags.
189 final FlowModFlags[] flowModFlags = {
192 new FlowModFlags(true, true, true, true, true),
194 for (final FlowModFlags f: flowModFlags) {
195 canModifyFlowTest(false, originalBuilder,
196 new UpdatedFlowBuilder(upd).setFlags(f),
198 canModifyFlowTest(false,
199 new OriginalFlowBuilder(org).setFlags(f),
200 updatedBuilder, ver);
203 // Set different cookie.
204 final FlowCookie[] cookies = {
207 new FlowCookie(BigInteger.valueOf(0x123456L)),
209 for (final FlowCookie c: cookies) {
210 canModifyFlowTest(false, originalBuilder,
211 new UpdatedFlowBuilder(upd).setCookie(c),
213 canModifyFlowTest(false,
214 new OriginalFlowBuilder(org).setCookie(c),
215 updatedBuilder, ver);
219 // Cookie mask is used by OF13 non-strict MODIFY command.
220 updatedBuilder.setCookie(cookie1);
221 for (final Boolean strict: bools) {
222 updatedBuilder.setCookieMask(null).setStrict(strict);
223 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
225 updatedBuilder.setCookieMask(defCookie);
226 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
228 updatedBuilder.setCookieMask(cookieMask);
229 final boolean expected = (of13.equals(ver) &&
230 !Boolean.TRUE.equals(strict));
231 canModifyFlowTest(expected, originalBuilder, updatedBuilder,
239 * {@link FlowCreatorUtil#equalsFlowModFlags(FlowModFlags, FlowModFlags)}.
242 public void testEqualsFlowModFlags() {
243 final FlowModFlags[] defaults = {
245 new FlowModFlags(false, false, false, false, false),
246 new FlowModFlags(false, null, false, null, Boolean.FALSE),
248 final FlowModFlags all = new FlowModFlags(true, true, true, true, true);
249 final FlowModFlags none = new FlowModFlags(null, null, null, null, null);
251 for (final FlowModFlags f: defaults) {
252 assertTrue(FlowCreatorUtil.
253 equalsFlowModFlags(f, (FlowModFlags)null));
254 assertTrue(FlowCreatorUtil.
255 equalsFlowModFlags((FlowModFlags)null, f));
256 assertFalse(FlowCreatorUtil.
257 equalsFlowModFlags((FlowModFlags)null, all));
258 assertFalse(FlowCreatorUtil.
259 equalsFlowModFlags(all, (FlowModFlags)null));
260 assertTrue(FlowCreatorUtil.
261 equalsFlowModFlags((FlowModFlags)null, none));
262 assertTrue(FlowCreatorUtil.
263 equalsFlowModFlags(none, (FlowModFlags)null));
266 final String[] bitNames = {
274 for (final String name: bitNames) {
275 final FlowModFlags flags = FlowModFlags.getDefaultInstance(name);
276 assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, all));
277 assertFalse(FlowCreatorUtil.equalsFlowModFlags(all, flags));
278 assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, none));
279 assertFalse(FlowCreatorUtil.equalsFlowModFlags(none, flags));
281 for (final String nm: bitNames) {
282 final FlowModFlags f = FlowModFlags.getDefaultInstance(nm);
283 final boolean expected = nm.equals(name);
284 assertEquals(expected,
285 FlowCreatorUtil.equalsFlowModFlags(flags, f));
286 assertEquals(expected,
287 FlowCreatorUtil.equalsFlowModFlags(f, flags));
290 final boolean overlap = (bit == 0);
291 final boolean noByte = (bit == 1);
292 final boolean noPacket = (bit == 2);
293 final boolean reset = (bit == 3);
294 final boolean flowRem = (bit == 4);
296 new FlowModFlags(overlap, noByte, noPacket, reset, flowRem);
297 assertTrue(FlowCreatorUtil.equalsFlowModFlags(flags, f));
298 assertTrue(FlowCreatorUtil.equalsFlowModFlags(f, flags));
299 assertTrue(FlowCreatorUtil.
300 equalsFlowModFlags(f, new FlowModFlags(f)));
302 f = new FlowModFlags(!overlap, noByte, noPacket, reset, flowRem);
303 assertFalse(FlowCreatorUtil.equalsFlowModFlags(flags, f));
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));
319 * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
322 public void testEqualsWithDefault() {
324 for (final Boolean def: new Boolean[]{Boolean.TRUE, Boolean.FALSE}) {
325 assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
326 assertTrue(FlowCreatorUtil.equalsWithDefault(def, null, def));
327 assertTrue(FlowCreatorUtil.equalsWithDefault(null, def, def));
329 final Boolean inv = Boolean.valueOf(!def.booleanValue());
330 assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
331 assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
335 final Integer[] integers = {
336 Integer.valueOf(-100),
338 Integer.valueOf(100),
340 for (final Integer def: integers) {
341 final Integer same = new Integer(def.intValue());
342 assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
343 assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
344 assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
346 final Integer diff = new Integer(def.intValue() +1);
347 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
348 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
352 final String[] strings = {
357 for (final String def: strings) {
358 final String same = new String(def);
359 assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
360 assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
361 assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
363 final String diff = def + "-1";
364 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
365 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
369 private static void assertMatch (final Match match) {
370 assertTrue(match.getType().getClass().isInstance(OxmMatchType.class));
373 private static void assertMatch (final MatchV10 matchV10) {
374 assertEquals(matchV10.getDlDst(), macAddress);
375 assertEquals(matchV10.getDlSrc(), macAddress);
377 assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
378 assertTrue(matchV10.getNwDstMask().shortValue() == 0);
380 assertTrue(matchV10.getInPort().intValue() == 0);
381 assertTrue(matchV10.getDlVlan().intValue() == 0);
382 assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
383 assertTrue(matchV10.getDlType().intValue() == 0);
385 assertTrue(matchV10.getNwTos().shortValue() == 0);
386 assertTrue(matchV10.getNwProto().shortValue() == 0);
388 assertEquals(matchV10.getNwSrc(), ipv4Address);
389 assertEquals(matchV10.getNwDst(), ipv4Address);
391 assertTrue(matchV10.getTpSrc().intValue() == 0);
392 assertTrue(matchV10.getTpDst().intValue() == 0);
396 * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
397 * returns expected value.
400 * An expected return value.
402 * A original flow builder that contains original flow to be tested.
404 * An updated flow builder that contains updated flow to be tested.
406 * OpenFlow protocol version.
408 private static void canModifyFlowTest (final boolean expected, final OriginalFlowBuilder org,
409 final UpdatedFlowBuilder upd, final Short version) {
410 final boolean result = FlowCreatorUtil.
411 canModifyFlow(org.build(), upd.build(), version);
412 assertEquals(expected, result);
416 * Create a flow match that specifies ethernet type.
418 * @param etherType An ethernet type value.
419 * @return A flow match that specifies the given ethernet type.
421 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match createMatch (final long etherType) {
422 final EthernetTypeBuilder ethType = new EthernetTypeBuilder().
423 setType(new EtherType(etherType));
424 final EthernetMatchBuilder ether = new EthernetMatchBuilder().
425 setEthernetType(ethType.build());
426 return new MatchBuilder().setEthernetMatch(ether.build()).build();