blob: 5b363daae543354802510a9d4f1be9332d1f4797 [file] [log] [blame]
tombe988312014-09-19 18:38:47 -07001package org.onlab.onos.net.flow.impl;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07002
3import static org.junit.Assert.assertEquals;
4import static org.junit.Assert.assertFalse;
5import static org.junit.Assert.assertNotNull;
6import static org.junit.Assert.assertTrue;
alshabib97044902014-09-18 14:52:16 -07007import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
8import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
alshabib219ebaa2014-09-22 15:41:24 -07009import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070010
11import java.util.ArrayList;
alshabibba5ac482014-10-02 17:15:20 -070012import java.util.Collections;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070013import java.util.List;
alshabibba5ac482014-10-02 17:15:20 -070014import java.util.Set;
alshabib902d41b2014-10-07 16:52:05 -070015import java.util.concurrent.Future;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070016
17import org.junit.After;
18import org.junit.Before;
19import org.junit.Test;
alshabiba68eb962014-09-24 20:34:13 -070020import org.onlab.onos.ApplicationId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070021import org.onlab.onos.event.impl.TestEventDispatcher;
22import org.onlab.onos.net.DefaultDevice;
23import org.onlab.onos.net.Device;
24import org.onlab.onos.net.Device.Type;
25import org.onlab.onos.net.DeviceId;
26import org.onlab.onos.net.MastershipRole;
27import org.onlab.onos.net.Port;
28import org.onlab.onos.net.PortNumber;
29import org.onlab.onos.net.device.DeviceListener;
30import org.onlab.onos.net.device.DeviceService;
alshabib193525b2014-10-08 18:58:03 -070031import org.onlab.onos.net.flow.CompletedBatchOperation;
alshabib1c319ff2014-10-04 20:29:09 -070032import org.onlab.onos.net.flow.DefaultFlowEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070033import org.onlab.onos.net.flow.DefaultFlowRule;
alshabib1c319ff2014-10-04 20:29:09 -070034import org.onlab.onos.net.flow.FlowEntry;
35import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070036import org.onlab.onos.net.flow.FlowRule;
alshabib902d41b2014-10-07 16:52:05 -070037import org.onlab.onos.net.flow.FlowRuleBatchEntry;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070038import org.onlab.onos.net.flow.FlowRuleEvent;
39import org.onlab.onos.net.flow.FlowRuleListener;
40import org.onlab.onos.net.flow.FlowRuleProvider;
41import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
42import org.onlab.onos.net.flow.FlowRuleProviderService;
43import org.onlab.onos.net.flow.FlowRuleService;
44import org.onlab.onos.net.flow.TrafficSelector;
45import org.onlab.onos.net.flow.TrafficTreatment;
46import org.onlab.onos.net.flow.criteria.Criterion;
47import org.onlab.onos.net.flow.instructions.Instruction;
alshabib902d41b2014-10-07 16:52:05 -070048import org.onlab.onos.net.intent.BatchOperation;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070049import org.onlab.onos.net.provider.AbstractProvider;
50import org.onlab.onos.net.provider.ProviderId;
tomea961ff2014-10-01 12:45:15 -070051import org.onlab.onos.store.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070052
alshabibba5ac482014-10-02 17:15:20 -070053import com.google.common.collect.ImmutableList;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070054import com.google.common.collect.Lists;
55import com.google.common.collect.Sets;
56
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070057/**
58 * Test codifying the flow rule service & flow rule provider service contracts.
59 */
tom202175a2014-09-19 19:00:11 -070060public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070061
tomf6ab2152014-09-18 12:08:29 -070062 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070063 private static final DeviceId DID = DeviceId.deviceId("of:001");
alshabibba5ac482014-10-02 17:15:20 -070064 private static final int TIMEOUT = 10;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070065 private static final Device DEV = new DefaultDevice(
66 PID, DID, Type.SWITCH, "", "", "", "");
67
tom202175a2014-09-19 19:00:11 -070068 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070069
70 protected FlowRuleService service;
71 protected FlowRuleProviderRegistry registry;
alshabibbb8b1282014-09-22 17:00:18 -070072 protected FlowRuleProviderService providerService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070073 protected TestProvider provider;
74 protected TestListener listener = new TestListener();
alshabiba68eb962014-09-24 20:34:13 -070075 private ApplicationId appId;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070076
77 @Before
78 public void setUp() {
tom202175a2014-09-19 19:00:11 -070079 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -070080 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070081 mgr.eventDispatcher = new TestEventDispatcher();
82 mgr.deviceService = new TestDeviceService();
83 service = mgr;
84 registry = mgr;
85
86 mgr.activate();
87 mgr.addListener(listener);
88 provider = new TestProvider(PID);
alshabibbb8b1282014-09-22 17:00:18 -070089 providerService = registry.register(provider);
alshabiba68eb962014-09-24 20:34:13 -070090 appId = ApplicationId.getAppId();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070091 assertTrue("provider should be registered",
92 registry.getProviders().contains(provider.id()));
93 }
94
95 @After
96 public void tearDown() {
97 registry.unregister(provider);
98 assertFalse("provider should not be registered",
alshabib97044902014-09-18 14:52:16 -070099 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700100 service.removeListener(listener);
101 mgr.deactivate();
102 mgr.eventDispatcher = null;
103 mgr.deviceService = null;
104 }
105
106 private FlowRule flowRule(int tsval, int trval) {
107 TestSelector ts = new TestSelector(tsval);
108 TestTreatment tr = new TestTreatment(trval);
alshabiba0e04982014-10-03 13:03:19 -0700109 return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700110 }
111
alshabibbb8b1282014-09-22 17:00:18 -0700112
113 private FlowRule addFlowRule(int hval) {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700114 FlowRule rule = flowRule(hval, hval);
alshabibba5ac482014-10-02 17:15:20 -0700115 service.applyFlowRules(rule);
116
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700117 assertNotNull("rule should be found", service.getFlowEntries(DID));
alshabibbb8b1282014-09-22 17:00:18 -0700118 return rule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700119 }
120
121 private void validateEvents(FlowRuleEvent.Type ... events) {
122 if (events == null) {
123 assertTrue("events generated", listener.events.isEmpty());
124 }
125
126 int i = 0;
alshabibbb42cad2014-09-25 11:43:05 -0700127 System.err.println("events :" + listener.events);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700128 for (FlowRuleEvent e : listener.events) {
129 assertTrue("unexpected event", e.type().equals(events[i]));
130 i++;
131 }
132
133 assertEquals("mispredicted number of events",
134 events.length, listener.events.size());
135
136 listener.events.clear();
137 }
138
139 private int flowCount() {
140 return Sets.newHashSet(service.getFlowEntries(DID)).size();
141 }
142 @Test
143 public void getFlowEntries() {
144 assertTrue("store should be empty",
145 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabibba5ac482014-10-02 17:15:20 -0700146 FlowRule f1 = addFlowRule(1);
147 FlowRule f2 = addFlowRule(2);
148
alshabib1c319ff2014-10-04 20:29:09 -0700149 FlowEntry fe1 = new DefaultFlowEntry(f1);
150 FlowEntry fe2 = new DefaultFlowEntry(f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700151 assertEquals("2 rules should exist", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700152
alshabib1c319ff2014-10-04 20:29:09 -0700153 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700154 validateEvents(RULE_ADDED, RULE_ADDED);
155
156 addFlowRule(1);
157 assertEquals("should still be 2 rules", 2, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700158
alshabib1c319ff2014-10-04 20:29:09 -0700159 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
alshabib219ebaa2014-09-22 15:41:24 -0700160 validateEvents(RULE_UPDATED);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700161 }
162
alshabibbb8b1282014-09-22 17:00:18 -0700163
164 //backing store is sensitive to the order of additions/removals
alshabib1c319ff2014-10-04 20:29:09 -0700165 private boolean validateState(FlowEntryState... state) {
166 Iterable<FlowEntry> rules = service.getFlowEntries(DID);
alshabibbb8b1282014-09-22 17:00:18 -0700167 int i = 0;
alshabib1c319ff2014-10-04 20:29:09 -0700168 for (FlowEntry f : rules) {
alshabibbb8b1282014-09-22 17:00:18 -0700169 if (f.state() != state[i]) {
170 return false;
171 }
172 i++;
173 }
174 return true;
175 }
176
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700177 @Test
178 public void applyFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700179
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700180 FlowRule r1 = flowRule(1, 1);
alshabiba68eb962014-09-24 20:34:13 -0700181 FlowRule r2 = flowRule(2, 2);
182 FlowRule r3 = flowRule(3, 3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700183
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700184 assertTrue("store should be empty",
185 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
alshabib219ebaa2014-09-22 15:41:24 -0700186 mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700187 assertEquals("3 rules should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700188 assertTrue("Entries should be pending add.",
alshabib1c319ff2014-10-04 20:29:09 -0700189 validateState(FlowEntryState.PENDING_ADD, FlowEntryState.PENDING_ADD,
190 FlowEntryState.PENDING_ADD));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700191 }
192
193 @Test
194 public void removeFlowRules() {
alshabibbb8b1282014-09-22 17:00:18 -0700195 FlowRule f1 = addFlowRule(1);
196 FlowRule f2 = addFlowRule(2);
alshabibba5ac482014-10-02 17:15:20 -0700197 FlowRule f3 = addFlowRule(3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700198 assertEquals("3 rules should exist", 3, flowCount());
alshabibba5ac482014-10-02 17:15:20 -0700199
alshabib1c319ff2014-10-04 20:29:09 -0700200 FlowEntry fe1 = new DefaultFlowEntry(f1);
201 FlowEntry fe2 = new DefaultFlowEntry(f2);
202 FlowEntry fe3 = new DefaultFlowEntry(f3);
203 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700204 validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
205
alshabib1c319ff2014-10-04 20:29:09 -0700206 mgr.removeFlowRules(f1, f2);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700207 //removing from north, so no events generated
208 validateEvents();
alshabib219ebaa2014-09-22 15:41:24 -0700209 assertEquals("3 rule should exist", 3, flowCount());
alshabibbb8b1282014-09-22 17:00:18 -0700210 assertTrue("Entries should be pending remove.",
alshabib1c319ff2014-10-04 20:29:09 -0700211 validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE,
212 FlowEntryState.ADDED));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700213
alshabib1c319ff2014-10-04 20:29:09 -0700214 mgr.removeFlowRules(f1);
alshabib219ebaa2014-09-22 15:41:24 -0700215 assertEquals("3 rule should still exist", 3, flowCount());
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700216 }
217
218 @Test
219 public void flowRemoved() {
alshabibbb8b1282014-09-22 17:00:18 -0700220 FlowRule f1 = addFlowRule(1);
alshabibba5ac482014-10-02 17:15:20 -0700221 FlowRule f2 = addFlowRule(2);
alshabib1c319ff2014-10-04 20:29:09 -0700222 FlowEntry fe1 = new DefaultFlowEntry(f1);
223 FlowEntry fe2 = new DefaultFlowEntry(f2);
224 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
alshabiba68eb962014-09-24 20:34:13 -0700225 service.removeFlowRules(f1);
alshabib1c319ff2014-10-04 20:29:09 -0700226 fe1.setState(FlowEntryState.REMOVED);
227 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700228 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
229
alshabib1c319ff2014-10-04 20:29:09 -0700230 providerService.flowRemoved(fe1);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700231 validateEvents();
alshabibbb42cad2014-09-25 11:43:05 -0700232
alshabibba5ac482014-10-02 17:15:20 -0700233 FlowRule f3 = flowRule(3, 3);
alshabib1c319ff2014-10-04 20:29:09 -0700234 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibba5ac482014-10-02 17:15:20 -0700235 service.applyFlowRules(f3);
alshabib1c319ff2014-10-04 20:29:09 -0700236 providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700237 validateEvents(RULE_ADDED);
alshabibba5ac482014-10-02 17:15:20 -0700238
alshabib1c319ff2014-10-04 20:29:09 -0700239 providerService.flowRemoved(fe3);
alshabibbb42cad2014-09-25 11:43:05 -0700240 validateEvents();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700241 }
242
alshabibbb8b1282014-09-22 17:00:18 -0700243 @Test
244 public void flowMetrics() {
245 FlowRule f1 = flowRule(1, 1);
246 FlowRule f2 = flowRule(2, 2);
247 FlowRule f3 = flowRule(3, 3);
248
alshabibba5ac482014-10-02 17:15:20 -0700249 mgr.applyFlowRules(f1, f2, f3);
alshabibbb8b1282014-09-22 17:00:18 -0700250
alshabib1c319ff2014-10-04 20:29:09 -0700251 FlowEntry fe1 = new DefaultFlowEntry(f1);
252 FlowEntry fe2 = new DefaultFlowEntry(f2);
253
254
255 //FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
256 //FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
257
258 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb8b1282014-09-22 17:00:18 -0700259
260 assertTrue("Entries should be added.",
alshabib1c319ff2014-10-04 20:29:09 -0700261 validateState(FlowEntryState.ADDED, FlowEntryState.ADDED,
262 FlowEntryState.PENDING_ADD));
alshabibbb42cad2014-09-25 11:43:05 -0700263
alshabibba5ac482014-10-02 17:15:20 -0700264 validateEvents(RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700265 }
266
267 @Test
268 public void extraneousFlow() {
269 FlowRule f1 = flowRule(1, 1);
270 FlowRule f2 = flowRule(2, 2);
271 FlowRule f3 = flowRule(3, 3);
alshabibba5ac482014-10-02 17:15:20 -0700272 mgr.applyFlowRules(f1, f2);
alshabibbb42cad2014-09-25 11:43:05 -0700273
alshabib1c319ff2014-10-04 20:29:09 -0700274// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
275// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
276// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
277 FlowEntry fe1 = new DefaultFlowEntry(f1);
278 FlowEntry fe2 = new DefaultFlowEntry(f2);
279 FlowEntry fe3 = new DefaultFlowEntry(f3);
alshabibbb42cad2014-09-25 11:43:05 -0700280
alshabib1c319ff2014-10-04 20:29:09 -0700281
282 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
alshabibbb42cad2014-09-25 11:43:05 -0700283
alshabibba5ac482014-10-02 17:15:20 -0700284 validateEvents(RULE_ADDED, RULE_ADDED);
alshabibbb42cad2014-09-25 11:43:05 -0700285
286 }
287
288 /*
289 * Tests whether a rule that was marked for removal but no flowRemoved was received
290 * is indeed removed at the next stats update.
291 */
292 @Test
293 public void flowMissingRemove() {
294 FlowRule f1 = flowRule(1, 1);
295 FlowRule f2 = flowRule(2, 2);
296 FlowRule f3 = flowRule(3, 3);
297
alshabib1c319ff2014-10-04 20:29:09 -0700298// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
299// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
300
301 FlowEntry fe1 = new DefaultFlowEntry(f1);
302 FlowEntry fe2 = new DefaultFlowEntry(f2);
alshabibbb42cad2014-09-25 11:43:05 -0700303 mgr.applyFlowRules(f1, f2, f3);
304
305 mgr.removeFlowRules(f3);
306
alshabib1c319ff2014-10-04 20:29:09 -0700307 providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
alshabibbb42cad2014-09-25 11:43:05 -0700308
alshabibba5ac482014-10-02 17:15:20 -0700309 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
alshabibbb42cad2014-09-25 11:43:05 -0700310
311 }
312
313 @Test
314 public void getByAppId() {
315 FlowRule f1 = flowRule(1, 1);
316 FlowRule f2 = flowRule(2, 2);
317 mgr.applyFlowRules(f1, f2);
318
319 assertTrue("should have two rules",
320 Lists.newLinkedList(mgr.getFlowRulesById(appId)).size() == 2);
321 }
322
323 @Test
324 public void removeByAppId() {
325 FlowRule f1 = flowRule(1, 1);
326 FlowRule f2 = flowRule(2, 2);
327 mgr.applyFlowRules(f1, f2);
328
329
330 mgr.removeFlowRulesById(appId);
331
332 //only check that we are in pending remove. Events and actual remove state will
333 // be set by flowRemoved call.
alshabib1c319ff2014-10-04 20:29:09 -0700334 validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE);
alshabibbb8b1282014-09-22 17:00:18 -0700335 }
336
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700337 private static class TestListener implements FlowRuleListener {
338 final List<FlowRuleEvent> events = new ArrayList<>();
339
340 @Override
341 public void event(FlowRuleEvent event) {
342 events.add(event);
343 }
344 }
345
346 private static class TestDeviceService implements DeviceService {
347
348 @Override
349 public int getDeviceCount() {
350 return 0;
351 }
352
353 @Override
354 public Iterable<Device> getDevices() {
355 return null;
356 }
357
358 @Override
359 public Device getDevice(DeviceId deviceId) {
360 return DEV;
361 }
362
363 @Override
364 public MastershipRole getRole(DeviceId deviceId) {
365 return null;
366 }
367
368 @Override
369 public List<Port> getPorts(DeviceId deviceId) {
370 return null;
371 }
372
373 @Override
374 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
375 return null;
376 }
377
378 @Override
379 public boolean isAvailable(DeviceId deviceId) {
380 return false;
381 }
382
383 @Override
384 public void addListener(DeviceListener listener) {
385 }
386
387 @Override
388 public void removeListener(DeviceListener listener) {
389 }
390
391 }
392
393 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
394
395 protected TestProvider(ProviderId id) {
396 super(PID);
397 }
398
399 @Override
400 public void applyFlowRule(FlowRule... flowRules) {
401 }
402
403 @Override
404 public void removeFlowRule(FlowRule... flowRules) {
405 }
406
alshabiba68eb962014-09-24 20:34:13 -0700407 @Override
408 public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
409 }
410
alshabib902d41b2014-10-07 16:52:05 -0700411 @Override
alshabib193525b2014-10-08 18:58:03 -0700412 public Future<CompletedBatchOperation> executeBatch(
alshabib902d41b2014-10-07 16:52:05 -0700413 BatchOperation<FlowRuleBatchEntry> batch) {
414 // TODO Auto-generated method stub
415 return null;
416 }
417
alshabiba68eb962014-09-24 20:34:13 -0700418
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700419 }
420
421 private class TestSelector implements TrafficSelector {
422
423 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700424 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700425
426 public TestSelector(int val) {
427 testval = val;
428 }
429
430 @Override
alshabibba5ac482014-10-02 17:15:20 -0700431 public Set<Criterion> criteria() {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700432 return null;
433 }
434
435 @Override
436 public int hashCode() {
437 return testval;
438 }
439
440 @Override
441 public boolean equals(Object o) {
442 if (o instanceof TestSelector) {
443 return this.testval == ((TestSelector) o).testval;
444 }
445 return false;
446 }
447 }
448
449 private class TestTreatment implements TrafficTreatment {
450
451 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700452 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700453
454 public TestTreatment(int val) {
455 testval = val;
456 }
457
458 @Override
459 public List<Instruction> instructions() {
460 return null;
461 }
462
463 @Override
464 public int hashCode() {
465 return testval;
466 }
467
468 @Override
469 public boolean equals(Object o) {
470 if (o instanceof TestTreatment) {
471 return this.testval == ((TestTreatment) o).testval;
472 }
473 return false;
474 }
475
476 }
477
478}