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;
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;
37 public class FlowCreatorUtilTest {
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");
44 * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder)}.
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());
53 multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
54 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestFlowBuilder);
55 multipartRequestFlow = multipartRequestFlowBuilder.build();
56 assertMatch(multipartRequestFlow.getMatch());
61 * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder)}.
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());
70 multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
71 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestAggregateBuilder);
72 multipartRequestAggregate = multipartRequestAggregateBuilder.build();
73 assertMatch(multipartRequestAggregate.getMatch());
80 * {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
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};
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));
99 for (final Short ver : versions) {
100 final OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
101 final UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
102 canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
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);
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);
125 final OriginalFlow org = originalBuilder.build();
126 final UpdatedFlow upd = updatedBuilder.build();
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);
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);
142 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setHardTimeout(i), ver);
143 canModifyFlowTest(false, new OriginalFlowBuilder(org).setHardTimeout(i), updatedBuilder, ver);
145 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setPriority(i), ver);
146 canModifyFlowTest(false, new OriginalFlowBuilder(org).setPriority(i), updatedBuilder, ver);
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);
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);
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);
170 updatedBuilder.setCookieMask(defCookie);
171 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
173 updatedBuilder.setCookieMask(cookieMask);
174 final boolean expected = (of13.equals(ver) && !Boolean.TRUE.equals(strict));
175 canModifyFlowTest(expected, originalBuilder, updatedBuilder, ver);
182 * {@link FlowCreatorUtil#equalsFlowModFlags(FlowModFlags, FlowModFlags)}.
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);
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));
200 final String[] bitNames = {"cHECKOVERLAP", "nOBYTCOUNTS", "nOPKTCOUNTS", "rESETCOUNTS", "sENDFLOWREM"};
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));
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));
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)));
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));
243 * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
246 public void testEqualsWithDefault() {
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));
253 final Boolean inv = Boolean.valueOf(!def.booleanValue());
254 assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
255 assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
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));
266 final Integer diff = new Integer(def.intValue() + 1);
267 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
268 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
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));
279 final String diff = def + "-1";
280 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
281 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
285 private static void assertMatch(final Match match) {
286 assertTrue(match.getType().getClass().isInstance(OxmMatchType.class));
289 private static void assertMatch(final MatchV10 matchV10) {
290 assertEquals(matchV10.getDlDst(), MAC_ADDRESS);
291 assertEquals(matchV10.getDlSrc(), MAC_ADDRESS);
293 assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
294 assertTrue(matchV10.getNwDstMask().shortValue() == 0);
296 assertTrue(matchV10.getInPort().intValue() == 0);
297 assertTrue(matchV10.getDlVlan().intValue() == 0);
298 assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
299 assertTrue(matchV10.getDlType().intValue() == 0);
301 assertTrue(matchV10.getNwTos().shortValue() == 0);
302 assertTrue(matchV10.getNwProto().shortValue() == 0);
304 assertEquals(matchV10.getNwSrc(), IPV_4_ADDRESS);
305 assertEquals(matchV10.getNwDst(), IPV_4_ADDRESS);
307 assertTrue(matchV10.getTpSrc().intValue() == 0);
308 assertTrue(matchV10.getTpDst().intValue() == 0);
312 * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
313 * returns expected value.
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.
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);
327 * Create a flow match that specifies ethernet type.
329 * @param etherType An ethernet type value.
330 * @return A flow match that specifies the given ethernet type.
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();