blob: 1cedd4ae92ea20525a0531d18d4c309a3ee8bf4d [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 Chiu93ce3e82017-02-18 14:28:22 -050053import org.onosproject.net.flow.TrafficSelector;
54import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
55import org.onosproject.net.flowobjective.ForwardingObjective;
56import org.onosproject.net.flowobjective.Objective;
yoonseon86bebed2017-02-03 15:23:57 -080057import org.onosproject.net.flow.FlowRule;
58import org.onosproject.net.flow.FlowRuleBatchOperation;
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
83public class VirtualNetworkPacketManagerTest extends VirtualNetworkTestUtil {
84
85 private static final int PROCESSOR_PRIORITY = 1;
86
87 private VirtualNetworkManager manager;
88 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
89 private CoreService coreService = new TestCoreService();
90 private TestableIntentService intentService = new FakeIntentManager();
91 private TestServiceDirectory testDirectory;
92 private EventDeliveryService eventDeliveryService;
93 private VirtualProviderManager providerRegistryService;
94
95 private VirtualNetwork vnet1;
96 private VirtualNetwork vnet2;
97
98 private VirtualPacketProvider provider = new TestPacketProvider();
99 private VirtualNetworkPacketStore packetStore = new SimpleVirtualPacketStore();
100
101 private VirtualNetworkPacketManager packetManager1;
102 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;
109
yoonseon322c9c32016-12-07 16:47:02 -0800110 @Before
111 public void setUp() throws TestUtils.TestUtilsException {
112 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
113
114 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
yoonseon86bebed2017-02-03 15:23:57 -0800115 StorageService storageService = new TestStorageService();
116 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;
122 manager.intentService = intentService;
123 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
124
yoonseon86bebed2017-02-03 15:23:57 -0800125 flowObjectiveStore = new SimpleVirtualFlowObjectiveStore();
126 TestUtils.setField(flowObjectiveStore, "storageService", storageService);
127 flowObjectiveStore.activate();
128 flowRuleStore = new SimpleVirtualFlowRuleStore();
129 flowRuleStore.activate();
130
yoonseon322c9c32016-12-07 16:47:02 -0800131 providerRegistryService = new VirtualProviderManager();
132 providerRegistryService.registerProvider(provider);
yoonseon86bebed2017-02-03 15:23:57 -0800133 providerRegistryService.registerProvider(flowRuleProvider);
yoonseon322c9c32016-12-07 16:47:02 -0800134
135 testDirectory = new TestServiceDirectory()
136 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
137 .add(CoreService.class, coreService)
138 .add(VirtualProviderRegistryService.class, providerRegistryService)
139 .add(EventDeliveryService.class, eventDeliveryService)
140 .add(ClusterService.class, new ClusterServiceAdapter())
yoonseon86bebed2017-02-03 15:23:57 -0800141 .add(VirtualNetworkFlowRuleStore.class, flowRuleStore)
142 .add(VirtualNetworkFlowObjectiveStore.class, flowObjectiveStore)
yoonseon322c9c32016-12-07 16:47:02 -0800143 .add(VirtualNetworkPacketStore.class, packetStore);
144 TestUtils.setField(manager, "serviceDirectory", testDirectory);
145
146 eventDeliveryService = new TestEventDispatcher();
147 NetTestTools.injectEventDispatcher(manager, eventDeliveryService);
148
149 manager.activate();
150
151 vnet1 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID1);
152 vnet2 = VirtualNetworkTestUtil.setupVirtualNetworkTopology(manager, TID2);
153
154 packetManager1 = new VirtualNetworkPacketManager(manager, vnet1.id());
155 packetManager2 = new VirtualNetworkPacketManager(manager, vnet2.id());
156 }
157
158 /**
159 * Tests the correct usage of addProcessor() for a outbound packet.
160 */
161 @Test
162 public void addProcessorTest() {
163 PacketProcessor testProcessor = new TestProcessor();
164 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
165
166 assertEquals("1 processor expected", 1,
167 packetManager1.getProcessors().size());
168 assertEquals("0 processor expected", 0,
169 packetManager2.getProcessors().size());
170
171 assertEquals("not equal packet processor", testProcessor,
172 packetManager1.getProcessors().get(0).processor());
173 assertEquals("not equal packet processor priority", PROCESSOR_PRIORITY,
174 packetManager1.getProcessors().get(0).priority());
175 }
176
177 /**
178 * Tests the correct usage of addProcessor() for a outbound packet.
179 */
180 @Test
181 public void removeProcessorTest() {
182 PacketProcessor testProcessor = new TestProcessor();
183 packetManager1.addProcessor(testProcessor, PROCESSOR_PRIORITY);
184
185 assertEquals("1 processor expected", 1,
186 packetManager1.getProcessors().size());
187 assertEquals("0 processor expected", 0,
188 packetManager2.getProcessors().size());
189
190 packetManager1.removeProcessor(testProcessor);
191
192 assertEquals("0 processor expected", 0,
193 packetManager1.getProcessors().size());
194 assertEquals("0 processor expected", 0,
195 packetManager2.getProcessors().size());
196 }
197
198 /**
199 * Tests the correct usage of emit() for a outbound packet.
200 */
201 @Test
202 public void emitTest() {
203 OutboundPacket packet =
204 new DefaultOutboundPacket(VDID1, DefaultTrafficTreatment.emptyTreatment(), ByteBuffer.allocate(5));
205 packetManager1.emit(packet);
206 assertEquals("Packet not emitted correctly", packet, emittedPacket);
207 }
208
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500209 /**
210 * Tests the addition and removal of packet requests for a device.
211 *
212 * @throws TestUtils.TestUtilsException
213 */
214 @Test
215 public void requestAndCancelPacketsForDeviceTest() throws TestUtils.TestUtilsException {
216 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
217 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
218 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
219 Optional<DeviceId> optionalDeviceId = Optional.of(VDID3);
220
221 // add first request
222 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
223 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
224 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
225
226 // add same request as first
227 packetManager1.requestPackets(ts, CONTROL, appId, optionalDeviceId);
228 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
229 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, ADD);
230
231 // add second request
232 packetManager1.requestPackets(ts, REACTIVE, appId, optionalDeviceId);
233 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
234 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, ADD);
235
236 // cancel second request
237 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
238 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
239 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
240
241 // cancel second request again
242 packetManager1.cancelPackets(ts, REACTIVE, appId, optionalDeviceId);
243 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
244 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, REACTIVE, REMOVE);
245
246 // cancel first request
247 packetManager1.cancelPackets(ts, CONTROL, appId, optionalDeviceId);
248 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
249 testFlowObjectiveService.validateObjectiveForDevice(VDID3, ts, CONTROL, REMOVE);
250 }
251
252 /**
253 * Tests the addition and removal of packet requests for all devices in a virtual
254 * network.
255 *
256 * @throws TestUtils.TestUtilsException
257 */
258 @Test
259 public void requestAndCancelPacketsForVnetTest() throws TestUtils.TestUtilsException {
260 TestFlowObjectiveService testFlowObjectiveService = new TestFlowObjectiveService();
261 TestUtils.setField(packetManager1, "objectiveService", testFlowObjectiveService);
262 TrafficSelector ts = DefaultTrafficSelector.emptySelector();
263 Set<VirtualDevice> vnet1Devices = manager.getVirtualDevices(vnet1.id());
264
265 // add first request
266 packetManager1.requestPackets(ts, CONTROL, appId);
267 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
268 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
269
270 // add same request as first
271 packetManager1.requestPackets(ts, CONTROL, appId);
272 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
273 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, ADD);
274
275 // add second request
276 packetManager1.requestPackets(ts, REACTIVE, appId);
277 assertEquals("2 packets expected", 2, packetManager1.getRequests().size());
278 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, ADD);
279
280 // cancel second request
281 packetManager1.cancelPackets(ts, REACTIVE, appId);
282 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
283 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
284
285 // cancel second request again
286 packetManager1.cancelPackets(ts, REACTIVE, appId);
287 assertEquals("1 packet expected", 1, packetManager1.getRequests().size());
288 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, REACTIVE, REMOVE);
289
290 // cancel first request
291 packetManager1.cancelPackets(ts, CONTROL, appId);
292 assertEquals("0 packet expected", 0, packetManager1.getRequests().size());
293 testFlowObjectiveService.validateObjectives(vnet1Devices, ts, CONTROL, REMOVE);
294 }
295
yoonseon322c9c32016-12-07 16:47:02 -0800296 private static OutboundPacket emittedPacket = null;
297
298 /**
299 * Core service test class.
300 */
301 private class TestCoreService extends CoreServiceAdapter {
302
303 @Override
304 public IdGenerator getIdGenerator(String topic) {
305 return new IdGenerator() {
306 private AtomicLong counter = new AtomicLong(0);
307
308 @Override
309 public long getNewId() {
310 return counter.getAndIncrement();
311 }
312 };
313 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500314
315 @Override
316 public ApplicationId registerApplication(String name) {
317 return appId;
318 }
yoonseon322c9c32016-12-07 16:47:02 -0800319 }
320
321 private class TestPacketProvider extends AbstractVirtualProvider
322 implements VirtualPacketProvider {
323
324 /**
325 * Creates a provider with the supplied identifier.
326 */
327 protected TestPacketProvider() {
328 super(new ProviderId("test-packet",
329 "org.onosproject.virtual.test-packet"));
330 }
331
332 @Override
333 public void emit(NetworkId networkId, OutboundPacket packet) {
334 emittedPacket = packet;
335 }
yoonseonfb4a1db2017-01-31 11:38:30 -0800336
337 @Override
338 public void startPacketHandling() {
339
340 }
yoonseon322c9c32016-12-07 16:47:02 -0800341 }
342
343 private class TestProcessor implements PacketProcessor {
344
345 @Override
346 public void process(PacketContext context) {
347
348 }
349 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500350
351 private class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
352 // track objectives received for each device
353 private final Map<DeviceId, Set<ForwardingObjective>> deviceFwdObjs = new HashMap<>();
354
355 @Override
356 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
357 deviceFwdObjs.compute(deviceId, (deviceId1, forwardingObjectives) -> {
358 if (forwardingObjectives == null) {
359 return Sets.newHashSet(forwardingObjective);
360 }
361 forwardingObjectives.add(forwardingObjective);
362 return forwardingObjectives;
363 }
364 );
365 }
366
367 private void validateObjectives(Set<VirtualDevice> vdevs, TrafficSelector ts,
368 PacketPriority pp, Objective.Operation op) {
369 assertNotNull("set of devices must not be null", vdevs);
370 for (VirtualDevice vdev: vdevs) {
371 assertTrue("Forwarding objective must exist for device " + vdev.id(),
372 deviceHasObjective(vdev.id(), ts, pp, op));
373 }
374 }
375
376 private void validateObjectiveForDevice(DeviceId deviceId, TrafficSelector ts,
377 PacketPriority pp, Objective.Operation op) {
378 assertNotNull("deviceId must not be null", deviceId);
379 assertTrue("Forwarding objective must exist for device " + deviceId,
380 deviceHasObjective(deviceId, ts, pp, op));
381 }
382
383 private boolean deviceHasObjective(DeviceId deviceId, TrafficSelector ts,
384 PacketPriority pp, Objective.Operation op) {
385 Set<ForwardingObjective> fos = deviceFwdObjs.get(deviceId);
386 if (fos != null) {
387 for (ForwardingObjective fo: fos) {
388 if (fo.selector().equals(ts)
389 && fo.priority() == pp.priorityValue()
390 && fo.op().equals(op)) {
391 return true;
392 }
393 }
394 }
395 return false;
396 }
397 }
yoonseon86bebed2017-02-03 15:23:57 -0800398
399 private class TestFlowRuleProvider extends AbstractVirtualProvider
400 implements VirtualFlowRuleProvider {
401
402 protected TestFlowRuleProvider() {
403 super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
404 }
405
406 @Override
407 public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
408
409 }
410
411 @Override
412 public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
413
414 }
415
416 @Override
417 public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
418
419 }
420 }
Claudine Chiu93ce3e82017-02-18 14:28:22 -0500421}