blob: f67d99241e8dbae5d5975620acd6aae33179d119 [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 */
tombe988312014-09-19 18:38:47 -070016package org.onlab.onos.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;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070026import org.onlab.onos.core.ApplicationId;
27import org.onlab.onos.core.DefaultApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070028import org.onlab.onos.event.impl.TestEventDispatcher;
29import org.onlab.onos.net.DefaultDevice;
30import org.onlab.onos.net.Device;
31import org.onlab.onos.net.Device.Type;
32import org.onlab.onos.net.DeviceId;
33import org.onlab.onos.net.MastershipRole;
34import org.onlab.onos.net.Port;
35import org.onlab.onos.net.PortNumber;
36import org.onlab.onos.net.device.DeviceListener;
37import org.onlab.onos.net.device.DeviceService;
Jonathan Hart936c49d2014-10-23 16:38:59 -070038import org.onlab.onos.net.flow.BatchOperation;
alshabib193525b2014-10-08 18:58:03 -070039import org.onlab.onos.net.flow.CompletedBatchOperation;
alshabib1c319ff2014-10-04 20:29:09 -070040import org.onlab.onos.net.flow.DefaultFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070041import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib1c319ff2014-10-04 20:29:09 -070042import org.onlab.onos.net.flow.FlowEntry;
43import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070044import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070045import org.onlab.onos.net.flow.FlowRuleBatchEntry;
alshabibcf369912014-10-13 14:16:42 -070046import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070047import org.onlab.onos.net.flow.FlowRuleEvent;
48import org.onlab.onos.net.flow.FlowRuleListener;
49import org.onlab.onos.net.flow.FlowRuleProvider;
50import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
51import org.onlab.onos.net.flow.FlowRuleProviderService;
52import org.onlab.onos.net.flow.FlowRuleService;
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -070053import org.onlab.onos.net.flow.StoredFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070054import org.onlab.onos.net.flow.TrafficSelector;
55import org.onlab.onos.net.flow.TrafficTreatment;
56import org.onlab.onos.net.flow.criteria.Criterion;
57import org.onlab.onos.net.flow.instructions.Instruction;
58import org.onlab.onos.net.provider.AbstractProvider;
59import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070060import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070061
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070062import java.util.ArrayList;
63import java.util.Arrays;
64import java.util.Collections;
65import java.util.HashMap;
66import java.util.List;
67import java.util.Map;
68import java.util.Set;
69import java.util.concurrent.ExecutionException;
70import java.util.concurrent.Executor;
71import java.util.concurrent.Future;
72import java.util.concurrent.TimeUnit;
73import java.util.concurrent.TimeoutException;
74
75import static org.junit.Assert.*;
76import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070077
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070078/**
79 * Test codifying the flow rule service & flow rule provider service contracts.
80 */
tom202175a2014-09-19 19:00:11 -070081public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070082
alshabib92c65ad2014-10-08 21:56:05 -070083
tomf6ab2152014-09-18 12:08:29 -070084 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070085 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070086 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070087 private static final Device DEV = new DefaultDevice(
alshabib7911a052014-10-16 17:49:37 -070088 PID, DID, Type.SWITCH, "", "", "", "", null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070089
tom202175a2014-09-19 19:00:11 -070090 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070091
92 protected FlowRuleService service;
93 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -070094 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070095 protected TestProvider provider;
96 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -070097 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070098
99 @Before
100 public void setUp() {
tom202175a2014-09-19 19:00:11 -0700101 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -0700102 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700103 mgr.eventDispatcher = new TestEventDispatcher();
104 mgr.deviceService = new TestDeviceService();
105 service = mgr;
106 registry = mgr;
107
108 mgr.activate();
109 mgr.addListener(listener);
110 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -0700111 providerService = registry.register(provider);
alshabib92c65ad2014-10-08 21:56:05 -0700112 appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700113 assertTrue("provider should be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700114 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700115 }
116
117 @After
118 public void tearDown() {
119 registry.unregister(provider);
120 assertFalse("provider should not be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700121 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700122 service.removeListener(listener);
123 mgr.deactivate();
124 mgr.eventDispatcher = null;
125 mgr.deviceService = null;
126 }
127
128 private FlowRule flowRule(int tsval, int trval) {
129 TestSelector ts = new TestSelector(tsval);
130 TestTreatment tr = new TestTreatment(trval);
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700131 return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT, false);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700132 }
133
alshabibbb8b1282014-09-22 17:00:18 -0700134
135 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700136 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700137 service.applyFlowRules(rule);
138
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700139 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700140 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700141 }
142
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700143 private void validateEvents(FlowRuleEvent.Type... events) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700144 if (events == null) {
145 assertTrue("events generated", listener.events.isEmpty());
146 }
147
148 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700149 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700150 for (FlowRuleEvent e : listener.events) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800151 assertEquals("unexpected event", events[i], e.type());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700152 i++;
153 }
154
155 assertEquals("mispredicted number of events",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700156 events.length, listener.events.size());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700157
158 listener.events.clear();
159 }
160
161 private int flowCount() {
162 return Sets.newHashSet(service.getFlowEntries(DID)).size();
163 }
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700164
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700165 @Test
166 public void getFlowEntries() {
167 assertTrue("store should be empty",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700168 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700169 FlowRule f1 = addFlowRule(1);
170 FlowRule f2 = addFlowRule(2);
171
alshabib1c319ff2014-10-04 20:29:09 -0700172 FlowEntry fe1 = new DefaultFlowEntry(f1);
173 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700174 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700175
alshabib1c319ff2014-10-04 20:29:09 -0700176 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700177 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
178 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700179
180 addFlowRule(1);
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800181 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700182 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700183
alshabib1c319ff2014-10-04 20:29:09 -0700184 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700185 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700186 }
187
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700188 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
189 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700190 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700191 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700192 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
193 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
194 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700195 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700196 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700197 return true;
198 }
199
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700200 @Test
201 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700202
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700203 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700204 FlowRule r2 = flowRule(2, 2);
205 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700206
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700207 assertTrue("store should be empty",
alshabibcf369912014-10-13 14:16:42 -0700208 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700209 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700210 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700211 assertTrue("Entries should be pending add.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700212 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700213 r1, FlowEntryState.PENDING_ADD,
214 r2, FlowEntryState.PENDING_ADD,
215 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700216 }
217
218 @Test
219 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700220 FlowRule f1 = addFlowRule(1);
221 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700222 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700223 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700224
alshabib1c319ff2014-10-04 20:29:09 -0700225 FlowEntry fe1 = new DefaultFlowEntry(f1);
226 FlowEntry fe2 = new DefaultFlowEntry(f2);
227 FlowEntry fe3 = new DefaultFlowEntry(f3);
228 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700229 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
230 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700231
alshabib1c319ff2014-10-04 20:29:09 -0700232 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700233 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700234 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700235 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700236 assertTrue("Entries should be pending remove.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700237 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700238 f1, FlowEntryState.PENDING_REMOVE,
239 f2, FlowEntryState.PENDING_REMOVE,
240 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700241
alshabib1c319ff2014-10-04 20:29:09 -0700242 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700243 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700244 }
245
246 @Test
247 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700248 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700249 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700250 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700251 FlowEntry fe2 = new DefaultFlowEntry(f2);
252 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700253 service.removeFlowRules(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700254 fe1.setState(FlowEntryState.REMOVED);
255 providerService.flowRemoved(fe1);
alshabib3d643ec2014-10-22 18:33:00 -0700256 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
257 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700258
alshabib1c319ff2014-10-04 20:29:09 -0700259 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700260 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700261
alshabibba5ac482014-10-02 17:15:20 -0700262 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700263 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700264 service.applyFlowRules(f3);
alshabib1c319ff2014-10-04 20:29:09 -0700265 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700266 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700267
alshabib1c319ff2014-10-04 20:29:09 -0700268 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700269 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700270 }
271
alshabibbb8b1282014-09-22 17:00:18 -0700272 @Test
273 public void flowMetrics() {
274 FlowRule f1 = flowRule(1, 1);
275 FlowRule f2 = flowRule(2, 2);
276 FlowRule f3 = flowRule(3, 3);
277
alshabibba5ac482014-10-02 17:15:20 -0700278 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700279
alshabib1c319ff2014-10-04 20:29:09 -0700280 FlowEntry fe1 = new DefaultFlowEntry(f1);
281 FlowEntry fe2 = new DefaultFlowEntry(f2);
282
283
284 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
285 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
286
287 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700288
289 assertTrue("Entries should be added.",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700290 validateState(ImmutableMap.of(
291 f1, FlowEntryState.ADDED,
292 f2, FlowEntryState.ADDED,
293 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700294
alshabib3d643ec2014-10-22 18:33:00 -0700295 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
296 RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700297 }
298
299 @Test
300 public void extraneousFlow() {
301 FlowRule f1 = flowRule(1, 1);
302 FlowRule f2 = flowRule(2, 2);
303 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700304 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700305
alshabib1c319ff2014-10-04 20:29:09 -0700306// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
307// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
308// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
309 FlowEntry fe1 = new DefaultFlowEntry(f1);
310 FlowEntry fe2 = new DefaultFlowEntry(f2);
311 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700312
alshabib1c319ff2014-10-04 20:29:09 -0700313
314 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700315
alshabib3d643ec2014-10-22 18:33:00 -0700316 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700317
318 }
319
320 /*
321 * Tests whether a rule that was marked for removal but no flowRemoved was received
322 * is indeed removed at the next stats update.
323 */
324 @Test
325 public void flowMissingRemove() {
326 FlowRule f1 = flowRule(1, 1);
327 FlowRule f2 = flowRule(2, 2);
328 FlowRule f3 = flowRule(3, 3);
329
alshabib1c319ff2014-10-04 20:29:09 -0700330// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
331// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
332
333 FlowEntry fe1 = new DefaultFlowEntry(f1);
334 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700335 mgr.applyFlowRules(f1, f2, f3);
336
337 mgr.removeFlowRules(f3);
338
alshabib1c319ff2014-10-04 20:29:09 -0700339 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700340
alshabib3d643ec2014-10-22 18:33:00 -0700341 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
342 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700343
344 }
345
346 @Test
347 public void getByAppId() {
348 FlowRule f1 = flowRule(1, 1);
349 FlowRule f2 = flowRule(2, 2);
350 mgr.applyFlowRules(f1, f2);
351
352 assertTrue("should have two rules",
alshabibcf369912014-10-13 14:16:42 -0700353 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700354 }
355
356 @Test
357 public void removeByAppId() {
358 FlowRule f1 = flowRule(1, 1);
359 FlowRule f2 = flowRule(2, 2);
360 mgr.applyFlowRules(f1, f2);
361
362
363 mgr.removeFlowRulesById(appId);
364
365 //only check that we are in pending remove. Events and actual remove state will
366 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700367 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700368 f1, FlowEntryState.PENDING_REMOVE,
369 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700370 }
371
alshabibcf369912014-10-13 14:16:42 -0700372 @Test
373 public void applyBatch() {
374 FlowRule f1 = flowRule(1, 1);
375 FlowRule f2 = flowRule(2, 2);
376
377
378 mgr.applyFlowRules(f1);
379
380 FlowEntry fe1 = new DefaultFlowEntry(f1);
381 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
382
383 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
384 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
385
386 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
387 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
388
389 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
390 Lists.newArrayList(fbe1, fbe2));
391 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
392 assertTrue("Entries in wrong state",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700393 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700394 f1, FlowEntryState.PENDING_REMOVE,
395 f2, FlowEntryState.PENDING_ADD)));
alshabibcf369912014-10-13 14:16:42 -0700396 CompletedBatchOperation completed = null;
397 try {
398 completed = future.get();
399 } catch (InterruptedException | ExecutionException e) {
400 fail("Unexpected exception: " + e);
401 }
402 if (!completed.isSuccess()) {
403 fail("Installation should be a success");
404 }
405
406 }
407
408 @Test
409 public void cancelBatch() {
410 FlowRule f1 = flowRule(1, 1);
411 FlowRule f2 = flowRule(2, 2);
412
413
414 mgr.applyFlowRules(f1);
415
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700416 assertTrue("Entries in wrong state",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700417 validateState(ImmutableMap.of(
418 f1, FlowEntryState.PENDING_ADD)));
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700419
alshabibcf369912014-10-13 14:16:42 -0700420 FlowEntry fe1 = new DefaultFlowEntry(f1);
421 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
422
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700423 assertTrue("Entries in wrong state",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700424 validateState(ImmutableMap.of(
425 f1, FlowEntryState.ADDED)));
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700426
427
alshabibcf369912014-10-13 14:16:42 -0700428 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
429 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
430
431 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
432 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
433
434 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
435 Lists.newArrayList(fbe1, fbe2));
436 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
437
438 future.cancel(true);
439
440 assertTrue(flowCount() == 2);
441
442 /*
443 * Rule f1 should be re-added to the list and therefore be in a pending add
444 * state.
445 */
446 assertTrue("Entries in wrong state",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700447 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700448 f2, FlowEntryState.PENDING_REMOVE,
449 f1, FlowEntryState.PENDING_ADD)));
alshabibcf369912014-10-13 14:16:42 -0700450
451
alshabibcf369912014-10-13 14:16:42 -0700452 }
453
454
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700455 private static class TestListener implements FlowRuleListener {
456 final List<FlowRuleEvent> events = new ArrayList<>();
457
458 @Override
459 public void event(FlowRuleEvent event) {
460 events.add(event);
461 }
462 }
463
464 private static class TestDeviceService implements DeviceService {
465
466 @Override
467 public int getDeviceCount() {
Madan Jampani6a456162014-10-24 11:36:17 -0700468 return 1;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700469 }
470
471 @Override
472 public Iterable<Device> getDevices() {
Madan Jampani6a456162014-10-24 11:36:17 -0700473 return Arrays.asList(DEV);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700474 }
475
476 @Override
477 public Device getDevice(DeviceId deviceId) {
478 return DEV;
479 }
480
481 @Override
482 public MastershipRole getRole(DeviceId deviceId) {
483 return null;
484 }
485
486 @Override
487 public List<Port> getPorts(DeviceId deviceId) {
488 return null;
489 }
490
491 @Override
492 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
493 return null;
494 }
495
496 @Override
497 public boolean isAvailable(DeviceId deviceId) {
498 return false;
499 }
500
501 @Override
502 public void addListener(DeviceListener listener) {
503 }
504
505 @Override
506 public void removeListener(DeviceListener listener) {
507 }
508
509 }
510
511 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
512
513 protected TestProvider(ProviderId id) {
514 super(PID);
515 }
516
517 @Override
518 public void applyFlowRule(FlowRule... flowRules) {
519 }
520
521 @Override
522 public void removeFlowRule(FlowRule... flowRules) {
523 }
524
alshabiba68eb962014-09-24 20:34:13 -0700525 @Override
526 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
527 }
528
alshabib902d41b2014-10-07 16:52:05 -0700529 @Override
Madan Jampani117aaae2014-10-23 10:04:05 -0700530 public ListenableFuture<CompletedBatchOperation> executeBatch(
alshabib902d41b2014-10-07 16:52:05 -0700531 BatchOperation<FlowRuleBatchEntry> batch) {
alshabibcf369912014-10-13 14:16:42 -0700532 return new TestInstallationFuture();
alshabib902d41b2014-10-07 16:52:05 -0700533 }
534
alshabibcf369912014-10-13 14:16:42 -0700535 private class TestInstallationFuture
Madan Jampani117aaae2014-10-23 10:04:05 -0700536 implements ListenableFuture<CompletedBatchOperation> {
alshabibcf369912014-10-13 14:16:42 -0700537
538 @Override
539 public boolean cancel(boolean mayInterruptIfRunning) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800540 return false;
alshabibcf369912014-10-13 14:16:42 -0700541 }
542
543 @Override
544 public boolean isCancelled() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800545 return false;
alshabibcf369912014-10-13 14:16:42 -0700546 }
547
548 @Override
549 public boolean isDone() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800550 return true;
alshabibcf369912014-10-13 14:16:42 -0700551 }
552
553 @Override
554 public CompletedBatchOperation get()
555 throws InterruptedException, ExecutionException {
Yuta HIGUCHI4b524442014-10-28 22:23:57 -0700556 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet());
alshabibcf369912014-10-13 14:16:42 -0700557 }
558
559 @Override
560 public CompletedBatchOperation get(long timeout, TimeUnit unit)
561 throws InterruptedException,
562 ExecutionException, TimeoutException {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800563 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet());
alshabibcf369912014-10-13 14:16:42 -0700564 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700565
566 @Override
567 public void addListener(Runnable task, Executor executor) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800568 if (isDone()) {
569 executor.execute(task);
570 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700571 }
alshabibcf369912014-10-13 14:16:42 -0700572 }
alshabiba68eb962014-09-24 20:34:13 -0700573
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700574 }
575
576 private class TestSelector implements TrafficSelector {
577
578 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700579 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700580
581 public TestSelector(int val) {
582 testval = val;
583 }
584
585 @Override
alshabibba5ac482014-10-02 17:15:20 -0700586 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700587 return null;
588 }
589
590 @Override
Jonathan Hart936c49d2014-10-23 16:38:59 -0700591 public Criterion getCriterion(
592 org.onlab.onos.net.flow.criteria.Criterion.Type type) {
593 return null;
594 }
595
596 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700597 public int hashCode() {
598 return testval;
599 }
600
601 @Override
602 public boolean equals(Object o) {
603 if (o instanceof TestSelector) {
604 return this.testval == ((TestSelector) o).testval;
605 }
606 return false;
607 }
Jonathan Hart936c49d2014-10-23 16:38:59 -0700608
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700609 }
610
611 private class TestTreatment implements TrafficTreatment {
612
613 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700614 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700615
616 public TestTreatment(int val) {
617 testval = val;
618 }
619
620 @Override
621 public List<Instruction> instructions() {
622 return null;
623 }
624
625 @Override
626 public int hashCode() {
627 return testval;
628 }
629
630 @Override
631 public boolean equals(Object o) {
632 if (o instanceof TestTreatment) {
633 return this.testval == ((TestTreatment) o).testval;
634 }
635 return false;
636 }
637
638 }
639
alshabib92c65ad2014-10-08 21:56:05 -0700640 public class TestApplicationId extends DefaultApplicationId {
641
642 public TestApplicationId(short id, String name) {
643 super(id, name);
644 }
645 }
646
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700647}