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 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;
40 public class FlowCreatorUtilTest {
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");
47 * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestFlowBuilder flowBuilder)}.
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());
56 multipartRequestFlowBuilder = new MultipartRequestFlowBuilder();
57 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestFlowBuilder);
58 multipartRequestFlow = multipartRequestFlowBuilder.build();
59 assertMatch(multipartRequestFlow.getMatch());
64 * {@link FlowCreatorUtil#setWildcardedFlowMatch(short version, MultipartRequestAggregateBuilder aggregateBuilder)}.
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());
73 multipartRequestAggregateBuilder = new MultipartRequestAggregateBuilder();
74 FlowCreatorUtil.setWildcardedFlowMatch(OFConstants.OFP_VERSION_1_3, multipartRequestAggregateBuilder);
75 multipartRequestAggregate = multipartRequestAggregateBuilder.build();
76 assertMatch(multipartRequestAggregate.getMatch());
83 * {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
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};
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));
100 for (final Uint8 ver : versions) {
101 final OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
102 final UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
103 canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
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);
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);
129 final OriginalFlow org = originalBuilder.build();
130 final UpdatedFlow upd = updatedBuilder.build();
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);
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);
147 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setHardTimeout(uint), ver);
148 canModifyFlowTest(false, new OriginalFlowBuilder(org).setHardTimeout(uint), updatedBuilder, ver);
150 canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setPriority(uint), ver);
151 canModifyFlowTest(false, new OriginalFlowBuilder(org).setPriority(uint), updatedBuilder, ver);
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);
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);
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);
175 updatedBuilder.setCookieMask(defCookie);
176 canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
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);
187 * {@link FlowCreatorUtil#equalsFlowModFlags(FlowModFlags, FlowModFlags)}.
190 public void testEqualsFlowModFlags() {
191 final FlowModFlags[] defaults = {
193 new FlowModFlags(false, false, false, false, false),
194 new FlowModFlags(false, false, false, false, false)
196 final FlowModFlags all = new FlowModFlags(true, true, true, true, true);
197 final FlowModFlags none = new FlowModFlags(false, false, false, false, false);
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));
208 final String[] bitNames = {"cHECKOVERLAP", "nOBYTCOUNTS", "nOPKTCOUNTS", "rESETCOUNTS", "sENDFLOWREM"};
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));
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));
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)));
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));
251 * {@link FlowCreatorUtil#equalsWithDefault(Object, Object, Object)}.
254 public void testEqualsWithDefault() {
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));
261 final Boolean inv = !def.booleanValue();
262 assertFalse(FlowCreatorUtil.equalsWithDefault(null, inv, def));
263 assertFalse(FlowCreatorUtil.equalsWithDefault(inv, null, def));
267 final Integer[] integers = {-1000, 0, 1000,};
268 for (final Integer def : integers) {
269 final Integer same = Integer.valueOf(def);
270 assertTrue(FlowCreatorUtil.equalsWithDefault(null, null, def));
271 assertTrue(FlowCreatorUtil.equalsWithDefault(same, null, def));
272 assertTrue(FlowCreatorUtil.equalsWithDefault(null, same, def));
274 final Integer diff = Integer.valueOf(def.intValue() + 1);
275 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
276 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
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));
287 final String diff = def + "-1";
288 assertFalse(FlowCreatorUtil.equalsWithDefault(null, diff, def));
289 assertFalse(FlowCreatorUtil.equalsWithDefault(diff, null, def));
293 private static void assertMatch(final Match match) {
294 assertEquals(OxmMatchType.VALUE, match.getType());
297 private static void assertMatch(final MatchV10 matchV10) {
298 assertEquals(matchV10.getDlDst(), MAC_ADDRESS);
299 assertEquals(matchV10.getDlSrc(), MAC_ADDRESS);
301 assertTrue(matchV10.getNwSrcMask().shortValue() == 0);
302 assertTrue(matchV10.getNwDstMask().shortValue() == 0);
304 assertTrue(matchV10.getInPort().intValue() == 0);
305 assertTrue(matchV10.getDlVlan().intValue() == 0);
306 assertTrue(matchV10.getDlVlanPcp().shortValue() == 0);
307 assertTrue(matchV10.getDlType().intValue() == 0);
309 assertTrue(matchV10.getNwTos().shortValue() == 0);
310 assertTrue(matchV10.getNwProto().shortValue() == 0);
312 assertEquals(matchV10.getNwSrc(), IPV_4_ADDRESS);
313 assertEquals(matchV10.getNwDst(), IPV_4_ADDRESS);
315 assertTrue(matchV10.getTpSrc().intValue() == 0);
316 assertTrue(matchV10.getTpDst().intValue() == 0);
320 * Verify that {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}
321 * returns expected value.
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.
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);
335 * Create a flow match that specifies ethernet type.
337 * @param etherType An ethernet type value.
338 * @return A flow match that specifies the given ethernet type.
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();