blob: b1640156be9680ea6ded66b0a1ac3d43235995c4 [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;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -07009
10import java.util.ArrayList;
11import java.util.List;
12
13import org.junit.After;
14import org.junit.Before;
15import org.junit.Test;
16import org.onlab.onos.event.impl.TestEventDispatcher;
17import org.onlab.onos.net.DefaultDevice;
18import org.onlab.onos.net.Device;
19import org.onlab.onos.net.Device.Type;
20import org.onlab.onos.net.DeviceId;
21import org.onlab.onos.net.MastershipRole;
22import org.onlab.onos.net.Port;
23import org.onlab.onos.net.PortNumber;
24import org.onlab.onos.net.device.DeviceListener;
25import org.onlab.onos.net.device.DeviceService;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070026import org.onlab.onos.net.flow.DefaultFlowRule;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070027import org.onlab.onos.net.flow.FlowRule;
28import org.onlab.onos.net.flow.FlowRuleEvent;
29import org.onlab.onos.net.flow.FlowRuleListener;
30import org.onlab.onos.net.flow.FlowRuleProvider;
31import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
32import org.onlab.onos.net.flow.FlowRuleProviderService;
33import org.onlab.onos.net.flow.FlowRuleService;
34import org.onlab.onos.net.flow.TrafficSelector;
35import org.onlab.onos.net.flow.TrafficTreatment;
36import org.onlab.onos.net.flow.criteria.Criterion;
37import org.onlab.onos.net.flow.instructions.Instruction;
38import org.onlab.onos.net.provider.AbstractProvider;
39import org.onlab.onos.net.provider.ProviderId;
40
41import com.google.common.collect.Lists;
42import com.google.common.collect.Sets;
tom202175a2014-09-19 19:00:11 -070043import org.onlab.onos.net.trivial.impl.SimpleFlowRuleStore;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070044
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070045/**
46 * Test codifying the flow rule service & flow rule provider service contracts.
47 */
tom202175a2014-09-19 19:00:11 -070048public class FlowRuleManagerTest {
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070049
tomf6ab2152014-09-18 12:08:29 -070050 private static final ProviderId PID = new ProviderId("of", "foo");
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070051 private static final DeviceId DID = DeviceId.deviceId("of:001");
52 private static final Device DEV = new DefaultDevice(
53 PID, DID, Type.SWITCH, "", "", "", "");
54
tom202175a2014-09-19 19:00:11 -070055 private FlowRuleManager mgr;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070056
57 protected FlowRuleService service;
58 protected FlowRuleProviderRegistry registry;
59 protected FlowRuleProviderService providerSerivce;
60 protected TestProvider provider;
61 protected TestListener listener = new TestListener();
62
63 @Before
64 public void setUp() {
tom202175a2014-09-19 19:00:11 -070065 mgr = new FlowRuleManager();
tombe988312014-09-19 18:38:47 -070066 mgr.store = new SimpleFlowRuleStore();
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070067 mgr.eventDispatcher = new TestEventDispatcher();
68 mgr.deviceService = new TestDeviceService();
69 service = mgr;
70 registry = mgr;
71
72 mgr.activate();
73 mgr.addListener(listener);
74 provider = new TestProvider(PID);
75 providerSerivce = registry.register(provider);
76 assertTrue("provider should be registered",
77 registry.getProviders().contains(provider.id()));
78 }
79
80 @After
81 public void tearDown() {
82 registry.unregister(provider);
83 assertFalse("provider should not be registered",
alshabib97044902014-09-18 14:52:16 -070084 registry.getProviders().contains(provider.id()));
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070085 service.removeListener(listener);
86 mgr.deactivate();
87 mgr.eventDispatcher = null;
88 mgr.deviceService = null;
89 }
90
91 private FlowRule flowRule(int tsval, int trval) {
92 TestSelector ts = new TestSelector(tsval);
93 TestTreatment tr = new TestTreatment(trval);
Ayaka Koshibed4e53e12014-09-18 14:24:55 -070094 return new DefaultFlowRule(DID, ts, tr, 0);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -070095 }
96
97 private void addFlowRule(int hval) {
98 FlowRule rule = flowRule(hval, hval);
99 providerSerivce.flowAdded(rule);
100 assertNotNull("rule should be found", service.getFlowEntries(DID));
101 }
102
103 private void validateEvents(FlowRuleEvent.Type ... events) {
104 if (events == null) {
105 assertTrue("events generated", listener.events.isEmpty());
106 }
107
108 int i = 0;
109 for (FlowRuleEvent e : listener.events) {
110 assertTrue("unexpected event", e.type().equals(events[i]));
111 i++;
112 }
113
114 assertEquals("mispredicted number of events",
115 events.length, listener.events.size());
116
117 listener.events.clear();
118 }
119
120 private int flowCount() {
121 return Sets.newHashSet(service.getFlowEntries(DID)).size();
122 }
123 @Test
124 public void getFlowEntries() {
125 assertTrue("store should be empty",
126 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
127 addFlowRule(1);
128 addFlowRule(2);
129 assertEquals("2 rules should exist", 2, flowCount());
130 validateEvents(RULE_ADDED, RULE_ADDED);
131
132 addFlowRule(1);
133 assertEquals("should still be 2 rules", 2, flowCount());
134 validateEvents();
135 }
136
137 @Test
138 public void applyFlowRules() {
139 TestSelector ts = new TestSelector(1);
140 FlowRule r1 = flowRule(1, 1);
141 FlowRule r2 = flowRule(1, 2);
142 FlowRule r3 = flowRule(1, 3);
143
144 //current FlowRules always return 0. FlowEntries inherit the value
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700145 FlowRule e1 = new DefaultFlowRule(DID, ts, r1.treatment(), 0);
146 FlowRule e2 = new DefaultFlowRule(DID, ts, r2.treatment(), 0);
147 FlowRule e3 = new DefaultFlowRule(DID, ts, r3.treatment(), 0);
148 List<FlowRule> fel = Lists.newArrayList(e1, e2, e3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700149
150 assertTrue("store should be empty",
151 Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
Ayaka Koshibed4e53e12014-09-18 14:24:55 -0700152 List<FlowRule> ret = mgr.applyFlowRules(r1, r2, r3);
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700153 assertEquals("3 rules should exist", 3, flowCount());
154 assertTrue("3 entries should result", fel.containsAll(ret));
155 }
156
157 @Test
158 public void removeFlowRules() {
159 addFlowRule(1);
160 addFlowRule(2);
161 addFlowRule(3);
162 assertEquals("3 rules should exist", 3, flowCount());
163 validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
164
165 FlowRule rem1 = flowRule(1, 1);
166 FlowRule rem2 = flowRule(2, 2);
167 mgr.removeFlowRules(rem1, rem2);
168 //removing from north, so no events generated
169 validateEvents();
170 assertEquals("1 rule should exist", 1, flowCount());
171
172 mgr.removeFlowRules(rem1);
173 assertEquals("1 rule should still exist", 1, flowCount());
174 }
175
176 @Test
177 public void flowRemoved() {
178 addFlowRule(1);
179 addFlowRule(2);
180 FlowRule rem1 = flowRule(1, 1);
181 providerSerivce.flowRemoved(rem1);
182 validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
183
184 providerSerivce.flowRemoved(rem1);
185 validateEvents();
186 }
187
188 private static class TestListener implements FlowRuleListener {
189 final List<FlowRuleEvent> events = new ArrayList<>();
190
191 @Override
192 public void event(FlowRuleEvent event) {
193 events.add(event);
194 }
195 }
196
197 private static class TestDeviceService implements DeviceService {
198
199 @Override
200 public int getDeviceCount() {
201 return 0;
202 }
203
204 @Override
205 public Iterable<Device> getDevices() {
206 return null;
207 }
208
209 @Override
210 public Device getDevice(DeviceId deviceId) {
211 return DEV;
212 }
213
214 @Override
215 public MastershipRole getRole(DeviceId deviceId) {
216 return null;
217 }
218
219 @Override
220 public List<Port> getPorts(DeviceId deviceId) {
221 return null;
222 }
223
224 @Override
225 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
226 return null;
227 }
228
229 @Override
230 public boolean isAvailable(DeviceId deviceId) {
231 return false;
232 }
233
234 @Override
235 public void addListener(DeviceListener listener) {
236 }
237
238 @Override
239 public void removeListener(DeviceListener listener) {
240 }
241
242 }
243
244 private class TestProvider extends AbstractProvider implements FlowRuleProvider {
245
246 protected TestProvider(ProviderId id) {
247 super(PID);
248 }
249
250 @Override
251 public void applyFlowRule(FlowRule... flowRules) {
252 }
253
254 @Override
255 public void removeFlowRule(FlowRule... flowRules) {
256 }
257
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700258 }
259
260 private class TestSelector implements TrafficSelector {
261
262 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700263 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700264
265 public TestSelector(int val) {
266 testval = val;
267 }
268
269 @Override
270 public List<Criterion> criteria() {
271 return null;
272 }
273
274 @Override
275 public int hashCode() {
276 return testval;
277 }
278
279 @Override
280 public boolean equals(Object o) {
281 if (o instanceof TestSelector) {
282 return this.testval == ((TestSelector) o).testval;
283 }
284 return false;
285 }
286 }
287
288 private class TestTreatment implements TrafficTreatment {
289
290 //for controlling hashcode uniqueness;
alshabib97044902014-09-18 14:52:16 -0700291 private final int testval;
Ayaka Koshibeb55524f2014-09-18 09:59:24 -0700292
293 public TestTreatment(int val) {
294 testval = val;
295 }
296
297 @Override
298 public List<Instruction> instructions() {
299 return null;
300 }
301
302 @Override
303 public int hashCode() {
304 return testval;
305 }
306
307 @Override
308 public boolean equals(Object o) {
309 if (o instanceof TestTreatment) {
310 return this.testval == ((TestTreatment) o).testval;
311 }
312 return false;
313 }
314
315 }
316
317}