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