blob: fe923dc64e3f8e7cb92fbfac1b77d35048a92af8 [file] [log] [blame]
Ray Milkey2e78d902016-03-01 09:35:36 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Ray Milkey2e78d902016-03-01 09:35:36 -08003 *
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 */
16package org.onosproject.net.flowobjective.impl;
17
18import java.util.ArrayList;
19import java.util.List;
20
21import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.junit.TestUtils;
25import org.onlab.packet.ChassisId;
Ray Milkey2e78d902016-03-01 09:35:36 -080026import org.onosproject.net.DefaultAnnotations;
27import org.onosproject.net.DefaultDevice;
28import org.onosproject.net.Device;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.NetTestTools;
31import org.onosproject.net.behaviour.DefaultNextGroup;
32import org.onosproject.net.behaviour.NextGroup;
33import org.onosproject.net.behaviour.PipelinerAdapter;
34import org.onosproject.net.behaviour.PipelinerContext;
35import org.onosproject.net.device.DeviceEvent;
36import org.onosproject.net.device.DeviceListener;
37import org.onosproject.net.device.DeviceServiceAdapter;
38import org.onosproject.net.driver.AbstractDriverLoader;
39import org.onosproject.net.driver.Behaviour;
40import org.onosproject.net.driver.DefaultDriverData;
41import org.onosproject.net.driver.DefaultDriverHandler;
42import org.onosproject.net.driver.DefaultDriverProviderService;
43import org.onosproject.net.driver.Driver;
Ray Milkeyd931a9b2016-03-02 17:01:30 -080044import org.onosproject.net.driver.DriverAdapter;
Ray Milkey2e78d902016-03-01 09:35:36 -080045import org.onosproject.net.driver.DriverData;
46import org.onosproject.net.driver.DriverHandler;
Ray Milkeyd931a9b2016-03-02 17:01:30 -080047import org.onosproject.net.driver.DriverServiceAdapter;
Ray Milkey2e78d902016-03-01 09:35:36 -080048import org.onosproject.net.flow.DefaultTrafficSelector;
49import org.onosproject.net.flow.DefaultTrafficTreatment;
50import org.onosproject.net.flow.TrafficSelector;
51import org.onosproject.net.flow.TrafficTreatment;
52import org.onosproject.net.flow.criteria.Criteria;
53import org.onosproject.net.flowobjective.DefaultFilteringObjective;
54import org.onosproject.net.flowobjective.DefaultForwardingObjective;
55import org.onosproject.net.flowobjective.DefaultNextObjective;
56import org.onosproject.net.flowobjective.FilteringObjective;
57import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
58import org.onosproject.net.flowobjective.ForwardingObjective;
59import org.onosproject.net.flowobjective.NextObjective;
60import org.onosproject.net.flowobjective.ObjectiveEvent;
61import org.onosproject.net.intent.TestTools;
Ray Milkey2e78d902016-03-01 09:35:36 -080062
63import static org.hamcrest.CoreMatchers.hasItem;
64import static org.hamcrest.MatcherAssert.assertThat;
65import static org.hamcrest.Matchers.hasSize;
66import static org.hamcrest.Matchers.notNullValue;
67import static org.onlab.junit.TestUtils.TestUtilsException;
68
69/**
70 * Tests for the flow objective manager.
71 */
72public class FlowObjectiveManagerTest {
73
74 private static final int RETRY_MS = 250;
75 private FlowObjectiveManager manager;
76 DeviceId id1 = NetTestTools.did("d1");
77 DefaultDevice d1 = new DefaultDevice(NetTestTools.PID, id1, Device.Type.SWITCH,
78 "test", "1.0", "1.0",
79 "abacab", new ChassisId("c"),
80 DefaultAnnotations.EMPTY);
81
82 DeviceId id2 = NetTestTools.did("d2");
83 DefaultDevice d2 = new DefaultDevice(NetTestTools.PID, id2, Device.Type.SWITCH,
84 "test", "1.0", "1.0",
85 "abacab", new ChassisId("c"),
86 DefaultAnnotations.EMPTY);
87
88 List<String> filteringObjectives;
89 List<String> forwardingObjectives;
90 List<String> nextObjectives;
91
92 private class TestDeviceService extends DeviceServiceAdapter {
93
94 List<Device> deviceList;
95
96 TestDeviceService() {
97 deviceList = new ArrayList<>();
98
99 deviceList.add(d1);
100 }
101
102 @Override
103 public Iterable<Device> getDevices() {
104 return deviceList;
105 }
106
107 @Override
108 public boolean isAvailable(DeviceId deviceId) {
109 return true;
110 }
111 }
112
113 private class TestFlowObjectiveStore extends FlowObjectiveStoreAdapter {
114 @Override
115 public NextGroup getNextGroup(Integer nextId) {
116 if (nextId != 4) {
117 byte[] data = new byte[1];
118 data[0] = 5;
119 return new DefaultNextGroup(data);
120 } else {
121 return null;
122 }
123 }
124
125 }
126
127 private class TestDriversLoader extends AbstractDriverLoader implements DefaultDriverProviderService {
128 public TestDriversLoader() {
129 super("/onos-drivers.xml");
130 }
131 }
132
133 private class TestDriver extends DriverAdapter {
134
135 @Override
136 public boolean hasBehaviour(Class<? extends Behaviour> behaviourClass) {
137 return true;
138 }
139
140 @Override
141 @SuppressWarnings("unchecked")
142 public <T extends Behaviour> T createBehaviour(DriverData data, Class<T> behaviourClass) {
143 return (T) new TestPipeliner();
144 }
145
146 @Override
147 @SuppressWarnings("unchecked")
148 public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {
149 return (T) new TestPipeliner();
150 }
151
152 }
153
154 private class TestPipeliner extends PipelinerAdapter {
155 DeviceId deviceId;
156
157 @Override
158 public void init(DeviceId deviceId, PipelinerContext context) {
159 this.deviceId = deviceId;
160 }
161
162 @Override
163 public void filter(FilteringObjective filterObjective) {
164 filteringObjectives.add(deviceId.toString());
165 }
166
167 @Override
168 public void forward(ForwardingObjective forwardObjective) {
169 forwardingObjectives.add(deviceId.toString());
170 }
171
172 @Override
173 public void next(NextObjective nextObjective) {
174 nextObjectives.add(deviceId.toString());
175 }
176 }
177
178 private class TestDriverService extends DriverServiceAdapter {
179 @Override
180 public DriverHandler createHandler(DeviceId deviceId, String... credentials) {
181 Driver driver = new TestDriver();
182 return new DefaultDriverHandler(new DefaultDriverData(driver, id1));
183 }
184 }
185
186 @Before
187 public void initializeTest() {
188 manager = new FlowObjectiveManager();
189 manager.flowObjectiveStore = new TestFlowObjectiveStore();
Ray Milkey2e78d902016-03-01 09:35:36 -0800190 manager.deviceService = new TestDeviceService();
191 manager.defaultDriverService = new TestDriversLoader();
192 manager.driverService = new TestDriverService();
193
194 filteringObjectives = new ArrayList<>();
195 forwardingObjectives = new ArrayList<>();
196 nextObjectives = new ArrayList<>();
197 manager.activate();
198 }
199
200 @After
201 public void tearDownTest() {
202 manager.deactivate();
203 manager = null;
204 filteringObjectives.clear();
205 forwardingObjectives.clear();
206 nextObjectives.clear();
207 }
208
209 /**
210 * Tests adding a forwarding objective.
211 */
212 @Test
213 public void forwardingObjective() {
214 TrafficSelector selector = DefaultTrafficSelector.emptySelector();
215 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
216 ForwardingObjective forward =
217 DefaultForwardingObjective.builder()
218 .fromApp(NetTestTools.APP_ID)
219 .withFlag(ForwardingObjective.Flag.SPECIFIC)
220 .withSelector(selector)
221 .withTreatment(treatment)
222 .makePermanent()
223 .add();
224
225 manager.forward(id1, forward);
226
227 TestTools.assertAfter(RETRY_MS, () ->
228 assertThat(forwardingObjectives, hasSize(1)));
229
230 assertThat(forwardingObjectives, hasItem("of:d1"));
231 assertThat(filteringObjectives, hasSize(0));
232 assertThat(nextObjectives, hasSize(0));
233 }
234
235 /**
236 * Tests adding a filtering objective.
237 */
238 @Test
239 public void filteringObjective() {
240 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
241 FilteringObjective filter =
242 DefaultFilteringObjective.builder()
243 .fromApp(NetTestTools.APP_ID)
244 .withMeta(treatment)
245 .makePermanent()
246 .deny()
247 .addCondition(Criteria.matchEthType(12))
248 .add();
249
250 manager.activate();
251 manager.filter(id1, filter);
252
253 TestTools.assertAfter(RETRY_MS, () ->
254 assertThat(filteringObjectives, hasSize(1)));
255
256 assertThat(forwardingObjectives, hasSize(0));
257 assertThat(filteringObjectives, hasItem("of:d1"));
258 assertThat(nextObjectives, hasSize(0));
259 }
260
261 /**
262 * Tests adding a next objective.
263 */
264 @Test
265 public void nextObjective() {
266 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
267 NextObjective next =
268 DefaultNextObjective.builder()
269 .withId(manager.allocateNextId())
270 .addTreatment(treatment)
271 .withType(NextObjective.Type.BROADCAST)
272 .fromApp(NetTestTools.APP_ID)
273 .makePermanent()
274 .add();
275
276 manager.next(id1, next);
277
278 TestTools.assertAfter(RETRY_MS, () ->
279 assertThat(nextObjectives, hasSize(1)));
280
281 assertThat(forwardingObjectives, hasSize(0));
282 assertThat(filteringObjectives, hasSize(0));
283 assertThat(nextObjectives, hasItem("of:d1"));
284 }
285
286 /**
287 * Tests adding a pending forwarding objective.
288 *
289 * @throws TestUtilsException if lookup of a field fails
290 */
291 @Test
292 public void pendingForwardingObjective() throws TestUtilsException {
293 TrafficSelector selector = DefaultTrafficSelector.emptySelector();
294 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
295
296 ForwardingObjective forward4 =
297 DefaultForwardingObjective.builder()
298 .fromApp(NetTestTools.APP_ID)
299 .withFlag(ForwardingObjective.Flag.SPECIFIC)
300 .withSelector(selector)
301 .withTreatment(treatment)
302 .makePermanent()
303 .nextStep(4)
304 .add();
305 ForwardingObjective forward5 =
306 DefaultForwardingObjective.builder()
307 .fromApp(NetTestTools.APP_ID)
308 .withFlag(ForwardingObjective.Flag.SPECIFIC)
309 .withSelector(selector)
310 .withTreatment(treatment)
311 .makePermanent()
312 .nextStep(5)
313 .add();
314
315 // multiple pending forwards should be combined
316 manager.forward(id1, forward4);
317 manager.forward(id1, forward4);
318 manager.forward(id1, forward5);
319
320
321 // 1 should be complete, 1 pending
322 TestTools.assertAfter(RETRY_MS, () ->
323 assertThat(forwardingObjectives, hasSize(1)));
324
325 assertThat(forwardingObjectives, hasItem("of:d1"));
326 assertThat(filteringObjectives, hasSize(0));
327 assertThat(nextObjectives, hasSize(0));
328
329 // Now send events to trigger the objective still in the queue
330 ObjectiveEvent event1 = new ObjectiveEvent(ObjectiveEvent.Type.ADD, 4);
331 FlowObjectiveStoreDelegate delegate = TestUtils.getField(manager, "delegate");
332 delegate.notify(event1);
333
334 // all should be processed now
335 TestTools.assertAfter(RETRY_MS, () ->
336 assertThat(forwardingObjectives, hasSize(2)));
337 assertThat(forwardingObjectives, hasItem("of:d1"));
338 assertThat(filteringObjectives, hasSize(0));
339 assertThat(nextObjectives, hasSize(0));
340 }
341
342 /**
343 * Tests receipt of a device up event.
344 *
345 * @throws TestUtilsException if lookup of a field fails
346 */
347 @Test
348 public void deviceUpEvent() throws TestUtilsException {
349 TrafficSelector selector = DefaultTrafficSelector.emptySelector();
350 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
351
352 DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, d2);
353 DeviceListener listener = TestUtils.getField(manager, "deviceListener");
354 assertThat(listener, notNullValue());
355
356 listener.event(event);
357
358 ForwardingObjective forward =
359 DefaultForwardingObjective.builder()
360 .fromApp(NetTestTools.APP_ID)
361 .withFlag(ForwardingObjective.Flag.SPECIFIC)
362 .withSelector(selector)
363 .withTreatment(treatment)
364 .makePermanent()
365 .add();
366 manager.forward(id2, forward);
367
368 // new device should have an objective now
369 TestTools.assertAfter(RETRY_MS, () ->
370 assertThat(forwardingObjectives, hasSize(1)));
371
372 assertThat(forwardingObjectives, hasItem("of:d2"));
373 assertThat(filteringObjectives, hasSize(0));
374 assertThat(nextObjectives, hasSize(0));
375 }
Ray Milkey2e78d902016-03-01 09:35:36 -0800376}