blob: 5684a729dec9a7601d5c9f61dfb5a45e45f7710e [file] [log] [blame]
yoonseon322c9c32016-12-07 16:47:02 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
yoonseon322c9c32016-12-07 16:47:02 -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 */
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;
Ray Milkey7bf273c2017-09-27 16:15:15 -070054import org.onosproject.net.flow.oldbatch.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.packet.DefaultOutboundPacket;
60import org.onosproject.net.packet.OutboundPacket;
61import org.onosproject.net.packet.PacketContext;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050062import org.onosproject.net.packet.PacketPriority;
yoonseon322c9c32016-12-07 16:47:02 -080063import org.onosproject.net.packet.PacketProcessor;
64import org.onosproject.net.provider.ProviderId;
yoonseon86bebed2017-02-03 15:23:57 -080065import org.onosproject.store.service.StorageService;
yoonseon322c9c32016-12-07 16:47:02 -080066import org.onosproject.store.service.TestStorageService;
67
68import java.nio.ByteBuffer;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050069import java.util.HashMap;
70import java.util.Map;
71import java.util.Optional;
72import java.util.Set;
yoonseon322c9c32016-12-07 16:47:02 -080073import java.util.concurrent.atomic.AtomicLong;
74
75import static org.junit.Assert.*;
Claudine Chiu93ce3e82017-02-18 14:28:22 -050076import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
77import static org.onosproject.net.flowobjective.Objective.Operation.REMOVE;
78import static org.onosproject.net.packet.PacketPriority.CONTROL;
79import static org.onosproject.net.packet.PacketPriority.REACTIVE;
yoonseon322c9c32016-12-07 16:47:02 -080080
Claudine Chiu1f036b82017-03-09 16:45:56 -050081/**
82 * Junit tests for VirtualNetworkPacketManager using SimpleVirtualPacketStore.
83 */
yoonseon322c9c32016-12-07 16:47:02 -080084public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
85
86 private static final int PROCESSOR_PRIORITY = 1;
87
Claudine Chiu1f036b82017-03-09 16:45:56 -050088 protected VirtualNetworkManager manager;
89 protected DistributedVirtualNetworkStore virtualNetworkManagerStore;
yoonseon322c9c32016-12-07 16:47:02 -080090 private CoreService coreService = new TestCoreService();
Claudine Chiu1f036b82017-03-09 16:45:56 -050091 protected TestServiceDirectory testDirectory;
yoonseon322c9c32016-12-07 16:47:02 -080092 private EventDeliveryService eventDeliveryService;
93 private VirtualProviderManager providerRegistryService;
94
95 private VirtualNetwork vnet1;
96 private VirtualNetwork vnet2;
97
98 private VirtualPacketProvider provider = new TestPacketProvider();
Claudine Chiu1f036b82017-03-09 16:45:56 -050099 protected VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
yoonseon322c9c32016-12-07 16:47:02 -0800100
Claudine Chiu1f036b82017-03-09 16:45:56 -0500101 protected VirtualNetworkPacketManager packetManager1;
yoonseon322c9c32016-12-07 16:47:02 -0800102 private VirtualNetworkPacketManager packetManager2;
103
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500104 private ApplicationId appId = new TestApplicationId("VirtualPacketManagerTest");
105
yoonseon86bebed2017-02-03 15:23:57 -0800106 private VirtualFlowRuleProvider flowRuleProvider = new TestFlowRuleProvider();
107 private SimpleVirtualFlowRuleStore flowRuleStore;
108 private SimpleVirtualFlowObjectiveStore flowObjectiveStore;
Claudine Chiu1f036b82017-03-09 16:45:56 -0500109 protected StorageService storageService = new TestStorageService();
yoonseon86bebed2017-02-03 15:23:57 -0800110
yoonseon322c9c32016-12-07 16:47:02 -0800111 @Before
112 public void setUp() throws TestUtils.TestUtilsException {
113 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
114
115 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
yoonseon86bebed2017-02-03 15:23:57 -0800116 TestUtils.setField(virtualNetworkManagerStore, "storageService", storageService);
yoonseon322c9c32016-12-07 16:47:02 -0800117 virtualNetworkManagerStore.activate();
118
119 manager = new VirtualNetworkManager();
120 manager.store = virtualNetworkManagerStore;
121 manager.coreService = coreService;
yoonseon322c9c32016-12-07 16:47:02 -0800122 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
123
yoonseon86bebed2017-02-03 15:23:57 -0800124 flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
125 TestUtils.setField(flowObjectiveStore, "storageService", storageService);
126 flowObjectiveStore.activate();
127 flowRuleStore = new SimpleVirtualFlowRuleStore();
128 flowRuleStore.activate();
129
yoonseon322c9c32016-12-07 16:47:02 -0800130 providerRegistryService = new VirtualProviderManager();
131 providerRegistryService.registerProvider(provider);
yoonseon86bebed2017-02-03 15:23:57 -0800132 providerRegistryService.registerProvider(flowRuleProvider);
yoonseon322c9c32016-12-07 16:47:02 -0800133
134 testDirectory = new TestServiceDirectory()
135 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
136 .add(CoreService.class, coreService)
137 .add(VirtualProviderRegistryService.class, providerRegistryService)
138 .add(EventDeliveryService.class, eventDeliveryService)
139 .add(ClusterService.class, new ClusterServiceAdapter())
yoonseon86bebed2017-02-03 15:23:57 -0800140 .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
141 .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
yoonseon322c9c32016-12-07 16:47:02 -0800142 .add(VirtualNetworkPacketStore.class, packetStore);
143 TestUtils.setField(manager, "serviceDirectory", testDirectory);
144
145 eventDeliveryService = new TestEventDispatcher();
146 NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
147
148 manager.activate();
149
150 vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
151 vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
152
153 packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
154 packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
155 }
156
157 /**
158 * Tests the correct usage of addProcessor() for a outbound packet.
159 */
160 @Test
161 public void addProcessorTest() {
162 PacketProcessor testProcessor = new TestProcessor();
163 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
164
165 assertEquals("1 processor expected", 1,
166 packetManager1.getProcessors().size());
167 assertEquals("0 processor expected", 0,
168 packetManager2.getProcessors().size());
169
170 assertEquals("not equal packet processor", testProcessor,
171 packetManager1.getProcessors().get(0).processor());
172 assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
173 packetManager1.getProcessors().get(0).priority());
174 }
175
176 /**
177 * Tests the correct usage of addProcessor() for a outbound packet.
178 */
179 @Test
180 public void removeProcessorTest() {
181 PacketProcessor testProcessor = new TestProcessor();
182 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
183
184 assertEquals("1 processor expected", 1,
185 packetManager1.getProcessors().size());
186 assertEquals("0 processor expected", 0,
187 packetManager2.getProcessors().size());
188
189 packetManager1.removeProcessor(testProcessor);
190
191 assertEquals("0 processor expected", 0,
192 packetManager1.getProcessors().size());
193 assertEquals("0 processor expected", 0,
194 packetManager2.getProcessors().size());
195 }
196
197 /**
198 * Tests the correct usage of emit() for a outbound packet.
199 */
200 @Test
201 public void emitTest() {
202 OutboundPacket packet =
203 new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
204 packetManager1.emit(packet);
205 assertEquals("Packet not emitted correctly", packet, emittedPacket);
206 }
207
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500208 /**
209 * Tests the addition and removal of packet requests for a device.
210 *
211 * @throws TestUtils.TestUtilsException
212 */
213 @Test
214 public void requestAndCancelPacketsForDeviceTest() throws TestUtils.TestUtilsException {
215 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
216 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
217 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
218 Optional<DeviceId> optionalDeviceId = Optional.of(VDID3);
219
220 // add first request
221 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
222 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
223 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
224
225 // add same request as first
226 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
227 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
228 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
229
230 // add second request
231 packetManager1.requestPackets(ts, REACTIVE, appId, optionalDeviceId);
232 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
233 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, ADD);
234
235 // cancel second request
236 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
237 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
238 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
239
240 // cancel second request again
241 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
242 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
243 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
244
245 // cancel first request
246 packetManager1.cancelPackets(ts, CONTROL, appId, optionalDeviceId);
247 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
248 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, REMOVE);
249 }
250
251 /**
252 * Tests the addition and removal of packet requests for all devices in a virtual
253 * network.
254 *
255 * @throws TestUtils.TestUtilsException
256 */
257 @Test
258 public void requestAndCancelPacketsForVnetTest() throws TestUtils.TestUtilsException {
259 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
260 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
261 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
262 Set<VirtualDevice> vnet1Devices = manager.getVirtualDevices(vnet1.id());
263
264 // add first request
265 packetManager1.requestPackets(ts, CONTROL, appId);
266 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
267 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
268
269 // add same request as first
270 packetManager1.requestPackets(ts, CONTROL, appId);
271 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
272 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
273
274 // add second request
275 packetManager1.requestPackets(ts, REACTIVE, appId);
276 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
277 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, ADD);
278
279 // cancel second request
280 packetManager1.cancelPackets(ts, REACTIVE, appId);
281 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
282 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
283
284 // cancel second request again
285 packetManager1.cancelPackets(ts, REACTIVE, appId);
286 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
287 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
288
289 // cancel first request
290 packetManager1.cancelPackets(ts, CONTROL, appId);
291 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
292 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, REMOVE);
293 }
294
Claudine Chiu1f036b82017-03-09 16:45:56 -0500295 protected OutboundPacket emittedPacket = null;
yoonseon322c9c32016-12-07 16:47:02 -0800296
297 /**
298 * Core service test class.
299 */
300 private class TestCoreService extends CoreServiceAdapter {
301
302 @Override
303 public IdGenerator getIdGenerator(String topic) {
304 return new IdGenerator() {
305 private AtomicLong counter = new AtomicLong(0);
306
307 @Override
308 public long getNewId() {
309 return counter.getAndIncrement();
310 }
311 };
312 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500313
314 @Override
315 public ApplicationId registerApplication(String name) {
316 return appId;
317 }
yoonseon322c9c32016-12-07 16:47:02 -0800318 }
319
320 private class TestPacketProvider extends AbstractVirtualProvider
321 implements VirtualPacketProvider {
322
323 /**
324 * Creates a provider with the supplied identifier.
325 */
326 protected TestPacketProvider() {
327 super(new ProviderId("test-packet",
328 "org.onosproject.virtual.test-packet"));
329 }
330
331 @Override
332 public void emit(NetworkId networkId, OutboundPacket packet) {
333 emittedPacket = packet;
334 }
yoonseonfb4a1db2017-01-31 11:38:30 -0800335
yoonseon322c9c32016-12-07 16:47:02 -0800336 }
337
338 private class TestProcessor implements PacketProcessor {
339
340 @Override
341 public void process(PacketContext context) {
342
343 }
344 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500345
346 private class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
347 // track objectives received for each device
348 private final Map<DeviceId, Set<ForwardingObjective>> deviceFwdObjs = new HashMap<>();
349
350 @Override
351 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
352 deviceFwdObjs.compute(deviceId, (deviceId1, forwardingObjectives) -> {
353 if (forwardingObjectives == null) {
354 return Sets.newHashSet(forwardingObjective);
355 }
356 forwardingObjectives.add(forwardingObjective);
357 return forwardingObjectives;
358 }
359 );
360 }
361
362 private void validateObjectives(Set<VirtualDevice> vdevs, TrafficSelector ts,
363 PacketPriority pp, Objective.Operation op) {
364 assertNotNull("set of devices must not be null", vdevs);
365 for (VirtualDevice vdev: vdevs) {
366 assertTrue("Forwarding objective must exist for device " + vdev.id(),
367 deviceHasObjective(vdev.id(), ts, pp, op));
368 }
369 }
370
371 private void validateObjectiveForDevice(DeviceId deviceId, TrafficSelector ts,
372 PacketPriority pp, Objective.Operation op) {
373 assertNotNull("deviceId must not be null", deviceId);
374 assertTrue("Forwarding objective must exist for device " + deviceId,
375 deviceHasObjective(deviceId, ts, pp, op));
376 }
377
378 private boolean deviceHasObjective(DeviceId deviceId, TrafficSelector ts,
379 PacketPriority pp, Objective.Operation op) {
380 Set<ForwardingObjective> fos = deviceFwdObjs.get(deviceId);
381 if (fos != null) {
382 for (ForwardingObjective fo: fos) {
383 if (fo.selector().equals(ts)
384 && fo.priority() == pp.priorityValue()
385 && fo.op().equals(op)) {
386 return true;
387 }
388 }
389 }
390 return false;
391 }
392 }
yoonseon86bebed2017-02-03 15:23:57 -0800393
394 private class TestFlowRuleProvider extends AbstractVirtualProvider
395 implements VirtualFlowRuleProvider {
396
397 protected TestFlowRuleProvider() {
398 super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
399 }
400
401 @Override
402 public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
403
404 }
405
406 @Override
407 public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
408
409 }
410
411 @Override
412 public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
413
414 }
415 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500416}