blob: afd9a90de27dcc596336e7e5974d808900cc4af3 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.net.flow.impl;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070017
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableMap;
20import com.google.common.collect.Lists;
21import com.google.common.collect.Sets;
22import com.google.common.util.concurrent.ListenableFuture;
23import com.google.common.util.concurrent.MoreExecutors;
Saurav Das86af8f12015-05-25 23:55:33 -070024
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070025import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
Marc De Leenheerde47caa2015-04-24 11:27:44 -070028import org.onosproject.cfg.ComponentConfigAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.core.ApplicationId;
Ray Milkeycc53abd2015-02-19 12:31:33 -080030import org.onosproject.core.CoreServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.core.DefaultApplicationId;
Brian O'Connor72cb19a2015-01-16 16:14:41 -080032import org.onosproject.core.IdGenerator;
Thomas Vachuska36002e62015-05-19 16:12:29 -070033import org.onosproject.common.event.impl.TestEventDispatcher;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.DefaultDevice;
35import org.onosproject.net.Device;
36import org.onosproject.net.Device.Type;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.MastershipRole;
39import org.onosproject.net.Port;
40import org.onosproject.net.PortNumber;
41import org.onosproject.net.device.DeviceListener;
42import org.onosproject.net.device.DeviceServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.flow.CompletedBatchOperation;
44import org.onosproject.net.flow.DefaultFlowEntry;
45import org.onosproject.net.flow.DefaultFlowRule;
46import org.onosproject.net.flow.FlowEntry;
47import org.onosproject.net.flow.FlowEntry.FlowEntryState;
48import org.onosproject.net.flow.FlowRule;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import 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;
alshabib346b5b32015-03-06 00:42:16 -080061import org.onosproject.net.flow.instructions.Instructions;
Saurav Das86af8f12015-05-25 23:55:33 -070062import org.onosproject.net.flow.instructions.Instructions.MetadataInstruction;
Brian O'Connorabafb502014-12-02 22:26:20 -080063import org.onosproject.net.provider.AbstractProvider;
64import org.onosproject.net.provider.ProviderId;
Thomas Vachuskac97aa612015-06-23 16:00:18 -070065import org.onosproject.store.trivial.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070066
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070067import java.util.ArrayList;
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -070068import java.util.Collections;
69import java.util.HashMap;
70import java.util.List;
71import java.util.Map;
72import java.util.Set;
73import java.util.concurrent.ExecutionException;
74import java.util.concurrent.Executor;
75import java.util.concurrent.TimeUnit;
76import java.util.concurrent.TimeoutException;
77import java.util.concurrent.atomic.AtomicLong;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070078
Ray Milkeyda36c402015-02-18 10:06:06 -080079import static org.junit.Assert.assertEquals;
80import static org.junit.Assert.assertFalse;
81import static org.junit.Assert.assertNotNull;
82import static org.junit.Assert.assertTrue;
Thomas Vachuska42e8cce2015-07-29 19:25:18 -070083import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Ray Milkeyda36c402015-02-18 10:06:06 -080084import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_ADDED;
85import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_ADD_REQUESTED;
86import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
87import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVE_REQUESTED;
88import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070089
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070090/**
91 * Test codifying the flow rule service & flow rule provider service contracts.
92 */
tom202175a2014-09-19 19:00:11 -070093public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070094
alshabib92c65ad2014-10-08 21:56:05 -070095
tomf6ab2152014-09-18 12:08:29 -070096 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070097 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070098 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070099 private static final Device DEV = new DefaultDevice(
alshabib7911a052014-10-16 17:49:37 -0700100 PID, DID, Type.SWITCH, "", "", "", "", null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700101
tom202175a2014-09-19 19:00:11 -0700102 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700103
104 protected FlowRuleService service;
105 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -0700106 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700107 protected TestProvider provider;
108 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -0700109 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700110
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800111
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700112 @Before
113 public void setUp() {
tom202175a2014-09-19 19:00:11 -0700114 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -0700115 mgr.store = new SimpleFlowRuleStore();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700116 injectEventDispatcher(mgr, new TestEventDispatcher());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700117 mgr.deviceService = new TestDeviceService();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800118 mgr.coreService = new TestCoreService();
119 mgr.operationsService = MoreExecutors.newDirectExecutorService();
120 mgr.deviceInstallers = MoreExecutors.newDirectExecutorService();
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700121 mgr.cfgService = new ComponentConfigAdapter();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700122 service = mgr;
123 registry = mgr;
124
Marc De Leenheerde47caa2015-04-24 11:27:44 -0700125 mgr.activate(null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700126 mgr.addListener(listener);
127 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -0700128 providerService = registry.register(provider);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800129 appId = new TestApplicationId(0, "FlowRuleManagerTest");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700130 assertTrue("provider should be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700131 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700132 }
133
134 @After
135 public void tearDown() {
136 registry.unregister(provider);
137 assertFalse("provider should not be registered",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700138 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700139 service.removeListener(listener);
140 mgr.deactivate();
Thomas Vachuska42e8cce2015-07-29 19:25:18 -0700141 injectEventDispatcher(mgr, null);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700142 mgr.deviceService = null;
143 }
144
145 private FlowRule flowRule(int tsval, int trval) {
146 TestSelector ts = new TestSelector(tsval);
147 TestTreatment tr = new TestTreatment(trval);
Ray Milkeyd13a37b2015-06-12 11:55:17 -0700148 return DefaultFlowRule.builder()
149 .forDevice(DID)
150 .withSelector(ts)
151 .withTreatment(tr)
152 .withPriority(10)
153 .fromApp(appId)
154 .makeTemporary(TIMEOUT)
155 .build();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700156 }
157
alshabibbb8b1282014-09-22 17:00:18 -0700158
159 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700160 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700161 service.applyFlowRules(rule);
162
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700163 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700164 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700165 }
166
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700167 private void validateEvents(FlowRuleEvent.Type... events) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700168 if (events == null) {
169 assertTrue("events generated", listener.events.isEmpty());
170 }
171
172 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700173 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700174 for (FlowRuleEvent e : listener.events) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800175 assertEquals("unexpected event", events[i], e.type());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700176 i++;
177 }
178
179 assertEquals("mispredicted number of events",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700180 events.length, listener.events.size());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700181
182 listener.events.clear();
183 }
184
185 private int flowCount() {
186 return Sets.newHashSet(service.getFlowEntries(DID)).size();
187 }
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700188
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700189 @Test
190 public void getFlowEntries() {
191 assertTrue("store should be empty",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700192 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700193 FlowRule f1 = addFlowRule(1);
194 FlowRule f2 = addFlowRule(2);
195
alshabib1c319ff2014-10-04 20:29:09 -0700196 FlowEntry fe1 = new DefaultFlowEntry(f1);
197 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700198 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700199
alshabib1c319ff2014-10-04 20:29:09 -0700200 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabib3d643ec2014-10-22 18:33:00 -0700201 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
202 RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700203
204 addFlowRule(1);
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800205 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700206 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700207
alshabib1c319ff2014-10-04 20:29:09 -0700208 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700209 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700210 }
211
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700212 private boolean validateState(Map<FlowRule, FlowEntryState> expected) {
213 Map<FlowRule, FlowEntryState> expectedToCheck = new HashMap<>(expected);
alshabib1c319ff2014-10-04 20:29:09 -0700214 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabib1c319ff2014-10-04 20:29:09 -0700215 for (FlowEntry f : rules) {
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700216 assertTrue("Unexpected FlowRule " + f, expectedToCheck.containsKey(f));
217 assertEquals("FlowEntry" + f, expectedToCheck.get(f), f.state());
218 expectedToCheck.remove(f);
alshabibbb8b1282014-09-22 17:00:18 -0700219 }
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700220 assertEquals(Collections.emptySet(), expectedToCheck.entrySet());
alshabibbb8b1282014-09-22 17:00:18 -0700221 return true;
222 }
223
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700224 @Test
225 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700226
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700227 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700228 FlowRule r2 = flowRule(2, 2);
229 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700230
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700231 assertTrue("store should be empty",
Ray Milkeycc53abd2015-02-19 12:31:33 -0800232 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700233 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700234 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700235 assertTrue("Entries should be pending add.",
Ray Milkeycc53abd2015-02-19 12:31:33 -0800236 validateState(ImmutableMap.of(
237 r1, FlowEntryState.PENDING_ADD,
238 r2, FlowEntryState.PENDING_ADD,
239 r3, FlowEntryState.PENDING_ADD)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700240 }
241
242 @Test
243 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700244 FlowRule f1 = addFlowRule(1);
245 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700246 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700247 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700248
alshabib1c319ff2014-10-04 20:29:09 -0700249 FlowEntry fe1 = new DefaultFlowEntry(f1);
250 FlowEntry fe2 = new DefaultFlowEntry(f2);
251 FlowEntry fe3 = new DefaultFlowEntry(f3);
252 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700253 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
254 RULE_ADDED, RULE_ADDED, RULE_ADDED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700255
alshabib1c319ff2014-10-04 20:29:09 -0700256 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700257 //removing from north, so no events generated
alshabib3d643ec2014-10-22 18:33:00 -0700258 validateEvents(RULE_REMOVE_REQUESTED, RULE_REMOVE_REQUESTED);
alshabib219ebaa2014-09-22 15:41:24 -0700259 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700260 assertTrue("Entries should be pending remove.",
Ray Milkeycc53abd2015-02-19 12:31:33 -0800261 validateState(ImmutableMap.of(
262 f1, FlowEntryState.PENDING_REMOVE,
263 f2, FlowEntryState.PENDING_REMOVE,
264 f3, FlowEntryState.ADDED)));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700265
alshabib1c319ff2014-10-04 20:29:09 -0700266 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700267 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700268 }
269
270 @Test
271 public void flowRemoved() {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800272
alshabibbb8b1282014-09-22 17:00:18 -0700273 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700274 FlowRule f2 = addFlowRule(2);
Yuta HIGUCHIf6f50a62014-10-19 15:58:49 -0700275 StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700276 FlowEntry fe2 = new DefaultFlowEntry(f2);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800277
278
alshabib1c319ff2014-10-04 20:29:09 -0700279 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700280 service.removeFlowRules(f1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800281
alshabib1c319ff2014-10-04 20:29:09 -0700282 fe1.setState(FlowEntryState.REMOVED);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800283
284
285
alshabib1c319ff2014-10-04 20:29:09 -0700286 providerService.flowRemoved(fe1);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800287
288
alshabib3d643ec2014-10-22 18:33:00 -0700289 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED,
Ray Milkeycc53abd2015-02-19 12:31:33 -0800290 RULE_ADDED, RULE_REMOVE_REQUESTED, RULE_REMOVED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700291
alshabib1c319ff2014-10-04 20:29:09 -0700292 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700293 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700294
alshabibba5ac482014-10-02 17:15:20 -0700295 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700296 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700297 service.applyFlowRules(f3);
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800298
alshabib1c319ff2014-10-04 20:29:09 -0700299 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabib3d643ec2014-10-22 18:33:00 -0700300 validateEvents(RULE_ADD_REQUESTED, RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700301
alshabib1c319ff2014-10-04 20:29:09 -0700302 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700303 validateEvents();
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800304
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700305 }
306
alshabibbb8b1282014-09-22 17:00:18 -0700307 @Test
308 public void flowMetrics() {
309 FlowRule f1 = flowRule(1, 1);
310 FlowRule f2 = flowRule(2, 2);
311 FlowRule f3 = flowRule(3, 3);
312
alshabibba5ac482014-10-02 17:15:20 -0700313 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700314
alshabib1c319ff2014-10-04 20:29:09 -0700315 FlowEntry fe1 = new DefaultFlowEntry(f1);
316 FlowEntry fe2 = new DefaultFlowEntry(f2);
317
alshabib1c319ff2014-10-04 20:29:09 -0700318 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
319 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
320
321 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700322
323 assertTrue("Entries should be added.",
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700324 validateState(ImmutableMap.of(
325 f1, FlowEntryState.ADDED,
326 f2, FlowEntryState.ADDED,
327 f3, FlowEntryState.PENDING_ADD)));
alshabibbb42cad2014-09-25 11:43:05 -0700328
alshabib3d643ec2014-10-22 18:33:00 -0700329 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
Ray Milkeycc53abd2015-02-19 12:31:33 -0800330 RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700331 }
332
333 @Test
334 public void extraneousFlow() {
335 FlowRule f1 = flowRule(1, 1);
336 FlowRule f2 = flowRule(2, 2);
337 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700338 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700339
alshabib1c319ff2014-10-04 20:29:09 -0700340// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
341// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
342// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
343 FlowEntry fe1 = new DefaultFlowEntry(f1);
344 FlowEntry fe2 = new DefaultFlowEntry(f2);
345 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700346
alshabib1c319ff2014-10-04 20:29:09 -0700347
348 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700349
alshabib3d643ec2014-10-22 18:33:00 -0700350 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700351
352 }
353
354 /*
355 * Tests whether a rule that was marked for removal but no flowRemoved was received
356 * is indeed removed at the next stats update.
357 */
358 @Test
359 public void flowMissingRemove() {
360 FlowRule f1 = flowRule(1, 1);
361 FlowRule f2 = flowRule(2, 2);
362 FlowRule f3 = flowRule(3, 3);
363
alshabib1c319ff2014-10-04 20:29:09 -0700364// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
365// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
366
367 FlowEntry fe1 = new DefaultFlowEntry(f1);
368 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700369 mgr.applyFlowRules(f1, f2, f3);
370
371 mgr.removeFlowRules(f3);
372
alshabib1c319ff2014-10-04 20:29:09 -0700373 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700374
alshabib3d643ec2014-10-22 18:33:00 -0700375 validateEvents(RULE_ADD_REQUESTED, RULE_ADD_REQUESTED, RULE_ADD_REQUESTED,
376 RULE_REMOVE_REQUESTED, RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700377
378 }
379
380 @Test
381 public void getByAppId() {
382 FlowRule f1 = flowRule(1, 1);
383 FlowRule f2 = flowRule(2, 2);
384 mgr.applyFlowRules(f1, f2);
385
386 assertTrue("should have two rules",
Ray Milkeycc53abd2015-02-19 12:31:33 -0800387 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
alshabibbb42cad2014-09-25 11:43:05 -0700388 }
389
390 @Test
391 public void removeByAppId() {
392 FlowRule f1 = flowRule(1, 1);
393 FlowRule f2 = flowRule(2, 2);
394 mgr.applyFlowRules(f1, f2);
395
396
397 mgr.removeFlowRulesById(appId);
398
399 //only check that we are in pending remove. Events and actual remove state will
400 // be set by flowRemoved call.
Yuta HIGUCHI605347c2014-10-17 21:05:23 -0700401 validateState(ImmutableMap.of(
Thomas Vachuskae0f804a2014-10-27 23:40:48 -0700402 f1, FlowEntryState.PENDING_REMOVE,
403 f2, FlowEntryState.PENDING_REMOVE));
alshabibbb8b1282014-09-22 17:00:18 -0700404 }
405
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700406 private static class TestListener implements FlowRuleListener {
407 final List<FlowRuleEvent> events = new ArrayList<>();
408
409 @Override
410 public void event(FlowRuleEvent event) {
411 events.add(event);
412 }
413 }
414
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800415 private static class TestDeviceService extends DeviceServiceAdapter {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700416
417 @Override
418 public int getDeviceCount() {
Madan Jampani6a456162014-10-24 11:36:17 -0700419 return 1;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700420 }
421
422 @Override
423 public Iterable<Device> getDevices() {
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700424 return Collections.singletonList(DEV);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700425 }
426
427 @Override
428 public Device getDevice(DeviceId deviceId) {
429 return DEV;
430 }
431
432 @Override
433 public MastershipRole getRole(DeviceId deviceId) {
434 return null;
435 }
436
437 @Override
438 public List<Port> getPorts(DeviceId deviceId) {
439 return null;
440 }
441
442 @Override
443 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
444 return null;
445 }
446
447 @Override
448 public boolean isAvailable(DeviceId deviceId) {
449 return false;
450 }
451
452 @Override
453 public void addListener(DeviceListener listener) {
454 }
455
456 @Override
457 public void removeListener(DeviceListener listener) {
458 }
459
460 }
461
462 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
463
464 protected TestProvider(ProviderId id) {
465 super(PID);
466 }
467
468 @Override
469 public void applyFlowRule(FlowRule... flowRules) {
470 }
471
472 @Override
473 public void removeFlowRule(FlowRule... flowRules) {
474 }
475
alshabiba68eb962014-09-24 20:34:13 -0700476 @Override
477 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
478 }
479
alshabib902d41b2014-10-07 16:52:05 -0700480 @Override
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800481 public void executeBatch(FlowRuleBatchOperation batch) {
482 // TODO: need to call batchOperationComplete
alshabib902d41b2014-10-07 16:52:05 -0700483 }
484
alshabibcf369912014-10-13 14:16:42 -0700485 private class TestInstallationFuture
Madan Jampani117aaae2014-10-23 10:04:05 -0700486 implements ListenableFuture<CompletedBatchOperation> {
alshabibcf369912014-10-13 14:16:42 -0700487
488 @Override
489 public boolean cancel(boolean mayInterruptIfRunning) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800490 return false;
alshabibcf369912014-10-13 14:16:42 -0700491 }
492
493 @Override
494 public boolean isCancelled() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800495 return false;
alshabibcf369912014-10-13 14:16:42 -0700496 }
497
498 @Override
499 public boolean isDone() {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800500 return true;
alshabibcf369912014-10-13 14:16:42 -0700501 }
502
503 @Override
504 public CompletedBatchOperation get()
505 throws InterruptedException, ExecutionException {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800506 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700507 }
508
509 @Override
510 public CompletedBatchOperation get(long timeout, TimeUnit unit)
511 throws InterruptedException,
512 ExecutionException, TimeoutException {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800513 return new CompletedBatchOperation(true, Collections.<FlowRule>emptySet(), null);
alshabibcf369912014-10-13 14:16:42 -0700514 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700515
516 @Override
517 public void addListener(Runnable task, Executor executor) {
Yuta HIGUCHI2fcb40c2014-11-03 14:39:10 -0800518 if (isDone()) {
519 executor.execute(task);
520 }
Madan Jampani117aaae2014-10-23 10:04:05 -0700521 }
alshabibcf369912014-10-13 14:16:42 -0700522 }
alshabiba68eb962014-09-24 20:34:13 -0700523
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700524 }
525
526 private class TestSelector implements TrafficSelector {
527
528 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700529 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700530
531 public TestSelector(int val) {
532 testval = val;
533 }
534
535 @Override
alshabibba5ac482014-10-02 17:15:20 -0700536 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700537 return null;
538 }
539
540 @Override
Jonathan Hart936c49d2014-10-23 16:38:59 -0700541 public Criterion getCriterion(
Brian O'Connorabafb502014-12-02 22:26:20 -0800542 org.onosproject.net.flow.criteria.Criterion.Type type) {
Jonathan Hart936c49d2014-10-23 16:38:59 -0700543 return null;
544 }
545
546 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700547 public int hashCode() {
548 return testval;
549 }
550
551 @Override
552 public boolean equals(Object o) {
553 if (o instanceof TestSelector) {
554 return this.testval == ((TestSelector) o).testval;
555 }
556 return false;
557 }
Jonathan Hart936c49d2014-10-23 16:38:59 -0700558
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700559 }
560
561 private class TestTreatment implements TrafficTreatment {
562
563 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700564 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700565
566 public TestTreatment(int val) {
567 testval = val;
568 }
569
570 @Override
alshabib346b5b32015-03-06 00:42:16 -0800571 public List<Instruction> deferred() {
572 return null;
573 }
574
575 @Override
576 public List<Instruction> immediate() {
577 return null;
578 }
579
580 @Override
Jonathan Hart8ef6d3b2015-03-08 21:21:27 -0700581 public List<Instruction> allInstructions() {
582 return null;
583 }
584
585 @Override
alshabib346b5b32015-03-06 00:42:16 -0800586 public Instructions.TableTypeTransition tableTransition() {
587 return null;
588 }
589
590 @Override
Jonathan Hart4a0ba562015-03-23 17:23:33 -0700591 public boolean clearedDeferred() {
592 return false;
alshabib346b5b32015-03-06 00:42:16 -0800593 }
594
595 @Override
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700596 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
Saurav Das86af8f12015-05-25 23:55:33 -0700608 @Override
609 public MetadataInstruction writeMetadata() {
610 return null;
611 }
612
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700613 }
614
alshabib92c65ad2014-10-08 21:56:05 -0700615 public class TestApplicationId extends DefaultApplicationId {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800616 public TestApplicationId(int id, String name) {
alshabib92c65ad2014-10-08 21:56:05 -0700617 super(id, name);
618 }
619 }
620
Ray Milkeycc53abd2015-02-19 12:31:33 -0800621 private class TestCoreService extends CoreServiceAdapter {
Brian O'Connor72cb19a2015-01-16 16:14:41 -0800622
623 @Override
624 public IdGenerator getIdGenerator(String topic) {
625 return new IdGenerator() {
626 private AtomicLong counter = new AtomicLong(0);
627 @Override
628 public long getNewId() {
629 return counter.getAndIncrement();
630 }
631 };
632 }
633 }
634
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700635}