blob: 86164fd0ed077e50dc316fb627cf732d40825fd0 [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.flow.impl;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07002
alshabibcf369912014-10-13 14:16:42 -07003import static java.util.Collections.EMPTY_LIST;
4import static org.junit.Assert.*;
alshabib97044902014-09-18 14:52:16 -07005import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
6import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
alshabib219ebaa2014-09-22 15:41:24 -07007import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07008
9import java.util.ArrayList;
alshabibba5ac482014-10-02 17:15:20 -070010import java.util.Collections;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070011import java.util.List;
alshabibba5ac482014-10-02 17:15:20 -070012import java.util.Set;
alshabibcf369912014-10-13 14:16:42 -070013import java.util.concurrent.ExecutionException;
alshabib902d41b2014-10-07 16:52:05 -070014import java.util.concurrent.Future;
alshabibcf369912014-10-13 14:16:42 -070015import java.util.concurrent.TimeUnit;
16import java.util.concurrent.TimeoutException;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070017
18import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
alshabiba68eb962014-09-24 20:34:13 -070021import org.onlab.onos.ApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070022import org.onlab.onos.event.impl.TestEventDispatcher;
alshabib92c65ad2014-10-08 21:56:05 -070023import org.onlab.onos.impl.DefaultApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070024import org.onlab.onos.net.DefaultDevice;
25import org.onlab.onos.net.Device;
26import org.onlab.onos.net.Device.Type;
27import org.onlab.onos.net.DeviceId;
28import org.onlab.onos.net.MastershipRole;
29import org.onlab.onos.net.Port;
30import org.onlab.onos.net.PortNumber;
31import org.onlab.onos.net.device.DeviceListener;
32import org.onlab.onos.net.device.DeviceService;
alshabib193525b2014-10-08 18:58:03 -070033import org.onlab.onos.net.flow.CompletedBatchOperation;
alshabib1c319ff2014-10-04 20:29:09 -070034import org.onlab.onos.net.flow.DefaultFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070035import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib1c319ff2014-10-04 20:29:09 -070036import org.onlab.onos.net.flow.FlowEntry;
37import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070038import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070039import org.onlab.onos.net.flow.FlowRuleBatchEntry;
alshabibcf369912014-10-13 14:16:42 -070040import org.onlab.onos.net.flow.FlowRuleBatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070041import org.onlab.onos.net.flow.FlowRuleEvent;
42import org.onlab.onos.net.flow.FlowRuleListener;
43import org.onlab.onos.net.flow.FlowRuleProvider;
44import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
45import org.onlab.onos.net.flow.FlowRuleProviderService;
46import org.onlab.onos.net.flow.FlowRuleService;
47import org.onlab.onos.net.flow.TrafficSelector;
48import org.onlab.onos.net.flow.TrafficTreatment;
49import org.onlab.onos.net.flow.criteria.Criterion;
50import org.onlab.onos.net.flow.instructions.Instruction;
alshabib902d41b2014-10-07 16:52:05 -070051import org.onlab.onos.net.intent.BatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070052import org.onlab.onos.net.provider.AbstractProvider;
53import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070054import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070055
alshabibba5ac482014-10-02 17:15:20 -070056import com.google.common.collect.ImmutableList;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070057import com.google.common.collect.Lists;
58import com.google.common.collect.Sets;
59
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070060/**
61 * Test codifying the flow rule service & flow rule provider service contracts.
62 */
tom202175a2014-09-19 19:00:11 -070063public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070064
alshabib92c65ad2014-10-08 21:56:05 -070065
66
tomf6ab2152014-09-18 12:08:29 -070067 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070068 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070069 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070070 private static final Device DEV = new DefaultDevice(
alshabib7911a052014-10-16 17:49:37 -070071 PID, DID, Type.SWITCH, "", "", "", "", null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070072
tom202175a2014-09-19 19:00:11 -070073 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070074
75 protected FlowRuleService service;
76 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -070077 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070078 protected TestProvider provider;
79 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -070080 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070081
82 @Before
83 public void setUp() {
tom202175a2014-09-19 19:00:11 -070084 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -070085 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070086 mgr.eventDispatcher = new TestEventDispatcher();
87 mgr.deviceService = new TestDeviceService();
88 service = mgr;
89 registry = mgr;
90
91 mgr.activate();
92 mgr.addListener(listener);
93 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -070094 providerService = registry.register(provider);
alshabib92c65ad2014-10-08 21:56:05 -070095 appId = new TestApplicationId((short) 0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070096 assertTrue("provider should be registered",
97 registry.getProviders().contains(provider.id()));
98 }
99
100 @After
101 public void tearDown() {
102 registry.unregister(provider);
103 assertFalse("provider should not be registered",
alshabib97044902014-09-18 14:52:16 -0700104 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700105 service.removeListener(listener);
106 mgr.deactivate();
107 mgr.eventDispatcher = null;
108 mgr.deviceService = null;
109 }
110
111 private FlowRule flowRule(int tsval, int trval) {
112 TestSelector ts = new TestSelector(tsval);
113 TestTreatment tr = new TestTreatment(trval);
alshabiba0e04982014-10-03 13:03:19 -0700114 return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700115 }
116
alshabibbb8b1282014-09-22 17:00:18 -0700117
118 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700119 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700120 service.applyFlowRules(rule);
121
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700122 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700123 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700124 }
125
126 private void validateEvents(FlowRuleEvent.Type ... events) {
127 if (events == null) {
128 assertTrue("events generated", listener.events.isEmpty());
129 }
130
131 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700132 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700133 for (FlowRuleEvent e : listener.events) {
134 assertTrue("unexpected event", e.type().equals(events[i]));
135 i++;
136 }
137
138 assertEquals("mispredicted number of events",
139 events.length, listener.events.size());
140
141 listener.events.clear();
142 }
143
144 private int flowCount() {
145 return Sets.newHashSet(service.getFlowEntries(DID)).size();
146 }
147 @Test
148 public void getFlowEntries() {
149 assertTrue("store should be empty",
150 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700151 FlowRule f1 = addFlowRule(1);
152 FlowRule f2 = addFlowRule(2);
153
alshabib1c319ff2014-10-04 20:29:09 -0700154 FlowEntry fe1 = new DefaultFlowEntry(f1);
155 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700156 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700157
alshabib1c319ff2014-10-04 20:29:09 -0700158 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700159 validateEvents(RULE_ADDED, RULE_ADDED);
160
161 addFlowRule(1);
162 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700163
alshabib1c319ff2014-10-04 20:29:09 -0700164 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700165 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700166 }
167
alshabibbb8b1282014-09-22 17:00:18 -0700168
169 //backing store is sensitive to the order of additions/removals
alshabib1c319ff2014-10-04 20:29:09 -0700170 private boolean validateState(FlowEntryState... state) {
171 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabibbb8b1282014-09-22 17:00:18 -0700172 int i = 0;
alshabib1c319ff2014-10-04 20:29:09 -0700173 for (FlowEntry f : rules) {
alshabibbb8b1282014-09-22 17:00:18 -0700174 if (f.state() != state[i]) {
175 return false;
176 }
177 i++;
178 }
179 return true;
180 }
181
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700182 @Test
183 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700184
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700185 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700186 FlowRule r2 = flowRule(2, 2);
187 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700188
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700189 assertTrue("store should be empty",
alshabibcf369912014-10-13 14:16:42 -0700190 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700191 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700192 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700193 assertTrue("Entries should be pending add.",
alshabibcf369912014-10-13 14:16:42 -0700194 validateState(FlowEntryState.PENDING_ADD, FlowEntryState.PENDING_ADD,
195 FlowEntryState.PENDING_ADD));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700196 }
197
198 @Test
199 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700200 FlowRule f1 = addFlowRule(1);
201 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700202 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700203 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700204
alshabib1c319ff2014-10-04 20:29:09 -0700205 FlowEntry fe1 = new DefaultFlowEntry(f1);
206 FlowEntry fe2 = new DefaultFlowEntry(f2);
207 FlowEntry fe3 = new DefaultFlowEntry(f3);
208 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700209 validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
210
alshabib1c319ff2014-10-04 20:29:09 -0700211 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700212 //removing from north, so no events generated
213 validateEvents();
alshabib219ebaa2014-09-22 15:41:24 -0700214 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700215 assertTrue("Entries should be pending remove.",
alshabibcf369912014-10-13 14:16:42 -0700216 validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE,
217 FlowEntryState.ADDED));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700218
alshabib1c319ff2014-10-04 20:29:09 -0700219 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700220 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700221 }
222
223 @Test
224 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700225 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700226 FlowRule f2 = addFlowRule(2);
alshabib1c319ff2014-10-04 20:29:09 -0700227 FlowEntry fe1 = new DefaultFlowEntry(f1);
228 FlowEntry fe2 = new DefaultFlowEntry(f2);
229 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700230 service.removeFlowRules(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700231 fe1.setState(FlowEntryState.REMOVED);
232 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700233 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
234
alshabib1c319ff2014-10-04 20:29:09 -0700235 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700236 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700237
alshabibba5ac482014-10-02 17:15:20 -0700238 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700239 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700240 service.applyFlowRules(f3);
alshabib1c319ff2014-10-04 20:29:09 -0700241 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700242 validateEvents(RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700243
alshabib1c319ff2014-10-04 20:29:09 -0700244 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700245 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700246 }
247
alshabibbb8b1282014-09-22 17:00:18 -0700248 @Test
249 public void flowMetrics() {
250 FlowRule f1 = flowRule(1, 1);
251 FlowRule f2 = flowRule(2, 2);
252 FlowRule f3 = flowRule(3, 3);
253
alshabibba5ac482014-10-02 17:15:20 -0700254 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700255
alshabib1c319ff2014-10-04 20:29:09 -0700256 FlowEntry fe1 = new DefaultFlowEntry(f1);
257 FlowEntry fe2 = new DefaultFlowEntry(f2);
258
259
260 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
261 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
262
263 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700264
265 assertTrue("Entries should be added.",
alshabib1c319ff2014-10-04 20:29:09 -0700266 validateState(FlowEntryState.ADDED, FlowEntryState.ADDED,
267 FlowEntryState.PENDING_ADD));
alshabibbb42cad2014-09-25 11:43:05 -0700268
alshabibba5ac482014-10-02 17:15:20 -0700269 validateEvents(RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700270 }
271
272 @Test
273 public void extraneousFlow() {
274 FlowRule f1 = flowRule(1, 1);
275 FlowRule f2 = flowRule(2, 2);
276 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700277 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700278
alshabib1c319ff2014-10-04 20:29:09 -0700279// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
280// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
281// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
282 FlowEntry fe1 = new DefaultFlowEntry(f1);
283 FlowEntry fe2 = new DefaultFlowEntry(f2);
284 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700285
alshabib1c319ff2014-10-04 20:29:09 -0700286
287 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700288
alshabibba5ac482014-10-02 17:15:20 -0700289 validateEvents(RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700290
291 }
292
293 /*
294 * Tests whether a rule that was marked for removal but no flowRemoved was received
295 * is indeed removed at the next stats update.
296 */
297 @Test
298 public void flowMissingRemove() {
299 FlowRule f1 = flowRule(1, 1);
300 FlowRule f2 = flowRule(2, 2);
301 FlowRule f3 = flowRule(3, 3);
302
alshabib1c319ff2014-10-04 20:29:09 -0700303// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
304// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
305
306 FlowEntry fe1 = new DefaultFlowEntry(f1);
307 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700308 mgr.applyFlowRules(f1, f2, f3);
309
310 mgr.removeFlowRules(f3);
311
alshabib1c319ff2014-10-04 20:29:09 -0700312 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700313
alshabibba5ac482014-10-02 17:15:20 -0700314 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700315
316 }
317
318 @Test
319 public void getByAppId() {
320 FlowRule f1 = flowRule(1, 1);
321 FlowRule f2 = flowRule(2, 2);
322 mgr.applyFlowRules(f1, f2);
323
324 assertTrue("should have two rules",
alshabibcf369912014-10-13 14:16:42 -0700325 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700326 }
327
328 @Test
329 public void removeByAppId() {
330 FlowRule f1 = flowRule(1, 1);
331 FlowRule f2 = flowRule(2, 2);
332 mgr.applyFlowRules(f1, f2);
333
334
335 mgr.removeFlowRulesById(appId);
336
337 //only check that we are in pending remove. Events and actual remove state will
338 // be set by flowRemoved call.
alshabib1c319ff2014-10-04 20:29:09 -0700339 validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE);
alshabibbb8b1282014-09-22 17:00:18 -0700340 }
341
alshabibcf369912014-10-13 14:16:42 -0700342 @Test
343 public void applyBatch() {
344 FlowRule f1 = flowRule(1, 1);
345 FlowRule f2 = flowRule(2, 2);
346
347
348 mgr.applyFlowRules(f1);
349
350 FlowEntry fe1 = new DefaultFlowEntry(f1);
351 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
352
353 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
354 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
355
356 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
357 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
358
359 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
360 Lists.newArrayList(fbe1, fbe2));
361 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
362 assertTrue("Entries in wrong state",
363 validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_ADD));
364 CompletedBatchOperation completed = null;
365 try {
366 completed = future.get();
367 } catch (InterruptedException | ExecutionException e) {
368 fail("Unexpected exception: " + e);
369 }
370 if (!completed.isSuccess()) {
371 fail("Installation should be a success");
372 }
373
374 }
375
376 @Test
377 public void cancelBatch() {
378 FlowRule f1 = flowRule(1, 1);
379 FlowRule f2 = flowRule(2, 2);
380
381
382 mgr.applyFlowRules(f1);
383
384 FlowEntry fe1 = new DefaultFlowEntry(f1);
385 providerService.pushFlowMetrics(DID, Collections.<FlowEntry>singletonList(fe1));
386
387 FlowRuleBatchEntry fbe1 = new FlowRuleBatchEntry(
388 FlowRuleBatchEntry.FlowRuleOperation.REMOVE, f1);
389
390 FlowRuleBatchEntry fbe2 = new FlowRuleBatchEntry(
391 FlowRuleBatchEntry.FlowRuleOperation.ADD, f2);
392
393 FlowRuleBatchOperation fbo = new FlowRuleBatchOperation(
394 Lists.newArrayList(fbe1, fbe2));
395 Future<CompletedBatchOperation> future = mgr.applyBatch(fbo);
396
397 future.cancel(true);
398
399 assertTrue(flowCount() == 2);
400
401 /*
402 * Rule f1 should be re-added to the list and therefore be in a pending add
403 * state.
404 */
405 assertTrue("Entries in wrong state",
406 validateState(FlowEntryState.PENDING_REMOVE,
407 FlowEntryState.PENDING_ADD));
408
409
alshabibcf369912014-10-13 14:16:42 -0700410 }
411
412
413
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700414 private static class TestListener implements FlowRuleListener {
415 final List<FlowRuleEvent> events = new ArrayList<>();
416
417 @Override
418 public void event(FlowRuleEvent event) {
419 events.add(event);
420 }
421 }
422
423 private static class TestDeviceService implements DeviceService {
424
425 @Override
426 public int getDeviceCount() {
427 return 0;
428 }
429
430 @Override
431 public Iterable<Device> getDevices() {
432 return null;
433 }
434
435 @Override
436 public Device getDevice(DeviceId deviceId) {
437 return DEV;
438 }
439
440 @Override
441 public MastershipRole getRole(DeviceId deviceId) {
442 return null;
443 }
444
445 @Override
446 public List<Port> getPorts(DeviceId deviceId) {
447 return null;
448 }
449
450 @Override
451 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
452 return null;
453 }
454
455 @Override
456 public boolean isAvailable(DeviceId deviceId) {
457 return false;
458 }
459
460 @Override
461 public void addListener(DeviceListener listener) {
462 }
463
464 @Override
465 public void removeListener(DeviceListener listener) {
466 }
467
468 }
469
470 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
471
472 protected TestProvider(ProviderId id) {
473 super(PID);
474 }
475
476 @Override
477 public void applyFlowRule(FlowRule... flowRules) {
478 }
479
480 @Override
481 public void removeFlowRule(FlowRule... flowRules) {
482 }
483
alshabiba68eb962014-09-24 20:34:13 -0700484 @Override
485 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
486 }
487
alshabib902d41b2014-10-07 16:52:05 -0700488 @Override
alshabib193525b2014-10-08 18:58:03 -0700489 public Future<CompletedBatchOperation> executeBatch(
alshabib902d41b2014-10-07 16:52:05 -0700490 BatchOperation<FlowRuleBatchEntry> batch) {
alshabibcf369912014-10-13 14:16:42 -0700491 return new TestInstallationFuture();
alshabib902d41b2014-10-07 16:52:05 -0700492 }
493
alshabibcf369912014-10-13 14:16:42 -0700494 private class TestInstallationFuture
495 implements Future<CompletedBatchOperation> {
496
497 @Override
498 public boolean cancel(boolean mayInterruptIfRunning) {
499 return true;
500 }
501
502 @Override
503 public boolean isCancelled() {
504 return true;
505 }
506
507 @Override
508 public boolean isDone() {
509 return false;
510 }
511
512 @Override
513 public CompletedBatchOperation get()
514 throws InterruptedException, ExecutionException {
515 return new CompletedBatchOperation(true, EMPTY_LIST);
516 }
517
518 @Override
519 public CompletedBatchOperation get(long timeout, TimeUnit unit)
520 throws InterruptedException,
521 ExecutionException, TimeoutException {
522 return null;
523 }
524 }
alshabiba68eb962014-09-24 20:34:13 -0700525
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700526 }
527
528 private class TestSelector implements TrafficSelector {
529
530 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700531 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700532
533 public TestSelector(int val) {
534 testval = val;
535 }
536
537 @Override
alshabibba5ac482014-10-02 17:15:20 -0700538 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700539 return null;
540 }
541
542 @Override
543 public int hashCode() {
544 return testval;
545 }
546
547 @Override
548 public boolean equals(Object o) {
549 if (o instanceof TestSelector) {
550 return this.testval == ((TestSelector) o).testval;
551 }
552 return false;
553 }
554 }
555
556 private class TestTreatment implements TrafficTreatment {
557
558 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700559 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700560
561 public TestTreatment(int val) {
562 testval = val;
563 }
564
565 @Override
566 public List<Instruction> instructions() {
567 return null;
568 }
569
570 @Override
571 public int hashCode() {
572 return testval;
573 }
574
575 @Override
576 public boolean equals(Object o) {
577 if (o instanceof TestTreatment) {
578 return this.testval == ((TestTreatment) o).testval;
579 }
580 return false;
581 }
582
583 }
584
alshabib92c65ad2014-10-08 21:56:05 -0700585 public class TestApplicationId extends DefaultApplicationId {
586
587 public TestApplicationId(short id, String name) {
588 super(id, name);
589 }
590 }
591
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700592}