blob: f4549c5b96385d0f3337c0bcf483f6eb87e46d7d [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.flow.impl;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070017
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableMap;
20import com.google.common.collect.Lists;
21import com.google.common.collect.Sets;
22import com.google.common.util.concurrent.ListenableFuture;
23import com.google.common.util.concurrent.MoreExecutors;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070024import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080027import org.onlab.junit.TestTools;
Marc De Leenheerde47caa2015-04-24 11:27:44 -070028import org.onosproject.cfg.ComponentConfigAdapter;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080029import org.onosproject.common.event.impl.TestEventDispatcher;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.core.ApplicationId;
Ray Milkeycc53abd2015-02-19 12:31:33 -080031import org.onosproject.core.CoreServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.core.DefaultApplicationId;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080033import org.onosproject.core.IdGenerator;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080034import org.onosproject.mastership.MastershipServiceAdapter;
35import org.onosproject.net.AnnotationKeys;
36import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.DefaultDevice;
38import org.onosproject.net.Device;
39import org.onosproject.net.Device.Type;
40import org.onosproject.net.DeviceId;
41import org.onosproject.net.MastershipRole;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070042import org.onosproject.net.config.NetworkConfigServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.device.DeviceServiceAdapter;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080044import org.onosproject.net.driver.AbstractHandlerBehaviour;
45import org.onosproject.net.driver.DefaultDriver;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070046import org.onosproject.net.driver.DriverRegistry;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080047import org.onosproject.net.driver.impl.DriverManager;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070048import org.onosproject.net.driver.impl.DriverRegistryManager;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import org.onosproject.net.flow.CompletedBatchOperation;
50import org.onosproject.net.flow.DefaultFlowEntry;
51import org.onosproject.net.flow.DefaultFlowRule;
52import org.onosproject.net.flow.FlowEntry;
53import org.onosproject.net.flow.FlowEntry.FlowEntryState;
54import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080055import org.onosproject.net.flow.FlowRuleEvent;
56import org.onosproject.net.flow.FlowRuleListener;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080057import org.onosproject.net.flow.FlowRuleProgrammable;
Brian O'Connorabafb502014-12-02 22:26:20 -080058import org.onosproject.net.flow.FlowRuleProvider;
59import org.onosproject.net.flow.FlowRuleProviderRegistry;
60import org.onosproject.net.flow.FlowRuleProviderService;
61import org.onosproject.net.flow.FlowRuleService;
62import org.onosproject.net.flow.StoredFlowEntry;
63import org.onosproject.net.flow.TrafficSelector;
64import org.onosproject.net.flow.TrafficTreatment;
65import org.onosproject.net.flow.criteria.Criterion;
66import org.onosproject.net.flow.instructions.Instruction;
alshabib346b5b32015-03-06 00:42:16 -080067import org.onosproject.net.flow.instructions.Instructions;
Saurav Das86af8f12015-05-25 23:55:33 -070068import org.onosproject.net.flow.instructions.Instructions.MetadataInstruction;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070069import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
70import org.onosproject.net.pi.PiPipeconfServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080071import org.onosproject.net.provider.AbstractProvider;
72import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070073import org.onosproject.store.trivial.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070074
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070075import java.util.ArrayList;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080076import java.util.Collection;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070077import java.util.Collections;
78import java.util.HashMap;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080079import java.util.HashSet;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070080import java.util.List;
81import java.util.Map;
82import java.util.Set;
83import java.util.concurrent.ExecutionException;
84import java.util.concurrent.Executor;
85import java.util.concurrent.TimeUnit;
86import java.util.concurrent.TimeoutException;
87import java.util.concurrent.atomic.AtomicLong;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070088
Carmelo Cascone0761cd32018-08-29 19:22:50 -070089import static org.junit.Assert.assertEquals;
90import static org.junit.Assert.assertFalse;
91import static org.junit.Assert.assertNotNull;
92import static org.junit.Assert.assertTrue;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070093import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Carmelo Cascone0761cd32018-08-29 19:22:50 -070094import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_ADDED;
95import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_ADD_REQUESTED;
96import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
97import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVE_REQUESTED;
98import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070099
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700100/**
101 * Test codifying the flow rule service & flow rule provider service contracts.
102 */
tom202175a2014-09-19 19:00:11 -0700103public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700104
alshabib92c65ad2014-10-08 21:56:05 -0700105
tomf6ab2152014-09-18 12:08:29 -0700106 private static final ProviderId PID = new ProviderId("of", "foo");
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800107 private static final ProviderId FOO_PID = new ProviderId("foo", "foo");
108
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700109 private static final DeviceId DID = DeviceId.deviceId("of:001");
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800110 private static final DeviceId FOO_DID = DeviceId.deviceId("foo:002");
alshabibba5ac482014-10-02 17:15:20 -0700111 private static final int TIMEOUT = 10;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800112
113 private static final DefaultAnnotations ANNOTATIONS =
114 DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
115
116 private static final Device DEV =
117 new DefaultDevice(PID, DID, Type.SWITCH, "", "", "", "", null);
118 private static final Device FOO_DEV =
119 new DefaultDevice(FOO_PID, FOO_DID, Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700120
tom202175a2014-09-19 19:00:11 -0700121 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700122
123 protected FlowRuleService service;
124 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -0700125 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700126 protected TestProvider provider;
127 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -0700128 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700129
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800130 private TestDriverManager driverService;
131
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700132 @Before
133 public void setUp() {
tom202175a2014-09-19 19:00:11 -0700134 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -0700135 mgr.store = new SimpleFlowRuleStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700136 injectEventDispatcher(mgr, new TestEventDispatcher());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700137 mgr.deviceService = new TestDeviceService();
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800138 mgr.mastershipService = new TestMastershipService();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800139 mgr.coreService = new TestCoreService();
140 mgr.operationsService = MoreExecutors.newDirectExecutorService();
141 mgr.deviceInstallers = MoreExecutors.newDirectExecutorService();
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700142 mgr.cfgService = new ComponentConfigAdapter();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700143 service = mgr;
144 registry = mgr;
145
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700146 DriverRegistryManager driverRegistry = new DriverRegistryManager();
147 driverService = new TestDriverManager(driverRegistry);
148 driverRegistry.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
149 ImmutableMap.of(FlowRuleProgrammable.class,
150 TestFlowRuleProgrammable.class),
151 ImmutableMap.of()));
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800152
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700153 mgr.activate(null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700154 mgr.addListener(listener);
155 provider = new TestProvider(PID);
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700156 providerService = this.registry.register(provider);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800157 appId = new TestApplicationId(0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700158 assertTrue("provider should be registered",
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700159 this.registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700160 }
161
162 @After
163 public void tearDown() {
164 registry.unregister(provider);
165 assertFalse("provider should not be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700166 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700167 service.removeListener(listener);
168 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700169 injectEventDispatcher(mgr, null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700170 mgr.deviceService = null;
171 }
172
173 private FlowRule flowRule(int tsval, int trval) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800174 return flowRule(DID, tsval, trval);
175 }
176
177 private FlowRule flowRule(DeviceId did, int tsval, int trval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700178 TestSelector ts = new TestSelector(tsval);
179 TestTreatment tr = new TestTreatment(trval);
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700180 return DefaultFlowRule.builder()
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800181 .forDevice(did)
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700182 .withSelector(ts)
183 .withTreatment(tr)
184 .withPriority(10)
185 .fromApp(appId)
186 .makeTemporary(TIMEOUT)
187 .build();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700188 }
189
alshabibbb8b1282014-09-22 17:00:18 -0700190 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700191 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700192 service.applyFlowRules(rule);
193
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700194 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700195 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700196 }
197
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700198 private void validateEvents(FlowRuleEvent.Type... events) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700199 if (events == null) {
200 assertTrue("events generated", listener.events.isEmpty());
201 }
202
203 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700204 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700205 for (FlowRuleEvent e : listener.events) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800206 assertEquals("unexpected event", events[i], e.type());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700207 i++;
208 }
209
210 assertEquals("mispredicted number of events",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700211 events.length, listener.events.size());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700212
213 listener.events.clear();
214 }
215
216 private int flowCount() {
217 return Sets.newHashSet(service.getFlowEntries(DID)).size();
218 }
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700219
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700220 @Test
221 public void getFlowEntries() {
222 assertTrue("store should be empty",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700223 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700224 FlowRule f1 = addFlowRule(1);
225 FlowRule f2 = addFlowRule(2);
226
alshabib1c319ff2014-10-04 20:29:09 -0700227 FlowEntry fe1 = new DefaultFlowEntry(f1);
228 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700229 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700230
alshabib1c319ff2014-10-04 20:29:09 -0700231 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700232 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
233 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700234
235 addFlowRule(1);
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800236 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700237 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700238
alshabib1c319ff2014-10-04 20:29:09 -0700239 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
Charles Chan93fa7272016-01-26 22:27:02 -0800240 validateEvents(RULE_UPDATED, RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700241 }
242
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700243 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
244 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700245 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700246 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700247 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
248 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
249 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700250 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700251 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700252 return true;
253 }
254
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700255 @Test
256 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700257
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700258 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700259 FlowRule r2 = flowRule(2, 2);
260 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700261
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700262 assertTrue("store should be empty",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800263 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700264 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700265 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700266 assertTrue("Entries should be pending add.",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800267 validateState(ImmutableMap.of(
268 r1, FlowEntryState.PENDING_ADD,
269 r2, FlowEntryState.PENDING_ADD,
270 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700271 }
272
273 @Test
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530274 public void purgeFlowRules() {
275 FlowRule f1 = addFlowRule(1);
276 FlowRule f2 = addFlowRule(2);
277 FlowRule f3 = addFlowRule(3);
278 assertEquals("3 rules should exist", 3, flowCount());
279 FlowEntry fe1 = new DefaultFlowEntry(f1);
280 FlowEntry fe2 = new DefaultFlowEntry(f2);
281 FlowEntry fe3 = new DefaultFlowEntry(f3);
282 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
283 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700284 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530285 mgr.purgeFlowRules(DID);
286 assertEquals("0 rule should exist", 0, flowCount());
287 }
288
289 @Test
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700290 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700291 FlowRule f1 = addFlowRule(1);
292 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700293 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700294 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700295
alshabib1c319ff2014-10-04 20:29:09 -0700296 FlowEntry fe1 = new DefaultFlowEntry(f1);
297 FlowEntry fe2 = new DefaultFlowEntry(f2);
298 FlowEntry fe3 = new DefaultFlowEntry(f3);
299 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700300 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
301 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700302
alshabib1c319ff2014-10-04 20:29:09 -0700303 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700304 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700305 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700306 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700307 assertTrue("Entries should be pending remove.",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800308 validateState(ImmutableMap.of(
309 f1, FlowEntryState.PENDING_REMOVE,
310 f2, FlowEntryState.PENDING_REMOVE,
311 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700312
alshabib1c319ff2014-10-04 20:29:09 -0700313 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700314 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700315 }
316
317 @Test
318 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700319 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700320 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700321 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700322 FlowEntry fe2 = new DefaultFlowEntry(f2);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800323
alshabib1c319ff2014-10-04 20:29:09 -0700324 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700325 service.removeFlowRules(f1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800326
Brian O'Connora3e5cd52015-12-05 15:59:19 -0800327 //FIXME modification of "stored" flow entry outside of store
alshabib1c319ff2014-10-04 20:29:09 -0700328 fe1.setState(FlowEntryState.REMOVED);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800329
alshabib1c319ff2014-10-04 20:29:09 -0700330 providerService.flowRemoved(fe1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800331
alshabib3d643ec2014-10-22 18:33:00 -0700332 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800333 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700334
alshabib1c319ff2014-10-04 20:29:09 -0700335 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700336 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700337
alshabibba5ac482014-10-02 17:15:20 -0700338 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700339 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700340 service.applyFlowRules(f3);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800341
alshabib1c319ff2014-10-04 20:29:09 -0700342 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
Charles Chan93fa7272016-01-26 22:27:02 -0800343 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
alshabibba5ac482014-10-02 17:15:20 -0700344
alshabib1c319ff2014-10-04 20:29:09 -0700345 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700346 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700347 }
348
alshabibbb8b1282014-09-22 17:00:18 -0700349 @Test
350 public void flowMetrics() {
351 FlowRule f1 = flowRule(1, 1);
352 FlowRule f2 = flowRule(2, 2);
353 FlowRule f3 = flowRule(3, 3);
354
alshabibba5ac482014-10-02 17:15:20 -0700355 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700356
alshabib1c319ff2014-10-04 20:29:09 -0700357 FlowEntry fe1 = new DefaultFlowEntry(f1);
358 FlowEntry fe2 = new DefaultFlowEntry(f2);
359
alshabib1c319ff2014-10-04 20:29:09 -0700360 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
361 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
362
363 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700364
365 assertTrue("Entries should be added.",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700366 validateState(ImmutableMap.of(
367 f1, FlowEntryState.ADDED,
368 f2, FlowEntryState.ADDED,
369 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700370
alshabib3d643ec2014-10-22 18:33:00 -0700371 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
Sivachidambaram Subramanian605104e2017-06-21 07:40:04 +0530372 RULE_ADDED, RULE_ADDED, RULE_ADD_REQUESTED);
alshabibbb42cad2014-09-25 11:43:05 -0700373 }
374
375 @Test
376 public void extraneousFlow() {
377 FlowRule f1 = flowRule(1, 1);
378 FlowRule f2 = flowRule(2, 2);
379 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700380 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700381
alshabib1c319ff2014-10-04 20:29:09 -0700382// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
383// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
384// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
385 FlowEntry fe1 = new DefaultFlowEntry(f1);
386 FlowEntry fe2 = new DefaultFlowEntry(f2);
387 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700388
alshabib1c319ff2014-10-04 20:29:09 -0700389
390 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700391
alshabib3d643ec2014-10-22 18:33:00 -0700392 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700393
394 }
395
396 /*
397 * Tests whether a rule that was marked for removal but no flowRemoved was received
398 * is indeed removed at the next stats update.
399 */
400 @Test
401 public void flowMissingRemove() {
402 FlowRule f1 = flowRule(1, 1);
403 FlowRule f2 = flowRule(2, 2);
404 FlowRule f3 = flowRule(3, 3);
405
alshabib1c319ff2014-10-04 20:29:09 -0700406// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
407// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
408
409 FlowEntry fe1 = new DefaultFlowEntry(f1);
410 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700411 mgr.applyFlowRules(f1, f2, f3);
412
413 mgr.removeFlowRules(f3);
414
alshabib1c319ff2014-10-04 20:29:09 -0700415 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700416
alshabib3d643ec2014-10-22 18:33:00 -0700417 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
418 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700419
420 }
421
422 @Test
423 public void getByAppId() {
424 FlowRule f1 = flowRule(1, 1);
425 FlowRule f2 = flowRule(2, 2);
426 mgr.applyFlowRules(f1, f2);
427
428 assertTrue("should have two rules",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800429 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700430 }
431
432 @Test
433 public void removeByAppId() {
434 FlowRule f1 = flowRule(1, 1);
435 FlowRule f2 = flowRule(2, 2);
436 mgr.applyFlowRules(f1, f2);
437
438
439 mgr.removeFlowRulesById(appId);
440
441 //only check that we are in pending remove. Events and actual remove state will
442 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700443 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700444 f1, FlowEntryState.PENDING_REMOVE,
445 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700446 }
447
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800448 @Test
449 public void fallbackBasics() {
450 FlowRule f1 = flowRule(FOO_DID, 1, 1);
451 flowRules.clear();
452 mgr.applyFlowRules(f1);
453 assertTrue("flow rule not applied", flowRules.contains(f1));
454
455 flowRules.clear();
456 mgr.removeFlowRules(f1);
457 assertTrue("flow rule not removed", flowRules.contains(f1));
458 }
459
460 @Test
461 public void fallbackFlowRemoved() {
462 FlowRule f1 = flowRule(FOO_DID, 1, 1);
463 mgr.applyFlowRules(f1);
464 flowRules.clear();
465 providerService.flowRemoved(new DefaultFlowEntry(f1));
466 assertTrue("flow rule not reapplied", flowRules.contains(f1));
467 }
468
469 @Test
470 public void fallbackExtraFlow() {
471 FlowRule f1 = flowRule(FOO_DID, 1, 1);
472 flowRules.clear();
473 providerService.pushFlowMetrics(FOO_DID, ImmutableList.of(new DefaultFlowEntry(f1)));
474 assertTrue("flow rule not removed", flowRules.contains(f1));
475 }
476
477 @Test
478 public void fallbackPoll() {
479 FlowRuleDriverProvider fallback = (FlowRuleDriverProvider) mgr.defaultProvider();
480 FlowRule f1 = flowRule(FOO_DID, 1, 1);
481 mgr.applyFlowRules(f1);
482 FlowEntry fe = mgr.getFlowEntries(FOO_DID).iterator().next();
483 assertEquals("incorrect state", FlowEntryState.PENDING_ADD, fe.state());
484
485 fallback.init(fallback.providerService, mgr.deviceService, mgr.mastershipService, 1);
486 TestTools.assertAfter(2000, () -> {
487 FlowEntry e = mgr.getFlowEntries(FOO_DID).iterator().next();
488 assertEquals("incorrect state", FlowEntryState.ADDED, e.state());
489 });
490 }
491
492
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700493 private static class TestListener implements FlowRuleListener {
494 final List<FlowRuleEvent> events = new ArrayList<>();
495
496 @Override
497 public void event(FlowRuleEvent event) {
498 events.add(event);
499 }
500 }
501
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800502 private static class TestDeviceService extends DeviceServiceAdapter {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700503 @Override
504 public int getDeviceCount() {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800505 return 2;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700506 }
507
508 @Override
509 public Iterable<Device> getDevices() {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800510 return ImmutableList.of(DEV, FOO_DEV);
511 }
512
513 @Override
514 public Iterable<Device> getAvailableDevices() {
515 return getDevices();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700516 }
517
518 @Override
519 public Device getDevice(DeviceId deviceId) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800520 return deviceId.equals(FOO_DID) ? FOO_DEV : DEV;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700521 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700522 }
523
524 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
525
526 protected TestProvider(ProviderId id) {
527 super(PID);
528 }
529
530 @Override
531 public void applyFlowRule(FlowRule... flowRules) {
532 }
533
534 @Override
535 public void removeFlowRule(FlowRule... flowRules) {
536 }
537
alshabiba68eb962014-09-24 20:34:13 -0700538 @Override
539 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
540 }
541
alshabib902d41b2014-10-07 16:52:05 -0700542 @Override
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800543 public void executeBatch(FlowRuleBatchOperation batch) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800544 // TODO: need to call batchOperationComplete
alshabib902d41b2014-10-07 16:52:05 -0700545 }
546
alshabibcf369912014-10-13 14:16:42 -0700547 private class TestInstallationFuture
Madan Jampani117aaae2014-10-23 10:04:05 -0700548 implements ListenableFuture<CompletedBatchOperation> {
alshabibcf369912014-10-13 14:16:42 -0700549
550 @Override
551 public boolean cancel(boolean mayInterruptIfRunning) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800552 return false;
alshabibcf369912014-10-13 14:16:42 -0700553 }
554
555 @Override
556 public boolean isCancelled() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800557 return false;
alshabibcf369912014-10-13 14:16:42 -0700558 }
559
560 @Override
561 public boolean isDone() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800562 return true;
alshabibcf369912014-10-13 14:16:42 -0700563 }
564
565 @Override
566 public CompletedBatchOperation get()
567 throws InterruptedException, ExecutionException {
Sho SHIMIZU21d00692016-08-15 11:15:28 -0700568 return new CompletedBatchOperation(true, Collections.emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700569 }
570
571 @Override
572 public CompletedBatchOperation get(long timeout, TimeUnit unit)
573 throws InterruptedException,
574 ExecutionException, TimeoutException {
Sho SHIMIZU21d00692016-08-15 11:15:28 -0700575 return new CompletedBatchOperation(true, Collections.emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700576 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700577
578 @Override
579 public void addListener(Runnable task, Executor executor) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800580 if (isDone()) {
581 executor.execute(task);
582 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700583 }
alshabibcf369912014-10-13 14:16:42 -0700584 }
alshabiba68eb962014-09-24 20:34:13 -0700585
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700586 }
587
588 private class TestSelector implements TrafficSelector {
589
590 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700591 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700592
593 public TestSelector(int val) {
594 testval = val;
595 }
596
597 @Override
alshabibba5ac482014-10-02 17:15:20 -0700598 public Set<Criterion> criteria() {
Hyunsun Moon7bfbc1c2016-04-05 16:40:43 -0700599 return Collections.emptySet();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700600 }
601
602 @Override
Jonathan Hart936c49d2014-10-23 16:38:59 -0700603 public Criterion getCriterion(
Brian O'Connorabafb502014-12-02 22:26:20 -0800604 org.onosproject.net.flow.criteria.Criterion.Type type) {
Jonathan Hart936c49d2014-10-23 16:38:59 -0700605 return null;
606 }
607
608 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700609 public int hashCode() {
610 return testval;
611 }
612
613 @Override
614 public boolean equals(Object o) {
615 if (o instanceof TestSelector) {
616 return this.testval == ((TestSelector) o).testval;
617 }
618 return false;
619 }
Jonathan Hart936c49d2014-10-23 16:38:59 -0700620
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700621 }
622
623 private class TestTreatment implements TrafficTreatment {
624
625 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700626 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700627
628 public TestTreatment(int val) {
629 testval = val;
630 }
631
632 @Override
alshabib346b5b32015-03-06 00:42:16 -0800633 public List<Instruction> deferred() {
634 return null;
635 }
636
637 @Override
638 public List<Instruction> immediate() {
639 return null;
640 }
641
642 @Override
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700643 public List<Instruction> allInstructions() {
644 return null;
645 }
646
647 @Override
alshabib346b5b32015-03-06 00:42:16 -0800648 public Instructions.TableTypeTransition tableTransition() {
649 return null;
650 }
651
652 @Override
Jonathan Hart4a0ba562015-03-23 17:23:33 -0700653 public boolean clearedDeferred() {
654 return false;
alshabib346b5b32015-03-06 00:42:16 -0800655 }
656
657 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700658 public int hashCode() {
659 return testval;
660 }
661
662 @Override
663 public boolean equals(Object o) {
664 if (o instanceof TestTreatment) {
665 return this.testval == ((TestTreatment) o).testval;
666 }
667 return false;
668 }
669
Saurav Das86af8f12015-05-25 23:55:33 -0700670 @Override
671 public MetadataInstruction writeMetadata() {
672 return null;
673 }
674
alshabib10c810b2015-08-18 16:59:04 -0700675 @Override
Cem Türker3baff672017-10-12 15:09:01 +0300676 public Instructions.StatTriggerInstruction statTrigger() {
677 return null;
678 }
679
680 @Override
alshabib10c810b2015-08-18 16:59:04 -0700681 public Instructions.MeterInstruction metered() {
682 return null;
683 }
684
cansu.toprak409289d2017-10-27 10:04:05 +0300685 @Override
686 public Set<Instructions.MeterInstruction> meters() {
687 return Sets.newHashSet();
688 }
689
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700690 }
691
alshabib92c65ad2014-10-08 21:56:05 -0700692 public class TestApplicationId extends DefaultApplicationId {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800693 public TestApplicationId(int id, String name) {
alshabib92c65ad2014-10-08 21:56:05 -0700694 super(id, name);
695 }
696 }
697
Ray Milkeycc53abd2015-02-19 12:31:33 -0800698 private class TestCoreService extends CoreServiceAdapter {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800699
700 @Override
701 public IdGenerator getIdGenerator(String topic) {
702 return new IdGenerator() {
703 private AtomicLong counter = new AtomicLong(0);
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800704
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800705 @Override
706 public long getNewId() {
707 return counter.getAndIncrement();
708 }
709 };
710 }
711 }
712
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800713 private class TestMastershipService extends MastershipServiceAdapter {
714 @Override
715 public MastershipRole getLocalRole(DeviceId deviceId) {
716 return MastershipRole.MASTER;
717 }
718 }
719
720 private class TestDriverManager extends DriverManager {
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700721 TestDriverManager(DriverRegistry registry) {
722 this.registry = registry;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800723 this.deviceService = mgr.deviceService;
Carmelo Cascone0761cd32018-08-29 19:22:50 -0700724 this.pipeconfService = new PiPipeconfServiceAdapter();
725 this.networkConfigService = new NetworkConfigServiceAdapter();
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800726 activate();
727 }
728 }
729
730 static Collection<FlowRule> flowRules = new HashSet<>();
731
732 public static class TestFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
733
734 @Override
735 public Collection<FlowEntry> getFlowEntries() {
736 ImmutableList.Builder<FlowEntry> builder = ImmutableList.builder();
737 flowRules.stream().map(DefaultFlowEntry::new).forEach(builder::add);
738 return builder.build();
739 }
740
741 @Override
742 public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
743 flowRules.addAll(rules);
744 return rules;
745 }
746
747 @Override
748 public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
749 flowRules.addAll(rules);
750 return rules;
751 }
752 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700753}