blob: 3fd8b5a2e0382b0b224a89e8a8cef7865e9979d7 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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
Thomas Vachuskae0f804a2014-10-27 23:40:48 -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;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080023import 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;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.core.ApplicationId;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080028import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.core.DefaultApplicationId;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080030import org.onosproject.core.IdGenerator;
31import org.onosproject.core.Version;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.event.impl.TestEventDispatcher;
33import org.onosproject.net.DefaultDevice;
34import org.onosproject.net.Device;
35import org.onosproject.net.Device.Type;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.MastershipRole;
38import org.onosproject.net.Port;
39import org.onosproject.net.PortNumber;
40import org.onosproject.net.device.DeviceListener;
41import org.onosproject.net.device.DeviceServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.flow.CompletedBatchOperation;
43import org.onosproject.net.flow.DefaultFlowEntry;
44import org.onosproject.net.flow.DefaultFlowRule;
45import org.onosproject.net.flow.FlowEntry;
46import org.onosproject.net.flow.FlowEntry.FlowEntryState;
47import org.onosproject.net.flow.FlowRule;
48import org.onosproject.net.flow.FlowRuleBatchEntry;
49import org.onosproject.net.flow.FlowRuleBatchOperation;
50import org.onosproject.net.flow.FlowRuleEvent;
51import org.onosproject.net.flow.FlowRuleListener;
52import org.onosproject.net.flow.FlowRuleProvider;
53import org.onosproject.net.flow.FlowRuleProviderRegistry;
54import org.onosproject.net.flow.FlowRuleProviderService;
55import org.onosproject.net.flow.FlowRuleService;
56import org.onosproject.net.flow.StoredFlowEntry;
57import org.onosproject.net.flow.TrafficSelector;
58import org.onosproject.net.flow.TrafficTreatment;
59import org.onosproject.net.flow.criteria.Criterion;
60import org.onosproject.net.flow.instructions.Instruction;
61import org.onosproject.net.provider.AbstractProvider;
62import org.onosproject.net.provider.ProviderId;
63import org.onosproject.store.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070064
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070065import java.util.ArrayList;
66import java.util.Arrays;
67import java.util.Collections;
68import java.util.HashMap;
69import java.util.List;
70import java.util.Map;
71import java.util.Set;
72import java.util.concurrent.ExecutionException;
73import java.util.concurrent.Executor;
74import java.util.concurrent.Future;
75import java.util.concurrent.TimeUnit;
76import java.util.concurrent.TimeoutException;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080077import java.util.concurrent.atomic.AtomicLong;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070078
79import static org.junit.Assert.*;
Brian O'Connorabafb502014-12-02 22:26:20 -080080import static org.onosproject.net.flow.FlowRuleEvent.Type.*;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070081
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070082/**
83 * Test codifying the flow rule service & flow rule provider service contracts.
84 */
tom202175a2014-09-19 19:00:11 -070085public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070086
alshabib92c65ad2014-10-08 21:56:05 -070087
tomf6ab2152014-09-18 12:08:29 -070088 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070089 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070090 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070091 private static final Device DEV = new DefaultDevice(
alshabib7911a052014-10-16 17:49:37 -070092 PID, DID, Type.SWITCH, "", "", "", "", null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070093
tom202175a2014-09-19 19:00:11 -070094 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070095
96 protected FlowRuleService service;
97 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -070098 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070099 protected TestProvider provider;
100 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -0700101 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700102
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800103
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700104 @Before
105 public void setUp() {
tom202175a2014-09-19 19:00:11 -0700106 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -0700107 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700108 mgr.eventDispatcher = new TestEventDispatcher();
109 mgr.deviceService = new TestDeviceService();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800110 mgr.coreService = new TestCoreService();
111 mgr.operationsService = MoreExecutors.newDirectExecutorService();
112 mgr.deviceInstallers = MoreExecutors.newDirectExecutorService();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700113 service = mgr;
114 registry = mgr;
115
116 mgr.activate();
117 mgr.addListener(listener);
118 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -0700119 providerService = registry.register(provider);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800120 appId = new TestApplicationId(0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700121 assertTrue("provider should be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700122 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700123 }
124
125 @After
126 public void tearDown() {
127 registry.unregister(provider);
128 assertFalse("provider should not be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700129 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700130 service.removeListener(listener);
131 mgr.deactivate();
132 mgr.eventDispatcher = null;
133 mgr.deviceService = null;
134 }
135
136 private FlowRule flowRule(int tsval, int trval) {
137 TestSelector ts = new TestSelector(tsval);
138 TestTreatment tr = new TestTreatment(trval);
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700139 return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT, false);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700140 }
141
alshabibbb8b1282014-09-22 17:00:18 -0700142
143 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700144 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700145 service.applyFlowRules(rule);
146
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700147 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700148 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700149 }
150
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700151 private void validateEvents(FlowRuleEvent.Type... events) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700152 if (events == null) {
153 assertTrue("events generated", listener.events.isEmpty());
154 }
155
156 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700157 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700158 for (FlowRuleEvent e : listener.events) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800159 assertEquals("unexpected event", events[i], e.type());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700160 i++;
161 }
162
163 assertEquals("mispredicted number of events",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700164 events.length, listener.events.size());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700165
166 listener.events.clear();
167 }
168
169 private int flowCount() {
170 return Sets.newHashSet(service.getFlowEntries(DID)).size();
171 }
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700172
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700173 @Test
174 public void getFlowEntries() {
175 assertTrue("store should be empty",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700176 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700177 FlowRule f1 = addFlowRule(1);
178 FlowRule f2 = addFlowRule(2);
179
alshabib1c319ff2014-10-04 20:29:09 -0700180 FlowEntry fe1 = new DefaultFlowEntry(f1);
181 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700182 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700183
alshabib1c319ff2014-10-04 20:29:09 -0700184 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700185 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
186 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700187
188 addFlowRule(1);
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800189 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700190 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700191
alshabib1c319ff2014-10-04 20:29:09 -0700192 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700193 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700194 }
195
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700196 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
197 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700198 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700199 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700200 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
201 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
202 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700203 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700204 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700205 return true;
206 }
207
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700208 @Test
209 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700210
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700211 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700212 FlowRule r2 = flowRule(2, 2);
213 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700214
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700215 assertTrue("store should be empty",
alshabibcf369912014-10-13 14:16:42 -0700216 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700217 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700218 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700219 assertTrue("Entries should be pending add.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700220 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700221 r1, FlowEntryState.PENDING_ADD,
222 r2, FlowEntryState.PENDING_ADD,
223 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700224 }
225
226 @Test
227 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700228 FlowRule f1 = addFlowRule(1);
229 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700230 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700231 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700232
alshabib1c319ff2014-10-04 20:29:09 -0700233 FlowEntry fe1 = new DefaultFlowEntry(f1);
234 FlowEntry fe2 = new DefaultFlowEntry(f2);
235 FlowEntry fe3 = new DefaultFlowEntry(f3);
236 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700237 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
238 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700239
alshabib1c319ff2014-10-04 20:29:09 -0700240 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700241 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700242 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700243 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700244 assertTrue("Entries should be pending remove.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700245 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700246 f1, FlowEntryState.PENDING_REMOVE,
247 f2, FlowEntryState.PENDING_REMOVE,
248 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700249
alshabib1c319ff2014-10-04 20:29:09 -0700250 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700251 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700252 }
253
254 @Test
255 public void flowRemoved() {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800256
alshabibbb8b1282014-09-22 17:00:18 -0700257 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700258 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700259 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700260 FlowEntry fe2 = new DefaultFlowEntry(f2);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800261
262
alshabib1c319ff2014-10-04 20:29:09 -0700263 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700264 service.removeFlowRules(f1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800265
alshabib1c319ff2014-10-04 20:29:09 -0700266 fe1.setState(FlowEntryState.REMOVED);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800267
268
269
alshabib1c319ff2014-10-04 20:29:09 -0700270 providerService.flowRemoved(fe1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800271
272
alshabib3d643ec2014-10-22 18:33:00 -0700273 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
274 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700275
alshabib1c319ff2014-10-04 20:29:09 -0700276 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700277 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700278
alshabibba5ac482014-10-02 17:15:20 -0700279 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700280 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700281 service.applyFlowRules(f3);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800282
alshabib1c319ff2014-10-04 20:29:09 -0700283 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700284 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700285
alshabib1c319ff2014-10-04 20:29:09 -0700286 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700287 validateEvents();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800288
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700289 }
290
alshabibbb8b1282014-09-22 17:00:18 -0700291 @Test
292 public void flowMetrics() {
293 FlowRule f1 = flowRule(1, 1);
294 FlowRule f2 = flowRule(2, 2);
295 FlowRule f3 = flowRule(3, 3);
296
alshabibba5ac482014-10-02 17:15:20 -0700297 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700298
alshabib1c319ff2014-10-04 20:29:09 -0700299 FlowEntry fe1 = new DefaultFlowEntry(f1);
300 FlowEntry fe2 = new DefaultFlowEntry(f2);
301
alshabib1c319ff2014-10-04 20:29:09 -0700302 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
303 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
304
305 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700306
307 assertTrue("Entries should be added.",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700308 validateState(ImmutableMap.of(
309 f1, FlowEntryState.ADDED,
310 f2, FlowEntryState.ADDED,
311 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700312
alshabib3d643ec2014-10-22 18:33:00 -0700313 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
314 RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700315 }
316
317 @Test
318 public void extraneousFlow() {
319 FlowRule f1 = flowRule(1, 1);
320 FlowRule f2 = flowRule(2, 2);
321 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700322 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700323
alshabib1c319ff2014-10-04 20:29:09 -0700324// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
325// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
326// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
327 FlowEntry fe1 = new DefaultFlowEntry(f1);
328 FlowEntry fe2 = new DefaultFlowEntry(f2);
329 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700330
alshabib1c319ff2014-10-04 20:29:09 -0700331
332 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700333
alshabib3d643ec2014-10-22 18:33:00 -0700334 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700335
336 }
337
338 /*
339 * Tests whether a rule that was marked for removal but no flowRemoved was received
340 * is indeed removed at the next stats update.
341 */
342 @Test
343 public void flowMissingRemove() {
344 FlowRule f1 = flowRule(1, 1);
345 FlowRule f2 = flowRule(2, 2);
346 FlowRule f3 = flowRule(3, 3);
347
alshabib1c319ff2014-10-04 20:29:09 -0700348// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
349// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
350
351 FlowEntry fe1 = new DefaultFlowEntry(f1);
352 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700353 mgr.applyFlowRules(f1, f2, f3);
354
355 mgr.removeFlowRules(f3);
356
alshabib1c319ff2014-10-04 20:29:09 -0700357 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700358
alshabib3d643ec2014-10-22 18:33:00 -0700359 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
360 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700361
362 }
363
364 @Test
365 public void getByAppId() {
366 FlowRule f1 = flowRule(1, 1);
367 FlowRule f2 = flowRule(2, 2);
368 mgr.applyFlowRules(f1, f2);
369
370 assertTrue("should have two rules",
alshabibcf369912014-10-13 14:16:42 -0700371 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700372 }
373
374 @Test
375 public void removeByAppId() {
376 FlowRule f1 = flowRule(1, 1);
377 FlowRule f2 = flowRule(2, 2);
378 mgr.applyFlowRules(f1, f2);
379
380
381 mgr.removeFlowRulesById(appId);
382
383 //only check that we are in pending remove. Events and actual remove state will
384 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700385 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700386 f1, FlowEntryState.PENDING_REMOVE,
387 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700388 }
389
alshabibcf369912014-10-13 14:16:42 -0700390 @Test
391 public void applyBatch() {
392 FlowRule f1 = flowRule(1, 1);
393 FlowRule f2 = flowRule(2, 2);
394
395
396 mgr.applyFlowRules(f1);
397
398 FlowEntry fe1 = new DefaultFlowEntry(f1);
399 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
400
401 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
402 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
403
404 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
405 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
406
407 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800408 Lists.newArrayList(fbe1, fbe2), null, 0);
alshabibcf369912014-10-13 14:16:42 -0700409 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
410 assertTrue("Entries in wrong state",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700411 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700412 f1, FlowEntryState.PENDING_REMOVE,
413 f2, FlowEntryState.PENDING_ADD)));
alshabibcf369912014-10-13 14:16:42 -0700414 CompletedBatchOperation completed = null;
415 try {
416 completed = future.get();
417 } catch (InterruptedException | ExecutionException e) {
418 fail("Unexpected exception: " + e);
419 }
420 if (!completed.isSuccess()) {
421 fail("Installation should be a success");
422 }
423
424 }
425
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700426 private static class TestListener implements FlowRuleListener {
427 final List<FlowRuleEvent> events = new ArrayList<>();
428
429 @Override
430 public void event(FlowRuleEvent event) {
431 events.add(event);
432 }
433 }
434
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800435 private static class TestDeviceService extends DeviceServiceAdapter {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700436
437 @Override
438 public int getDeviceCount() {
Madan Jampani6a456162014-10-24 11:36:17 -0700439 return 1;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700440 }
441
442 @Override
443 public Iterable<Device> getDevices() {
Madan Jampani6a456162014-10-24 11:36:17 -0700444 return Arrays.asList(DEV);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700445 }
446
447 @Override
448 public Device getDevice(DeviceId deviceId) {
449 return DEV;
450 }
451
452 @Override
453 public MastershipRole getRole(DeviceId deviceId) {
454 return null;
455 }
456
457 @Override
458 public List<Port> getPorts(DeviceId deviceId) {
459 return null;
460 }
461
462 @Override
463 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
464 return null;
465 }
466
467 @Override
468 public boolean isAvailable(DeviceId deviceId) {
469 return false;
470 }
471
472 @Override
473 public void addListener(DeviceListener listener) {
474 }
475
476 @Override
477 public void removeListener(DeviceListener listener) {
478 }
479
480 }
481
482 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
483
484 protected TestProvider(ProviderId id) {
485 super(PID);
486 }
487
488 @Override
489 public void applyFlowRule(FlowRule... flowRules) {
490 }
491
492 @Override
493 public void removeFlowRule(FlowRule... flowRules) {
494 }
495
alshabiba68eb962014-09-24 20:34:13 -0700496 @Override
497 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
498 }
499
alshabib902d41b2014-10-07 16:52:05 -0700500 @Override
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800501 public void executeBatch(FlowRuleBatchOperation batch) {
502 // TODO: need to call batchOperationComplete
alshabib902d41b2014-10-07 16:52:05 -0700503 }
504
alshabibcf369912014-10-13 14:16:42 -0700505 private class TestInstallationFuture
Madan Jampani117aaae2014-10-23 10:04:05 -0700506 implements ListenableFuture<CompletedBatchOperation> {
alshabibcf369912014-10-13 14:16:42 -0700507
508 @Override
509 public boolean cancel(boolean mayInterruptIfRunning) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800510 return false;
alshabibcf369912014-10-13 14:16:42 -0700511 }
512
513 @Override
514 public boolean isCancelled() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800515 return false;
alshabibcf369912014-10-13 14:16:42 -0700516 }
517
518 @Override
519 public boolean isDone() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800520 return true;
alshabibcf369912014-10-13 14:16:42 -0700521 }
522
523 @Override
524 public CompletedBatchOperation get()
525 throws InterruptedException, ExecutionException {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800526 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700527 }
528
529 @Override
530 public CompletedBatchOperation get(long timeout, TimeUnit unit)
531 throws InterruptedException,
532 ExecutionException, TimeoutException {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800533 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700534 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700535
536 @Override
537 public void addListener(Runnable task, Executor executor) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800538 if (isDone()) {
539 executor.execute(task);
540 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700541 }
alshabibcf369912014-10-13 14:16:42 -0700542 }
alshabiba68eb962014-09-24 20:34:13 -0700543
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700544 }
545
546 private class TestSelector implements TrafficSelector {
547
548 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700549 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700550
551 public TestSelector(int val) {
552 testval = val;
553 }
554
555 @Override
alshabibba5ac482014-10-02 17:15:20 -0700556 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700557 return null;
558 }
559
560 @Override
Jonathan Hart936c49d2014-10-23 16:38:59 -0700561 public Criterion getCriterion(
Brian O'Connorabafb502014-12-02 22:26:20 -0800562 org.onosproject.net.flow.criteria.Criterion.Type type) {
Jonathan Hart936c49d2014-10-23 16:38:59 -0700563 return null;
564 }
565
566 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700567 public int hashCode() {
568 return testval;
569 }
570
571 @Override
572 public boolean equals(Object o) {
573 if (o instanceof TestSelector) {
574 return this.testval == ((TestSelector) o).testval;
575 }
576 return false;
577 }
Jonathan Hart936c49d2014-10-23 16:38:59 -0700578
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700579 }
580
581 private class TestTreatment implements TrafficTreatment {
582
583 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700584 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700585
586 public TestTreatment(int val) {
587 testval = val;
588 }
589
590 @Override
591 public List<Instruction> instructions() {
592 return null;
593 }
594
595 @Override
596 public int hashCode() {
597 return testval;
598 }
599
600 @Override
601 public boolean equals(Object o) {
602 if (o instanceof TestTreatment) {
603 return this.testval == ((TestTreatment) o).testval;
604 }
605 return false;
606 }
607
608 }
609
alshabib92c65ad2014-10-08 21:56:05 -0700610 public class TestApplicationId extends DefaultApplicationId {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800611 public TestApplicationId(int id, String name) {
alshabib92c65ad2014-10-08 21:56:05 -0700612 super(id, name);
613 }
614 }
615
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800616 private class TestCoreService implements CoreService {
617 @Override
618 public Version version() {
619 return null;
620 }
621
622 @Override
623 public Set<ApplicationId> getAppIds() {
624 return null;
625 }
626
627 @Override
628 public ApplicationId getAppId(Short id) {
629 return null;
630 }
631
632 @Override
633 public ApplicationId registerApplication(String identifier) {
634 return null;
635 }
636
637 @Override
638 public IdGenerator getIdGenerator(String topic) {
639 return new IdGenerator() {
640 private AtomicLong counter = new AtomicLong(0);
641 @Override
642 public long getNewId() {
643 return counter.getAndIncrement();
644 }
645 };
646 }
647 }
648
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700649}