blob: b3df23266ebb48ff45f97c0a0fd87e4c3af96b14 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
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;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.device.DeviceServiceAdapter;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080043import org.onosproject.net.driver.AbstractHandlerBehaviour;
44import org.onosproject.net.driver.DefaultDriver;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070045import org.onosproject.net.driver.DriverRegistry;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080046import org.onosproject.net.driver.impl.DriverManager;
Thomas Vachuska11b99fc2017-04-27 12:51:04 -070047import org.onosproject.net.driver.impl.DriverRegistryManager;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.net.flow.CompletedBatchOperation;
49import org.onosproject.net.flow.DefaultFlowEntry;
50import org.onosproject.net.flow.DefaultFlowRule;
51import org.onosproject.net.flow.FlowEntry;
52import org.onosproject.net.flow.FlowEntry.FlowEntryState;
53import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080054import org.onosproject.net.flow.FlowRuleBatchOperation;
55import 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;
Brian O'Connorabafb502014-12-02 22:26:20 -080069import org.onosproject.net.provider.AbstractProvider;
70import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070071import org.onosproject.store.trivial.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070072
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070073import java.util.ArrayList;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080074import java.util.Collection;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070075import java.util.Collections;
76import java.util.HashMap;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080077import java.util.HashSet;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070078import java.util.List;
79import java.util.Map;
80import java.util.Set;
81import java.util.concurrent.ExecutionException;
82import java.util.concurrent.Executor;
83import java.util.concurrent.TimeUnit;
84import java.util.concurrent.TimeoutException;
85import java.util.concurrent.atomic.AtomicLong;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070086
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080087import static org.junit.Assert.*;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070088import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080089import static org.onosproject.net.flow.FlowRuleEvent.Type.*;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070090
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070091/**
92 * Test codifying the flow rule service & flow rule provider service contracts.
93 */
tom202175a2014-09-19 19:00:11 -070094public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070095
alshabib92c65ad2014-10-08 21:56:05 -070096
tomf6ab2152014-09-18 12:08:29 -070097 private static final ProviderId PID = new ProviderId("of", "foo");
Thomas Vachuskac4ee7372016-02-02 16:10:09 -080098 private static final ProviderId FOO_PID = new ProviderId("foo", "foo");
99
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700100 private static final DeviceId DID = DeviceId.deviceId("of:001");
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800101 private static final DeviceId FOO_DID = DeviceId.deviceId("foo:002");
alshabibba5ac482014-10-02 17:15:20 -0700102 private static final int TIMEOUT = 10;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800103
104 private static final DefaultAnnotations ANNOTATIONS =
105 DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, "foo").build();
106
107 private static final Device DEV =
108 new DefaultDevice(PID, DID, Type.SWITCH, "", "", "", "", null);
109 private static final Device FOO_DEV =
110 new DefaultDevice(FOO_PID, FOO_DID, Type.SWITCH, "", "", "", "", null, ANNOTATIONS);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700111
tom202175a2014-09-19 19:00:11 -0700112 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700113
114 protected FlowRuleService service;
115 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -0700116 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700117 protected TestProvider provider;
118 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -0700119 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700120
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800121 private TestDriverManager driverService;
122
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700123 @Before
124 public void setUp() {
tom202175a2014-09-19 19:00:11 -0700125 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -0700126 mgr.store = new SimpleFlowRuleStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700127 injectEventDispatcher(mgr, new TestEventDispatcher());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700128 mgr.deviceService = new TestDeviceService();
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800129 mgr.mastershipService = new TestMastershipService();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800130 mgr.coreService = new TestCoreService();
131 mgr.operationsService = MoreExecutors.newDirectExecutorService();
132 mgr.deviceInstallers = MoreExecutors.newDirectExecutorService();
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700133 mgr.cfgService = new ComponentConfigAdapter();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700134 service = mgr;
135 registry = mgr;
136
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700137 DriverRegistryManager driverRegistry = new DriverRegistryManager();
138 driverService = new TestDriverManager(driverRegistry);
139 driverRegistry.addDriver(new DefaultDriver("foo", ImmutableList.of(), "", "", "",
140 ImmutableMap.of(FlowRuleProgrammable.class,
141 TestFlowRuleProgrammable.class),
142 ImmutableMap.of()));
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800143
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700144 mgr.activate(null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700145 mgr.addListener(listener);
146 provider = new TestProvider(PID);
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700147 providerService = this.registry.register(provider);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800148 appId = new TestApplicationId(0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700149 assertTrue("provider should be registered",
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700150 this.registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700151 }
152
153 @After
154 public void tearDown() {
155 registry.unregister(provider);
156 assertFalse("provider should not be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700157 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700158 service.removeListener(listener);
159 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700160 injectEventDispatcher(mgr, null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700161 mgr.deviceService = null;
162 }
163
164 private FlowRule flowRule(int tsval, int trval) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800165 return flowRule(DID, tsval, trval);
166 }
167
168 private FlowRule flowRule(DeviceId did, int tsval, int trval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700169 TestSelector ts = new TestSelector(tsval);
170 TestTreatment tr = new TestTreatment(trval);
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700171 return DefaultFlowRule.builder()
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800172 .forDevice(did)
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700173 .withSelector(ts)
174 .withTreatment(tr)
175 .withPriority(10)
176 .fromApp(appId)
177 .makeTemporary(TIMEOUT)
178 .build();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700179 }
180
alshabibbb8b1282014-09-22 17:00:18 -0700181 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700182 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700183 service.applyFlowRules(rule);
184
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700185 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700186 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700187 }
188
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700189 private void validateEvents(FlowRuleEvent.Type... events) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700190 if (events == null) {
191 assertTrue("events generated", listener.events.isEmpty());
192 }
193
194 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700195 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700196 for (FlowRuleEvent e : listener.events) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800197 assertEquals("unexpected event", events[i], e.type());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700198 i++;
199 }
200
201 assertEquals("mispredicted number of events",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700202 events.length, listener.events.size());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700203
204 listener.events.clear();
205 }
206
207 private int flowCount() {
208 return Sets.newHashSet(service.getFlowEntries(DID)).size();
209 }
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700210
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700211 @Test
212 public void getFlowEntries() {
213 assertTrue("store should be empty",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700214 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700215 FlowRule f1 = addFlowRule(1);
216 FlowRule f2 = addFlowRule(2);
217
alshabib1c319ff2014-10-04 20:29:09 -0700218 FlowEntry fe1 = new DefaultFlowEntry(f1);
219 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700220 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700221
alshabib1c319ff2014-10-04 20:29:09 -0700222 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700223 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
224 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700225
226 addFlowRule(1);
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800227 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700228 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700229
alshabib1c319ff2014-10-04 20:29:09 -0700230 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
Charles Chan93fa7272016-01-26 22:27:02 -0800231 validateEvents(RULE_UPDATED, RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700232 }
233
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700234 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
235 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700236 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700237 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700238 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
239 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
240 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700241 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700242 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700243 return true;
244 }
245
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700246 @Test
247 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700248
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700249 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700250 FlowRule r2 = flowRule(2, 2);
251 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700252
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700253 assertTrue("store should be empty",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800254 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700255 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700256 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700257 assertTrue("Entries should be pending add.",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800258 validateState(ImmutableMap.of(
259 r1, FlowEntryState.PENDING_ADD,
260 r2, FlowEntryState.PENDING_ADD,
261 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700262 }
263
264 @Test
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530265 public void purgeFlowRules() {
266 FlowRule f1 = addFlowRule(1);
267 FlowRule f2 = addFlowRule(2);
268 FlowRule f3 = addFlowRule(3);
269 assertEquals("3 rules should exist", 3, flowCount());
270 FlowEntry fe1 = new DefaultFlowEntry(f1);
271 FlowEntry fe2 = new DefaultFlowEntry(f2);
272 FlowEntry fe3 = new DefaultFlowEntry(f3);
273 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
274 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700275 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Kavitha Alagesanc69c66a2016-06-15 14:26:04 +0530276 mgr.purgeFlowRules(DID);
277 assertEquals("0 rule should exist", 0, flowCount());
278 }
279
280 @Test
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700281 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700282 FlowRule f1 = addFlowRule(1);
283 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700284 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700285 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700286
alshabib1c319ff2014-10-04 20:29:09 -0700287 FlowEntry fe1 = new DefaultFlowEntry(f1);
288 FlowEntry fe2 = new DefaultFlowEntry(f2);
289 FlowEntry fe3 = new DefaultFlowEntry(f3);
290 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700291 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
292 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700293
alshabib1c319ff2014-10-04 20:29:09 -0700294 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700295 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700296 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700297 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700298 assertTrue("Entries should be pending remove.",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800299 validateState(ImmutableMap.of(
300 f1, FlowEntryState.PENDING_REMOVE,
301 f2, FlowEntryState.PENDING_REMOVE,
302 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700303
alshabib1c319ff2014-10-04 20:29:09 -0700304 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700305 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700306 }
307
308 @Test
309 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700310 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700311 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700312 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700313 FlowEntry fe2 = new DefaultFlowEntry(f2);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800314
alshabib1c319ff2014-10-04 20:29:09 -0700315 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700316 service.removeFlowRules(f1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800317
Brian O'Connora3e5cd52015-12-05 15:59:19 -0800318 //FIXME modification of "stored" flow entry outside of store
alshabib1c319ff2014-10-04 20:29:09 -0700319 fe1.setState(FlowEntryState.REMOVED);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800320
alshabib1c319ff2014-10-04 20:29:09 -0700321 providerService.flowRemoved(fe1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800322
alshabib3d643ec2014-10-22 18:33:00 -0700323 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800324 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700325
alshabib1c319ff2014-10-04 20:29:09 -0700326 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700327 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700328
alshabibba5ac482014-10-02 17:15:20 -0700329 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700330 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700331 service.applyFlowRules(f3);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800332
alshabib1c319ff2014-10-04 20:29:09 -0700333 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
Charles Chan93fa7272016-01-26 22:27:02 -0800334 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED, RULE_UPDATED);
alshabibba5ac482014-10-02 17:15:20 -0700335
alshabib1c319ff2014-10-04 20:29:09 -0700336 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700337 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700338 }
339
alshabibbb8b1282014-09-22 17:00:18 -0700340 @Test
341 public void flowMetrics() {
342 FlowRule f1 = flowRule(1, 1);
343 FlowRule f2 = flowRule(2, 2);
344 FlowRule f3 = flowRule(3, 3);
345
alshabibba5ac482014-10-02 17:15:20 -0700346 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700347
alshabib1c319ff2014-10-04 20:29:09 -0700348 FlowEntry fe1 = new DefaultFlowEntry(f1);
349 FlowEntry fe2 = new DefaultFlowEntry(f2);
350
alshabib1c319ff2014-10-04 20:29:09 -0700351 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
352 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
353
354 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700355
356 assertTrue("Entries should be added.",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700357 validateState(ImmutableMap.of(
358 f1, FlowEntryState.ADDED,
359 f2, FlowEntryState.ADDED,
360 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700361
alshabib3d643ec2014-10-22 18:33:00 -0700362 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800363 RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700364 }
365
366 @Test
367 public void extraneousFlow() {
368 FlowRule f1 = flowRule(1, 1);
369 FlowRule f2 = flowRule(2, 2);
370 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700371 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700372
alshabib1c319ff2014-10-04 20:29:09 -0700373// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
374// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
375// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
376 FlowEntry fe1 = new DefaultFlowEntry(f1);
377 FlowEntry fe2 = new DefaultFlowEntry(f2);
378 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700379
alshabib1c319ff2014-10-04 20:29:09 -0700380
381 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700382
alshabib3d643ec2014-10-22 18:33:00 -0700383 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700384
385 }
386
387 /*
388 * Tests whether a rule that was marked for removal but no flowRemoved was received
389 * is indeed removed at the next stats update.
390 */
391 @Test
392 public void flowMissingRemove() {
393 FlowRule f1 = flowRule(1, 1);
394 FlowRule f2 = flowRule(2, 2);
395 FlowRule f3 = flowRule(3, 3);
396
alshabib1c319ff2014-10-04 20:29:09 -0700397// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
398// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
399
400 FlowEntry fe1 = new DefaultFlowEntry(f1);
401 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700402 mgr.applyFlowRules(f1, f2, f3);
403
404 mgr.removeFlowRules(f3);
405
alshabib1c319ff2014-10-04 20:29:09 -0700406 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700407
alshabib3d643ec2014-10-22 18:33:00 -0700408 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
409 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700410
411 }
412
413 @Test
414 public void getByAppId() {
415 FlowRule f1 = flowRule(1, 1);
416 FlowRule f2 = flowRule(2, 2);
417 mgr.applyFlowRules(f1, f2);
418
419 assertTrue("should have two rules",
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800420 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700421 }
422
423 @Test
424 public void removeByAppId() {
425 FlowRule f1 = flowRule(1, 1);
426 FlowRule f2 = flowRule(2, 2);
427 mgr.applyFlowRules(f1, f2);
428
429
430 mgr.removeFlowRulesById(appId);
431
432 //only check that we are in pending remove. Events and actual remove state will
433 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700434 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700435 f1, FlowEntryState.PENDING_REMOVE,
436 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700437 }
438
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800439 @Test
440 public void fallbackBasics() {
441 FlowRule f1 = flowRule(FOO_DID, 1, 1);
442 flowRules.clear();
443 mgr.applyFlowRules(f1);
444 assertTrue("flow rule not applied", flowRules.contains(f1));
445
446 flowRules.clear();
447 mgr.removeFlowRules(f1);
448 assertTrue("flow rule not removed", flowRules.contains(f1));
449 }
450
451 @Test
452 public void fallbackFlowRemoved() {
453 FlowRule f1 = flowRule(FOO_DID, 1, 1);
454 mgr.applyFlowRules(f1);
455 flowRules.clear();
456 providerService.flowRemoved(new DefaultFlowEntry(f1));
457 assertTrue("flow rule not reapplied", flowRules.contains(f1));
458 }
459
460 @Test
461 public void fallbackExtraFlow() {
462 FlowRule f1 = flowRule(FOO_DID, 1, 1);
463 flowRules.clear();
464 providerService.pushFlowMetrics(FOO_DID, ImmutableList.of(new DefaultFlowEntry(f1)));
465 assertTrue("flow rule not removed", flowRules.contains(f1));
466 }
467
468 @Test
469 public void fallbackPoll() {
470 FlowRuleDriverProvider fallback = (FlowRuleDriverProvider) mgr.defaultProvider();
471 FlowRule f1 = flowRule(FOO_DID, 1, 1);
472 mgr.applyFlowRules(f1);
473 FlowEntry fe = mgr.getFlowEntries(FOO_DID).iterator().next();
474 assertEquals("incorrect state", FlowEntryState.PENDING_ADD, fe.state());
475
476 fallback.init(fallback.providerService, mgr.deviceService, mgr.mastershipService, 1);
477 TestTools.assertAfter(2000, () -> {
478 FlowEntry e = mgr.getFlowEntries(FOO_DID).iterator().next();
479 assertEquals("incorrect state", FlowEntryState.ADDED, e.state());
480 });
481 }
482
483
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700484 private static class TestListener implements FlowRuleListener {
485 final List<FlowRuleEvent> events = new ArrayList<>();
486
487 @Override
488 public void event(FlowRuleEvent event) {
489 events.add(event);
490 }
491 }
492
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800493 private static class TestDeviceService extends DeviceServiceAdapter {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700494 @Override
495 public int getDeviceCount() {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800496 return 2;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700497 }
498
499 @Override
500 public Iterable<Device> getDevices() {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800501 return ImmutableList.of(DEV, FOO_DEV);
502 }
503
504 @Override
505 public Iterable<Device> getAvailableDevices() {
506 return getDevices();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700507 }
508
509 @Override
510 public Device getDevice(DeviceId deviceId) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800511 return deviceId.equals(FOO_DID) ? FOO_DEV : DEV;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700512 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700513 }
514
515 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
516
517 protected TestProvider(ProviderId id) {
518 super(PID);
519 }
520
521 @Override
522 public void applyFlowRule(FlowRule... flowRules) {
523 }
524
525 @Override
526 public void removeFlowRule(FlowRule... flowRules) {
527 }
528
alshabiba68eb962014-09-24 20:34:13 -0700529 @Override
530 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
531 }
532
alshabib902d41b2014-10-07 16:52:05 -0700533 @Override
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800534 public void executeBatch(FlowRuleBatchOperation batch) {
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800535 // TODO: need to call batchOperationComplete
alshabib902d41b2014-10-07 16:52:05 -0700536 }
537
alshabibcf369912014-10-13 14:16:42 -0700538 private class TestInstallationFuture
Madan Jampani117aaae2014-10-23 10:04:05 -0700539 implements ListenableFuture<CompletedBatchOperation> {
alshabibcf369912014-10-13 14:16:42 -0700540
541 @Override
542 public boolean cancel(boolean mayInterruptIfRunning) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800543 return false;
alshabibcf369912014-10-13 14:16:42 -0700544 }
545
546 @Override
547 public boolean isCancelled() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800548 return false;
alshabibcf369912014-10-13 14:16:42 -0700549 }
550
551 @Override
552 public boolean isDone() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800553 return true;
alshabibcf369912014-10-13 14:16:42 -0700554 }
555
556 @Override
557 public CompletedBatchOperation get()
558 throws InterruptedException, ExecutionException {
Sho SHIMIZU21d00692016-08-15 11:15:28 -0700559 return new CompletedBatchOperation(true, Collections.emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700560 }
561
562 @Override
563 public CompletedBatchOperation get(long timeout, TimeUnit unit)
564 throws InterruptedException,
565 ExecutionException, TimeoutException {
Sho SHIMIZU21d00692016-08-15 11:15:28 -0700566 return new CompletedBatchOperation(true, Collections.emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700567 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700568
569 @Override
570 public void addListener(Runnable task, Executor executor) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800571 if (isDone()) {
572 executor.execute(task);
573 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700574 }
alshabibcf369912014-10-13 14:16:42 -0700575 }
alshabiba68eb962014-09-24 20:34:13 -0700576
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700577 }
578
579 private class TestSelector implements TrafficSelector {
580
581 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700582 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700583
584 public TestSelector(int val) {
585 testval = val;
586 }
587
588 @Override
alshabibba5ac482014-10-02 17:15:20 -0700589 public Set<Criterion> criteria() {
Hyunsun Moon7bfbc1c2016-04-05 16:40:43 -0700590 return Collections.emptySet();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700591 }
592
593 @Override
Jonathan Hart936c49d2014-10-23 16:38:59 -0700594 public Criterion getCriterion(
Brian O'Connorabafb502014-12-02 22:26:20 -0800595 org.onosproject.net.flow.criteria.Criterion.Type type) {
Jonathan Hart936c49d2014-10-23 16:38:59 -0700596 return null;
597 }
598
599 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700600 public int hashCode() {
601 return testval;
602 }
603
604 @Override
605 public boolean equals(Object o) {
606 if (o instanceof TestSelector) {
607 return this.testval == ((TestSelector) o).testval;
608 }
609 return false;
610 }
Jonathan Hart936c49d2014-10-23 16:38:59 -0700611
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700612 }
613
614 private class TestTreatment implements TrafficTreatment {
615
616 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700617 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700618
619 public TestTreatment(int val) {
620 testval = val;
621 }
622
623 @Override
alshabib346b5b32015-03-06 00:42:16 -0800624 public List<Instruction> deferred() {
625 return null;
626 }
627
628 @Override
629 public List<Instruction> immediate() {
630 return null;
631 }
632
633 @Override
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700634 public List<Instruction> allInstructions() {
635 return null;
636 }
637
638 @Override
alshabib346b5b32015-03-06 00:42:16 -0800639 public Instructions.TableTypeTransition tableTransition() {
640 return null;
641 }
642
643 @Override
Jonathan Hart4a0ba562015-03-23 17:23:33 -0700644 public boolean clearedDeferred() {
645 return false;
alshabib346b5b32015-03-06 00:42:16 -0800646 }
647
648 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700649 public int hashCode() {
650 return testval;
651 }
652
653 @Override
654 public boolean equals(Object o) {
655 if (o instanceof TestTreatment) {
656 return this.testval == ((TestTreatment) o).testval;
657 }
658 return false;
659 }
660
Saurav Das86af8f12015-05-25 23:55:33 -0700661 @Override
662 public MetadataInstruction writeMetadata() {
663 return null;
664 }
665
alshabib10c810b2015-08-18 16:59:04 -0700666 @Override
667 public Instructions.MeterInstruction metered() {
668 return null;
669 }
670
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700671 }
672
alshabib92c65ad2014-10-08 21:56:05 -0700673 public class TestApplicationId extends DefaultApplicationId {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800674 public TestApplicationId(int id, String name) {
alshabib92c65ad2014-10-08 21:56:05 -0700675 super(id, name);
676 }
677 }
678
Ray Milkeycc53abd2015-02-19 12:31:33 -0800679 private class TestCoreService extends CoreServiceAdapter {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800680
681 @Override
682 public IdGenerator getIdGenerator(String topic) {
683 return new IdGenerator() {
684 private AtomicLong counter = new AtomicLong(0);
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800685
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800686 @Override
687 public long getNewId() {
688 return counter.getAndIncrement();
689 }
690 };
691 }
692 }
693
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800694 private class TestMastershipService extends MastershipServiceAdapter {
695 @Override
696 public MastershipRole getLocalRole(DeviceId deviceId) {
697 return MastershipRole.MASTER;
698 }
699 }
700
701 private class TestDriverManager extends DriverManager {
Thomas Vachuska11b99fc2017-04-27 12:51:04 -0700702 TestDriverManager(DriverRegistry registry) {
703 this.registry = registry;
Thomas Vachuskac4ee7372016-02-02 16:10:09 -0800704 this.deviceService = mgr.deviceService;
705 activate();
706 }
707 }
708
709 static Collection<FlowRule> flowRules = new HashSet<>();
710
711 public static class TestFlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
712
713 @Override
714 public Collection<FlowEntry> getFlowEntries() {
715 ImmutableList.Builder<FlowEntry> builder = ImmutableList.builder();
716 flowRules.stream().map(DefaultFlowEntry::new).forEach(builder::add);
717 return builder.build();
718 }
719
720 @Override
721 public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
722 flowRules.addAll(rules);
723 return rules;
724 }
725
726 @Override
727 public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) {
728 flowRules.addAll(rules);
729 return rules;
730 }
731 }
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700732}