Ray Milkey
Committed by Gerrit Code Review

Unit tests for flow objective manager

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