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