blob: 184a30e96738d391fc021218a3ea3f892bc40491 [file] [log] [blame]
yoonseon322c9c32016-12-07 16:47:02 -08001/*
2 * Copyright 2017-present 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
17package org.onosproject.incubator.net.virtual.impl;
18
Claudine Chiu93ce3e82017-02-18 14:28:22 -050019import com.google.common.collect.Sets;
yoonseon322c9c32016-12-07 16:47:02 -080020import org.junit.Before;
21import org.junit.Test;
22import org.onlab.junit.TestUtils;
23import org.onlab.osgi.TestServiceDirectory;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050024import org.onosproject.TestApplicationId;
yoonseon322c9c32016-12-07 16:47:02 -080025import org.onosproject.cluster.ClusterService;
26import org.onosproject.cluster.ClusterServiceAdapter;
27import org.onosproject.common.event.impl.TestEventDispatcher;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050028import org.onosproject.core.ApplicationId;
yoonseon322c9c32016-12-07 16:47:02 -080029import org.onosproject.core.CoreService;
30import org.onosproject.core.CoreServiceAdapter;
31import org.onosproject.core.IdGenerator;
32import org.onosproject.event.EventDeliveryService;
33import org.onosproject.incubator.net.virtual.NetworkId;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050034import org.onosproject.incubator.net.virtual.VirtualDevice;
yoonseon322c9c32016-12-07 16:47:02 -080035import org.onosproject.incubator.net.virtual.VirtualNetwork;
yoonseon86bebed2017-02-03 15:23:57 -080036import org.onosproject.incubator.net.virtual.VirtualNetworkFlowObjectiveStore;
37import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
yoonseon322c9c32016-12-07 16:47:02 -080038import org.onosproject.incubator.net.virtual.VirtualNetworkPacketStore;
39import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
40import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
41import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
yoonseon86bebed2017-02-03 15:23:57 -080042import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
yoonseon322c9c32016-12-07 16:47:02 -080043import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
44import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
45import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
yoonseon86bebed2017-02-03 15:23:57 -080046import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowObjectiveStore;
47import org.onosproject.incubator.store.virtual.impl.SimpleVirtualFlowRuleStore;
yoonseon322c9c32016-12-07 16:47:02 -080048import org.onosproject.incubator.store.virtual.impl.SimpleVirtualPacketStore;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050049import org.onosproject.net.DeviceId;
yoonseon322c9c32016-12-07 16:47:02 -080050import org.onosproject.net.NetTestTools;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050051import org.onosproject.net.flow.DefaultTrafficSelector;
yoonseon322c9c32016-12-07 16:47:02 -080052import org.onosproject.net.flow.DefaultTrafficTreatment;
Claudine Chiu1f036b82017-03-09 16:45:56 -050053import org.onosproject.net.flow.FlowRule;
54import org.onosproject.net.flow.FlowRuleBatchOperation;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050055import org.onosproject.net.flow.TrafficSelector;
56import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
57import org.onosproject.net.flowobjective.ForwardingObjective;
58import org.onosproject.net.flowobjective.Objective;
yoonseon322c9c32016-12-07 16:47:02 -080059import org.onosproject.net.intent.FakeIntentManager;
60import org.onosproject.net.intent.TestableIntentService;
61import org.onosproject.net.packet.DefaultOutboundPacket;
62import org.onosproject.net.packet.OutboundPacket;
63import org.onosproject.net.packet.PacketContext;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050064import org.onosproject.net.packet.PacketPriority;
yoonseon322c9c32016-12-07 16:47:02 -080065import org.onosproject.net.packet.PacketProcessor;
66import org.onosproject.net.provider.ProviderId;
yoonseon86bebed2017-02-03 15:23:57 -080067import org.onosproject.store.service.StorageService;
yoonseon322c9c32016-12-07 16:47:02 -080068import org.onosproject.store.service.TestStorageService;
69
70import java.nio.ByteBuffer;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050071import java.util.HashMap;
72import java.util.Map;
73import java.util.Optional;
74import java.util.Set;
yoonseon322c9c32016-12-07 16:47:02 -080075import java.util.concurrent.atomic.AtomicLong;
76
77import static org.junit.Assert.*;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050078import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
79import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
80import static org.onosproject.net.packet.PacketPriority.CONTROL;
81import static org.onosproject.net.packet.PacketPriority.REACTIVE;
yoonseon322c9c32016-12-07 16:47:02 -080082
Claudine Chiu1f036b82017-03-09 16:45:56 -050083/**
84 * Junit tests for VirtualNetworkPacketManager using SimpleVirtualPacketStore.
85 */
yoonseon322c9c32016-12-07 16:47:02 -080086public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
87
88 private static final int PROCESSOR_PRIORITY = 1;
89
Claudine Chiu1f036b82017-03-09 16:45:56 -050090 protected VirtualNetworkManager manager;
91 protected DistributedVirtualNetworkStore virtualNetworkManagerStore;
yoonseon322c9c32016-12-07 16:47:02 -080092 private CoreService coreService = new TestCoreService();
93 private TestableIntentService intentService = new FakeIntentManager();
Claudine Chiu1f036b82017-03-09 16:45:56 -050094 protected TestServiceDirectory testDirectory;
yoonseon322c9c32016-12-07 16:47:02 -080095 private EventDeliveryService eventDeliveryService;
96 private VirtualProviderManager providerRegistryService;
97
98 private VirtualNetwork vnet1;
99 private VirtualNetwork vnet2;
100
101 private VirtualPacketProvider provider = new TestPacketProvider();
Claudine Chiu1f036b82017-03-09 16:45:56 -0500102 protected VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
yoonseon322c9c32016-12-07 16:47:02 -0800103
Claudine Chiu1f036b82017-03-09 16:45:56 -0500104 protected VirtualNetworkPacketManager packetManager1;
yoonseon322c9c32016-12-07 16:47:02 -0800105 private VirtualNetworkPacketManager packetManager2;
106
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500107 private ApplicationId appId = new TestApplicationId("VirtualPacketManagerTest");
108
yoonseon86bebed2017-02-03 15:23:57 -0800109 private VirtualFlowRuleProvider flowRuleProvider = new TestFlowRuleProvider();
110 private SimpleVirtualFlowRuleStore flowRuleStore;
111 private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
Claudine Chiu1f036b82017-03-09 16:45:56 -0500112 protected StorageService storageService = new TestStorageService();
yoonseon86bebed2017-02-03 15:23:57 -0800113
yoonseon322c9c32016-12-07 16:47:02 -0800114 @Before
115 public void setUp() throws TestUtils.TestUtilsException {
116 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
117
118 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
yoonseon86bebed2017-02-03 15:23:57 -0800119 TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
yoonseon322c9c32016-12-07 16:47:02 -0800120 virtualNetworkManagerStore.activate();
121
122 manager = new VirtualNetworkManager();
123 manager.store = virtualNetworkManagerStore;
124 manager.coreService = coreService;
125 manager.intentService = intentService;
126 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
127
yoonseon86bebed2017-02-03 15:23:57 -0800128 flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
129 TestUtils.setField(flowObjectiveStore, "storageService", storageService);
130 flowObjectiveStore.activate();
131 flowRuleStore = new SimpleVirtualFlowRuleStore();
132 flowRuleStore.activate();
133
yoonseon322c9c32016-12-07 16:47:02 -0800134 providerRegistryService = new VirtualProviderManager();
135 providerRegistryService.registerProvider(provider);
yoonseon86bebed2017-02-03 15:23:57 -0800136 providerRegistryService.registerProvider(flowRuleProvider);
yoonseon322c9c32016-12-07 16:47:02 -0800137
138 testDirectory = new TestServiceDirectory()
139 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
140 .add(CoreService.class, coreService)
141 .add(VirtualProviderRegistryService.class, providerRegistryService)
142 .add(EventDeliveryService.class, eventDeliveryService)
143 .add(ClusterService.class, new ClusterServiceAdapter())
yoonseon86bebed2017-02-03 15:23:57 -0800144 .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
145 .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
yoonseon322c9c32016-12-07 16:47:02 -0800146 .add(VirtualNetworkPacketStore.class, packetStore);
147 TestUtils.setField(manager, "serviceDirectory", testDirectory);
148
149 eventDeliveryService = new TestEventDispatcher();
150 NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
151
152 manager.activate();
153
154 vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
155 vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
156
157 packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
158 packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
159 }
160
161 /**
162 * Tests the correct usage of addProcessor() for a outbound packet.
163 */
164 @Test
165 public void addProcessorTest() {
166 PacketProcessor testProcessor = new TestProcessor();
167 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
168
169 assertEquals("1 processor expected", 1,
170 packetManager1.getProcessors().size());
171 assertEquals("0 processor expected", 0,
172 packetManager2.getProcessors().size());
173
174 assertEquals("not equal packet processor", testProcessor,
175 packetManager1.getProcessors().get(0).processor());
176 assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
177 packetManager1.getProcessors().get(0).priority());
178 }
179
180 /**
181 * Tests the correct usage of addProcessor() for a outbound packet.
182 */
183 @Test
184 public void removeProcessorTest() {
185 PacketProcessor testProcessor = new TestProcessor();
186 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
187
188 assertEquals("1 processor expected", 1,
189 packetManager1.getProcessors().size());
190 assertEquals("0 processor expected", 0,
191 packetManager2.getProcessors().size());
192
193 packetManager1.removeProcessor(testProcessor);
194
195 assertEquals("0 processor expected", 0,
196 packetManager1.getProcessors().size());
197 assertEquals("0 processor expected", 0,
198 packetManager2.getProcessors().size());
199 }
200
201 /**
202 * Tests the correct usage of emit() for a outbound packet.
203 */
204 @Test
205 public void emitTest() {
206 OutboundPacket packet =
207 new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
208 packetManager1.emit(packet);
209 assertEquals("Packet not emitted correctly", packet, emittedPacket);
210 }
211
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500212 /**
213 * Tests the addition and removal of packet requests for a device.
214 *
215 * @throws TestUtils.TestUtilsException
216 */
217 @Test
218 public void requestAndCancelPacketsForDeviceTest() throws TestUtils.TestUtilsException {
219 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
220 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
221 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
222 Optional<DeviceId> optionalDeviceId = Optional.of(VDID3);
223
224 // add first request
225 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
226 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
227 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
228
229 // add same request as first
230 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
231 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
232 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
233
234 // add second request
235 packetManager1.requestPackets(ts, REACTIVE, appId, optionalDeviceId);
236 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
237 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, ADD);
238
239 // cancel second request
240 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
241 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
242 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
243
244 // cancel second request again
245 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
246 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
247 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
248
249 // cancel first request
250 packetManager1.cancelPackets(ts, CONTROL, appId, optionalDeviceId);
251 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
252 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, REMOVE);
253 }
254
255 /**
256 * Tests the addition and removal of packet requests for all devices in a virtual
257 * network.
258 *
259 * @throws TestUtils.TestUtilsException
260 */
261 @Test
262 public void requestAndCancelPacketsForVnetTest() throws TestUtils.TestUtilsException {
263 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
264 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
265 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
266 Set<VirtualDevice> vnet1Devices = manager.getVirtualDevices(vnet1.id());
267
268 // add first request
269 packetManager1.requestPackets(ts, CONTROL, appId);
270 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
271 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
272
273 // add same request as first
274 packetManager1.requestPackets(ts, CONTROL, appId);
275 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
276 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
277
278 // add second request
279 packetManager1.requestPackets(ts, REACTIVE, appId);
280 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
281 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, ADD);
282
283 // cancel second request
284 packetManager1.cancelPackets(ts, REACTIVE, appId);
285 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
286 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
287
288 // cancel second request again
289 packetManager1.cancelPackets(ts, REACTIVE, appId);
290 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
291 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
292
293 // cancel first request
294 packetManager1.cancelPackets(ts, CONTROL, appId);
295 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
296 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, REMOVE);
297 }
298
Claudine Chiu1f036b82017-03-09 16:45:56 -0500299 protected OutboundPacket emittedPacket = null;
yoonseon322c9c32016-12-07 16:47:02 -0800300
301 /**
302 * Core service test class.
303 */
304 private class TestCoreService extends CoreServiceAdapter {
305
306 @Override
307 public IdGenerator getIdGenerator(String topic) {
308 return new IdGenerator() {
309 private AtomicLong counter = new AtomicLong(0);
310
311 @Override
312 public long getNewId() {
313 return counter.getAndIncrement();
314 }
315 };
316 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500317
318 @Override
319 public ApplicationId registerApplication(String name) {
320 return appId;
321 }
yoonseon322c9c32016-12-07 16:47:02 -0800322 }
323
324 private class TestPacketProvider extends AbstractVirtualProvider
325 implements VirtualPacketProvider {
326
327 /**
328 * Creates a provider with the supplied identifier.
329 */
330 protected TestPacketProvider() {
331 super(new ProviderId("test-packet",
332 "org.onosproject.virtual.test-packet"));
333 }
334
335 @Override
336 public void emit(NetworkId networkId, OutboundPacket packet) {
337 emittedPacket = packet;
338 }
yoonseonfb4a1db2017-01-31 11:38:30 -0800339
340 @Override
341 public void startPacketHandling() {
342
343 }
yoonseon322c9c32016-12-07 16:47:02 -0800344 }
345
346 private class TestProcessor implements PacketProcessor {
347
348 @Override
349 public void process(PacketContext context) {
350
351 }
352 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500353
354 private class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
355 // track objectives received for each device
356 private final Map<DeviceId, Set<ForwardingObjective>> deviceFwdObjs = new HashMap<>();
357
358 @Override
359 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
360 deviceFwdObjs.compute(deviceId, (deviceId1, forwardingObjectives) -> {
361 if (forwardingObjectives == null) {
362 return Sets.newHashSet(forwardingObjective);
363 }
364 forwardingObjectives.add(forwardingObjective);
365 return forwardingObjectives;
366 }
367 );
368 }
369
370 private void validateObjectives(Set<VirtualDevice> vdevs, TrafficSelector ts,
371 PacketPriority pp, Objective.Operation op) {
372 assertNotNull("set of devices must not be null", vdevs);
373 for (VirtualDevice vdev: vdevs) {
374 assertTrue("Forwarding objective must exist for device " + vdev.id(),
375 deviceHasObjective(vdev.id(), ts, pp, op));
376 }
377 }
378
379 private void validateObjectiveForDevice(DeviceId deviceId, TrafficSelector ts,
380 PacketPriority pp, Objective.Operation op) {
381 assertNotNull("deviceId must not be null", deviceId);
382 assertTrue("Forwarding objective must exist for device " + deviceId,
383 deviceHasObjective(deviceId, ts, pp, op));
384 }
385
386 private boolean deviceHasObjective(DeviceId deviceId, TrafficSelector ts,
387 PacketPriority pp, Objective.Operation op) {
388 Set<ForwardingObjective> fos = deviceFwdObjs.get(deviceId);
389 if (fos != null) {
390 for (ForwardingObjective fo: fos) {
391 if (fo.selector().equals(ts)
392 && fo.priority() == pp.priorityValue()
393 && fo.op().equals(op)) {
394 return true;
395 }
396 }
397 }
398 return false;
399 }
400 }
yoonseon86bebed2017-02-03 15:23:57 -0800401
402 private class TestFlowRuleProvider extends AbstractVirtualProvider
403 implements VirtualFlowRuleProvider {
404
405 protected TestFlowRuleProvider() {
406 super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
407 }
408
409 @Override
410 public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
411
412 }
413
414 @Override
415 public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
416
417 }
418
419 @Override
420 public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
421
422 }
423 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500424}