blob: a2fbc9a40b5d0cff116298d9feac5d5d529fddee [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.flow.impl;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07002
alshabib44521ec2014-10-22 18:36:02 -07003
4
alshabib3d643ec2014-10-22 18:33:00 -07005import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07006
alshabib44521ec2014-10-22 18:36:02 -07007
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07008import java.util.ArrayList;
alshabibba5ac482014-10-02 17:15:20 -07009import java.util.Collections;
Yuta HIGUCHI605347c2014-10-17 21:05:23 -070010import java.util.HashMap;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070011import java.util.List;
Yuta HIGUCHI605347c2014-10-17 21:05:23 -070012import java.util.Map;
alshabibba5ac482014-10-02 17:15:20 -070013import java.util.Set;
alshabibcf369912014-10-13 14:16:42 -070014import java.util.concurrent.ExecutionException;
alshabib902d41b2014-10-07 16:52:05 -070015import java.util.concurrent.Future;
alshabibcf369912014-10-13 14:16:42 -070016import java.util.concurrent.TimeUnit;
17import java.util.concurrent.TimeoutException;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070018
19import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
alshabiba68eb962014-09-24 20:34:13 -070022import org.onlab.onos.ApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070023import org.onlab.onos.event.impl.TestEventDispatcher;
alshabib92c65ad2014-10-08 21:56:05 -070024import org.onlab.onos.impl.DefaultApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070025import org.onlab.onos.net.DefaultDevice;
26import org.onlab.onos.net.Device;
27import org.onlab.onos.net.Device.Type;
28import org.onlab.onos.net.DeviceId;
29import org.onlab.onos.net.MastershipRole;
30import org.onlab.onos.net.Port;
31import org.onlab.onos.net.PortNumber;
32import org.onlab.onos.net.device.DeviceListener;
33import org.onlab.onos.net.device.DeviceService;
alshabib193525b2014-10-08 18:58:03 -070034import org.onlab.onos.net.flow.CompletedBatchOperation;
alshabib1c319ff2014-10-04 20:29:09 -070035import org.onlab.onos.net.flow.DefaultFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070036import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib1c319ff2014-10-04 20:29:09 -070037import org.onlab.onos.net.flow.FlowEntry;
38import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070039import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070040import org.onlab.onos.net.flow.FlowRuleBatchEntry;
alshabibcf369912014-10-13 14:16:42 -070041import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070042import org.onlab.onos.net.flow.FlowRuleEvent;
43import org.onlab.onos.net.flow.FlowRuleListener;
44import org.onlab.onos.net.flow.FlowRuleProvider;
45import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
46import org.onlab.onos.net.flow.FlowRuleProviderService;
47import org.onlab.onos.net.flow.FlowRuleService;
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -070048import org.onlab.onos.net.flow.StoredFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070049import org.onlab.onos.net.flow.TrafficSelector;
50import org.onlab.onos.net.flow.TrafficTreatment;
51import org.onlab.onos.net.flow.criteria.Criterion;
52import org.onlab.onos.net.flow.instructions.Instruction;
Thomas Vachuska83e090e2014-10-22 14:25:35 -070053import org.onlab.onos.net.flow.BatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070054import org.onlab.onos.net.provider.AbstractProvider;
55import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070056import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070057
alshabibba5ac482014-10-02 17:15:20 -070058import com.google.common.collect.ImmutableList;
Yuta HIGUCHI605347c2014-10-17 21:05:23 -070059import com.google.common.collect.ImmutableMap;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070060import com.google.common.collect.Lists;
61import com.google.common.collect.Sets;
62
Ray Milkey5154ec32014-10-22 10:51:18 -070063import static java.util.Collections.EMPTY_LIST;
64import static org.junit.Assert.assertEquals;
65import static org.junit.Assert.assertFalse;
66import static org.junit.Assert.assertNotNull;
67import static org.junit.Assert.assertTrue;
68import static org.junit.Assert.fail;
69import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
70import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
71import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
72
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070073/**
74 * Test codifying the flow rule service & flow rule provider service contracts.
75 */
tom202175a2014-09-19 19:00:11 -070076public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070077
alshabib92c65ad2014-10-08 21:56:05 -070078
79
tomf6ab2152014-09-18 12:08:29 -070080 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070081 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070082 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070083 private static final Device DEV = new DefaultDevice(
alshabib7911a052014-10-16 17:49:37 -070084 PID, DID, Type.SWITCH, "", "", "", "", null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070085
tom202175a2014-09-19 19:00:11 -070086 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070087
88 protected FlowRuleService service;
89 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -070090 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070091 protected TestProvider provider;
92 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -070093 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070094
95 @Before
96 public void setUp() {
tom202175a2014-09-19 19:00:11 -070097 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -070098 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070099 mgr.eventDispatcher = new TestEventDispatcher();
100 mgr.deviceService = new TestDeviceService();
101 service = mgr;
102 registry = mgr;
103
104 mgr.activate();
105 mgr.addListener(listener);
106 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -0700107 providerService = registry.register(provider);
alshabib92c65ad2014-10-08 21:56:05 -0700108 appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700109 assertTrue("provider should be registered",
110 registry.getProviders().contains(provider.id()));
111 }
112
113 @After
114 public void tearDown() {
115 registry.unregister(provider);
116 assertFalse("provider should not be registered",
alshabib97044902014-09-18 14:52:16 -0700117 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700118 service.removeListener(listener);
119 mgr.deactivate();
120 mgr.eventDispatcher = null;
121 mgr.deviceService = null;
122 }
123
124 private FlowRule flowRule(int tsval, int trval) {
125 TestSelector ts = new TestSelector(tsval);
126 TestTreatment tr = new TestTreatment(trval);
Jonathan Hartbc4a7932014-10-21 11:46:00 -0700127 return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT, false);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700128 }
129
alshabibbb8b1282014-09-22 17:00:18 -0700130
131 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700132 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700133 service.applyFlowRules(rule);
134
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700135 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700136 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700137 }
138
139 private void validateEvents(FlowRuleEvent.Type ... events) {
140 if (events == null) {
141 assertTrue("events generated", listener.events.isEmpty());
142 }
143
144 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700145 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700146 for (FlowRuleEvent e : listener.events) {
147 assertTrue("unexpected event", e.type().equals(events[i]));
148 i++;
149 }
150
151 assertEquals("mispredicted number of events",
152 events.length, listener.events.size());
153
154 listener.events.clear();
155 }
156
157 private int flowCount() {
158 return Sets.newHashSet(service.getFlowEntries(DID)).size();
159 }
160 @Test
161 public void getFlowEntries() {
162 assertTrue("store should be empty",
163 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700164 FlowRule f1 = addFlowRule(1);
165 FlowRule f2 = addFlowRule(2);
166
alshabib1c319ff2014-10-04 20:29:09 -0700167 FlowEntry fe1 = new DefaultFlowEntry(f1);
168 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700169 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700170
alshabib1c319ff2014-10-04 20:29:09 -0700171 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700172 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
173 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700174
175 addFlowRule(1);
176 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700177
alshabib1c319ff2014-10-04 20:29:09 -0700178 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700179 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700180 }
181
alshabibbb8b1282014-09-22 17:00:18 -0700182
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700183 // TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
alshabibbb8b1282014-09-22 17:00:18 -0700184 //backing store is sensitive to the order of additions/removals
Ray Milkey5154ec32014-10-22 10:51:18 -0700185 @SuppressWarnings("unchecked")
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700186 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
187 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700188 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700189 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700190 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
191 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
192 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700193 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700194 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700195 return true;
196 }
197
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700198 @Test
199 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700200
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700201 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700202 FlowRule r2 = flowRule(2, 2);
203 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700204
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700205 assertTrue("store should be empty",
alshabibcf369912014-10-13 14:16:42 -0700206 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700207 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700208 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700209 assertTrue("Entries should be pending add.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700210 validateState(ImmutableMap.of(
211 r1, FlowEntryState.PENDING_ADD,
212 r2, FlowEntryState.PENDING_ADD,
213 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700214 }
215
216 @Test
217 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700218 FlowRule f1 = addFlowRule(1);
219 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700220 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700221 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700222
alshabib1c319ff2014-10-04 20:29:09 -0700223 FlowEntry fe1 = new DefaultFlowEntry(f1);
224 FlowEntry fe2 = new DefaultFlowEntry(f2);
225 FlowEntry fe3 = new DefaultFlowEntry(f3);
226 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700227 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
228 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700229
alshabib1c319ff2014-10-04 20:29:09 -0700230 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700231 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700232 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700233 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700234 assertTrue("Entries should be pending remove.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700235 validateState(ImmutableMap.of(
236 f1, FlowEntryState.PENDING_REMOVE,
237 f2, FlowEntryState.PENDING_REMOVE,
238 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700239
alshabib1c319ff2014-10-04 20:29:09 -0700240 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700241 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700242 }
243
244 @Test
245 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700246 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700247 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700248 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700249 FlowEntry fe2 = new DefaultFlowEntry(f2);
250 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700251 service.removeFlowRules(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700252 fe1.setState(FlowEntryState.REMOVED);
253 providerService.flowRemoved(fe1);
alshabib3d643ec2014-10-22 18:33:00 -0700254 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
255 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700256
alshabib1c319ff2014-10-04 20:29:09 -0700257 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700258 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700259
alshabibba5ac482014-10-02 17:15:20 -0700260 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700261 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700262 service.applyFlowRules(f3);
alshabib1c319ff2014-10-04 20:29:09 -0700263 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700264 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700265
alshabib1c319ff2014-10-04 20:29:09 -0700266 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700267 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700268 }
269
alshabibbb8b1282014-09-22 17:00:18 -0700270 @Test
271 public void flowMetrics() {
272 FlowRule f1 = flowRule(1, 1);
273 FlowRule f2 = flowRule(2, 2);
274 FlowRule f3 = flowRule(3, 3);
275
alshabibba5ac482014-10-02 17:15:20 -0700276 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700277
alshabib1c319ff2014-10-04 20:29:09 -0700278 FlowEntry fe1 = new DefaultFlowEntry(f1);
279 FlowEntry fe2 = new DefaultFlowEntry(f2);
280
281
282 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
283 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
284
285 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700286
287 assertTrue("Entries should be added.",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700288 validateState(ImmutableMap.of(
289 f1, FlowEntryState.ADDED,
290 f2, FlowEntryState.ADDED,
291 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700292
alshabib3d643ec2014-10-22 18:33:00 -0700293 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
294 RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700295 }
296
297 @Test
298 public void extraneousFlow() {
299 FlowRule f1 = flowRule(1, 1);
300 FlowRule f2 = flowRule(2, 2);
301 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700302 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700303
alshabib1c319ff2014-10-04 20:29:09 -0700304// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
305// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
306// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
307 FlowEntry fe1 = new DefaultFlowEntry(f1);
308 FlowEntry fe2 = new DefaultFlowEntry(f2);
309 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700310
alshabib1c319ff2014-10-04 20:29:09 -0700311
312 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700313
alshabib3d643ec2014-10-22 18:33:00 -0700314 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700315
316 }
317
318 /*
319 * Tests whether a rule that was marked for removal but no flowRemoved was received
320 * is indeed removed at the next stats update.
321 */
322 @Test
323 public void flowMissingRemove() {
324 FlowRule f1 = flowRule(1, 1);
325 FlowRule f2 = flowRule(2, 2);
326 FlowRule f3 = flowRule(3, 3);
327
alshabib1c319ff2014-10-04 20:29:09 -0700328// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
329// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
330
331 FlowEntry fe1 = new DefaultFlowEntry(f1);
332 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700333 mgr.applyFlowRules(f1, f2, f3);
334
335 mgr.removeFlowRules(f3);
336
alshabib1c319ff2014-10-04 20:29:09 -0700337 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700338
alshabib3d643ec2014-10-22 18:33:00 -0700339 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
340 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700341
342 }
343
344 @Test
345 public void getByAppId() {
346 FlowRule f1 = flowRule(1, 1);
347 FlowRule f2 = flowRule(2, 2);
348 mgr.applyFlowRules(f1, f2);
349
350 assertTrue("should have two rules",
alshabibcf369912014-10-13 14:16:42 -0700351 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700352 }
353
354 @Test
355 public void removeByAppId() {
356 FlowRule f1 = flowRule(1, 1);
357 FlowRule f2 = flowRule(2, 2);
358 mgr.applyFlowRules(f1, f2);
359
360
361 mgr.removeFlowRulesById(appId);
362
363 //only check that we are in pending remove. Events and actual remove state will
364 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700365 validateState(ImmutableMap.of(
366 f1, FlowEntryState.PENDING_REMOVE,
367 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700368 }
369
alshabibcf369912014-10-13 14:16:42 -0700370 @Test
371 public void applyBatch() {
372 FlowRule f1 = flowRule(1, 1);
373 FlowRule f2 = flowRule(2, 2);
374
375
376 mgr.applyFlowRules(f1);
377
378 FlowEntry fe1 = new DefaultFlowEntry(f1);
379 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
380
381 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
382 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
383
384 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
385 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
386
387 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
388 Lists.newArrayList(fbe1, fbe2));
389 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
390 assertTrue("Entries in wrong state",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700391 validateState(ImmutableMap.of(
392 f1, FlowEntryState.PENDING_REMOVE,
393 f2, FlowEntryState.PENDING_ADD)));
alshabibcf369912014-10-13 14:16:42 -0700394 CompletedBatchOperation completed = null;
395 try {
396 completed = future.get();
397 } catch (InterruptedException | ExecutionException e) {
398 fail("Unexpected exception: " + e);
399 }
400 if (!completed.isSuccess()) {
401 fail("Installation should be a success");
402 }
403
404 }
405
406 @Test
407 public void cancelBatch() {
408 FlowRule f1 = flowRule(1, 1);
409 FlowRule f2 = flowRule(2, 2);
410
411
412 mgr.applyFlowRules(f1);
413
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700414 assertTrue("Entries in wrong state",
415 validateState(ImmutableMap.of(
416 f1, FlowEntryState.PENDING_ADD)));
417
alshabibcf369912014-10-13 14:16:42 -0700418 FlowEntry fe1 = new DefaultFlowEntry(f1);
419 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
420
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700421 assertTrue("Entries in wrong state",
422 validateState(ImmutableMap.of(
423 f1, FlowEntryState.ADDED)));
424
425
alshabibcf369912014-10-13 14:16:42 -0700426 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
427 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
428
429 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
430 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
431
432 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
433 Lists.newArrayList(fbe1, fbe2));
434 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
435
436 future.cancel(true);
437
438 assertTrue(flowCount() == 2);
439
440 /*
441 * Rule f1 should be re-added to the list and therefore be in a pending add
442 * state.
443 */
444 assertTrue("Entries in wrong state",
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700445 validateState(ImmutableMap.of(
446 f2, FlowEntryState.PENDING_REMOVE,
447 f1, FlowEntryState.PENDING_ADD)));
alshabibcf369912014-10-13 14:16:42 -0700448
449
alshabibcf369912014-10-13 14:16:42 -0700450 }
451
452
453
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700454 private static class TestListener implements FlowRuleListener {
455 final List<FlowRuleEvent> events = new ArrayList<>();
456
457 @Override
458 public void event(FlowRuleEvent event) {
459 events.add(event);
460 }
461 }
462
463 private static class TestDeviceService implements DeviceService {
464
465 @Override
466 public int getDeviceCount() {
467 return 0;
468 }
469
470 @Override
471 public Iterable<Device> getDevices() {
472 return null;
473 }
474
475 @Override
476 public Device getDevice(DeviceId deviceId) {
477 return DEV;
478 }
479
480 @Override
481 public MastershipRole getRole(DeviceId deviceId) {
482 return null;
483 }
484
485 @Override
486 public List<Port> getPorts(DeviceId deviceId) {
487 return null;
488 }
489
490 @Override
491 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
492 return null;
493 }
494
495 @Override
496 public boolean isAvailable(DeviceId deviceId) {
497 return false;
498 }
499
500 @Override
501 public void addListener(DeviceListener listener) {
502 }
503
504 @Override
505 public void removeListener(DeviceListener listener) {
506 }
507
508 }
509
510 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
511
512 protected TestProvider(ProviderId id) {
513 super(PID);
514 }
515
516 @Override
517 public void applyFlowRule(FlowRule... flowRules) {
518 }
519
520 @Override
521 public void removeFlowRule(FlowRule... flowRules) {
522 }
523
alshabiba68eb962014-09-24 20:34:13 -0700524 @Override
525 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
526 }
527
alshabib902d41b2014-10-07 16:52:05 -0700528 @Override
alshabib193525b2014-10-08 18:58:03 -0700529 public Future<CompletedBatchOperation> executeBatch(
alshabib902d41b2014-10-07 16:52:05 -0700530 BatchOperation<FlowRuleBatchEntry> batch) {
alshabibcf369912014-10-13 14:16:42 -0700531 return new TestInstallationFuture();
alshabib902d41b2014-10-07 16:52:05 -0700532 }
533
alshabibcf369912014-10-13 14:16:42 -0700534 private class TestInstallationFuture
535 implements Future<CompletedBatchOperation> {
536
537 @Override
538 public boolean cancel(boolean mayInterruptIfRunning) {
539 return true;
540 }
541
542 @Override
543 public boolean isCancelled() {
544 return true;
545 }
546
547 @Override
548 public boolean isDone() {
549 return false;
550 }
551
552 @Override
Ray Milkey5154ec32014-10-22 10:51:18 -0700553 @SuppressWarnings("unchecked")
alshabibcf369912014-10-13 14:16:42 -0700554 public CompletedBatchOperation get()
555 throws InterruptedException, ExecutionException {
556 return new CompletedBatchOperation(true, EMPTY_LIST);
557 }
558
559 @Override
560 public CompletedBatchOperation get(long timeout, TimeUnit unit)
561 throws InterruptedException,
562 ExecutionException, TimeoutException {
563 return null;
564 }
565 }
alshabiba68eb962014-09-24 20:34:13 -0700566
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700567 }
568
569 private class TestSelector implements TrafficSelector {
570
571 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700572 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700573
574 public TestSelector(int val) {
575 testval = val;
576 }
577
578 @Override
alshabibba5ac482014-10-02 17:15:20 -0700579 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700580 return null;
581 }
582
583 @Override
584 public int hashCode() {
585 return testval;
586 }
587
588 @Override
589 public boolean equals(Object o) {
590 if (o instanceof TestSelector) {
591 return this.testval == ((TestSelector) o).testval;
592 }
593 return false;
594 }
595 }
596
597 private class TestTreatment implements TrafficTreatment {
598
599 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700600 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700601
602 public TestTreatment(int val) {
603 testval = val;
604 }
605
606 @Override
607 public List<Instruction> instructions() {
608 return null;
609 }
610
611 @Override
612 public int hashCode() {
613 return testval;
614 }
615
616 @Override
617 public boolean equals(Object o) {
618 if (o instanceof TestTreatment) {
619 return this.testval == ((TestTreatment) o).testval;
620 }
621 return false;
622 }
623
624 }
625
alshabib92c65ad2014-10-08 21:56:05 -0700626 public class TestApplicationId extends DefaultApplicationId {
627
628 public TestApplicationId(short id, String name) {
629 super(id, name);
630 }
631 }
632
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700633}