blob: 593c6d6896cf34010e4affabee870f3ae2c8fd58 [file] [log] [blame]
yoonseon6b972c32016-12-06 16:45:03 -08001/*
2 * Copyright 2016-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
19import com.google.common.collect.Lists;
20import com.google.common.collect.Sets;
21import com.google.common.util.concurrent.MoreExecutors;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25import org.onlab.junit.TestUtils;
26import org.onlab.osgi.ServiceDirectory;
27import org.onlab.osgi.TestServiceDirectory;
yoonseon6b972c32016-12-06 16:45:03 -080028import org.onosproject.TestApplicationId;
29import org.onosproject.common.event.impl.TestEventDispatcher;
30import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
32import org.onosproject.incubator.net.virtual.NetworkId;
33import org.onosproject.incubator.net.virtual.TenantId;
34import org.onosproject.incubator.net.virtual.VirtualDevice;
35import org.onosproject.incubator.net.virtual.VirtualLink;
36import org.onosproject.incubator.net.virtual.VirtualNetwork;
37import org.onosproject.incubator.net.virtual.VirtualNetworkFlowRuleStore;
38import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
39import org.onosproject.incubator.net.virtual.impl.provider.VirtualProviderManager;
40import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
41import org.onosproject.incubator.net.virtual.provider.VirtualFlowRuleProvider;
42import org.onosproject.incubator.net.virtual.provider.VirtualProviderRegistryService;
43import org.onosproject.incubator.store.virtual.impl.DistributedVirtualNetworkStore;
44import org.onosproject.net.ConnectPoint;
45import org.onosproject.net.DeviceId;
46import org.onosproject.net.Link;
47import org.onosproject.net.NetTestTools;
48import org.onosproject.net.PortNumber;
49import org.onosproject.net.TestDeviceParams;
50import org.onosproject.net.flow.DefaultFlowEntry;
51import org.onosproject.net.flow.DefaultFlowRule;
52import org.onosproject.net.flow.FlowEntry;
53import org.onosproject.net.flow.FlowId;
54import org.onosproject.net.flow.FlowRule;
55import org.onosproject.net.flow.FlowRuleBatchEntry;
56import org.onosproject.net.flow.FlowRuleBatchEvent;
57import org.onosproject.net.flow.FlowRuleBatchOperation;
58import org.onosproject.net.flow.FlowRuleEvent;
59import org.onosproject.net.flow.FlowRuleListener;
60import org.onosproject.net.flow.FlowRuleService;
61import org.onosproject.net.flow.FlowRuleStoreDelegate;
62import org.onosproject.net.flow.StoredFlowEntry;
63import org.onosproject.net.flow.TableStatisticsEntry;
64import org.onosproject.net.flow.TrafficSelector;
65import org.onosproject.net.flow.TrafficTreatment;
66import org.onosproject.net.flow.criteria.Criterion;
67import org.onosproject.net.flow.instructions.Instruction;
68import org.onosproject.net.flow.instructions.Instructions;
69import org.onosproject.net.intent.FakeIntentManager;
70import org.onosproject.net.intent.TestableIntentService;
71import org.onosproject.net.provider.ProviderId;
72import org.onosproject.store.service.TestStorageService;
73
74import java.util.ArrayList;
75import java.util.Collections;
76import java.util.HashSet;
77import java.util.List;
78import java.util.Set;
79import java.util.concurrent.ConcurrentHashMap;
80import java.util.concurrent.ConcurrentMap;
81
82import static org.junit.Assert.*;
83
84public class VirtualNetworkFlowRuleManagerTest extends TestDeviceParams {
85 private static final int TIMEOUT = 10;
86
87 private VirtualNetworkManager manager;
88 private DistributedVirtualNetworkStore virtualNetworkManagerStore;
89 private TestableIntentService intentService = new FakeIntentManager();
90 private ServiceDirectory testDirectory;
91 private VirtualNetworkFlowRuleStore flowRuleStore;
92 private VirtualProviderRegistryService providerRegistryService;
93
94 private VirtualNetworkFlowRuleManager vnetFlowRuleService1;
95 private VirtualNetworkFlowRuleManager vnetFlowRuleService2;
96
97 private VirtualFlowRuleProvider provider = new TestProvider();
98
99 protected TestFlowRuleListener listener1 = new TestFlowRuleListener();
100 protected TestFlowRuleListener listener2 = new TestFlowRuleListener();
101
102 private final TenantId tid1 = TenantId.tenantId("tid1");
103 private final TenantId tid2 = TenantId.tenantId("tid2");
104
105 private VirtualNetwork vnet1;
106 private VirtualNetwork vnet2;
107
108 private ApplicationId appId;
109
yoonseon6b972c32016-12-06 16:45:03 -0800110 @Before
111 public void setUp() throws Exception {
112 virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
113
114 CoreService coreService = new TestCoreService();
yoonseonc6a69272017-01-12 18:22:20 -0800115 TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
yoonseon6b972c32016-12-06 16:45:03 -0800116 TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
117 virtualNetworkManagerStore.activate();
118
119 flowRuleStore = new TestVirtualFlowRuleStore();
120
121 providerRegistryService = new VirtualProviderManager();
122 providerRegistryService.registerProvider(provider);
123
124 manager = new VirtualNetworkManager();
125 manager.store = virtualNetworkManagerStore;
126 manager.intentService = intentService;
127 TestUtils.setField(manager, "coreService", coreService);
128 NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
yoonseon6b972c32016-12-06 16:45:03 -0800129
130 appId = new TestApplicationId("FlowRuleManagerTest");
131
yoonseon6b972c32016-12-06 16:45:03 -0800132 testDirectory = new TestServiceDirectory()
133 .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
134 .add(CoreService.class, coreService)
135 .add(VirtualProviderRegistryService.class, providerRegistryService)
136 .add(VirtualNetworkFlowRuleStore.class, flowRuleStore);
yoonseonc6a69272017-01-12 18:22:20 -0800137 TestUtils.setField(manager, "serviceDirectory", testDirectory);
yoonseon6b972c32016-12-06 16:45:03 -0800138
yoonseonc6a69272017-01-12 18:22:20 -0800139 manager.activate();
yoonseon6b972c32016-12-06 16:45:03 -0800140
141 vnet1 = setupVirtualNetworkTopology(tid1);
142 vnet2 = setupVirtualNetworkTopology(tid2);
143
yoonseonc6a69272017-01-12 18:22:20 -0800144 vnetFlowRuleService1 = new VirtualNetworkFlowRuleManager(manager, vnet1.id());
145 vnetFlowRuleService2 = new VirtualNetworkFlowRuleManager(manager, vnet2.id());
yoonseon6b972c32016-12-06 16:45:03 -0800146 vnetFlowRuleService1.addListener(listener1);
147
148 vnetFlowRuleService1.operationsService = MoreExecutors.newDirectExecutorService();
149 vnetFlowRuleService2.operationsService = MoreExecutors.newDirectExecutorService();
150 vnetFlowRuleService1.deviceInstallers = MoreExecutors.newDirectExecutorService();
151 vnetFlowRuleService2.deviceInstallers = MoreExecutors.newDirectExecutorService();
152 }
153
154 @After
155 public void tearDown() {
156 manager.deactivate();
157 virtualNetworkManagerStore.deactivate();
158 }
159
160 /**
161 * Method to create the virtual network for further testing.
162 *
163 * @return virtual network
164 */
165 private VirtualNetwork setupVirtualNetworkTopology(TenantId tenantId) {
166 manager.registerTenantId(tenantId);
167 VirtualNetwork virtualNetwork = manager.createVirtualNetwork(tenantId);
168
169 VirtualDevice virtualDevice1 =
170 manager.createVirtualDevice(virtualNetwork.id(), DID1);
171 VirtualDevice virtualDevice2 =
172 manager.createVirtualDevice(virtualNetwork.id(), DID2);
173 VirtualDevice virtualDevice3 =
174 manager.createVirtualDevice(virtualNetwork.id(), DID3);
175 VirtualDevice virtualDevice4 =
176 manager.createVirtualDevice(virtualNetwork.id(), DID4);
177
178 ConnectPoint cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
179 manager.createVirtualPort(virtualNetwork.id(), cp1.deviceId(), cp1.port(), cp1);
180
181 ConnectPoint cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
182 manager.createVirtualPort(virtualNetwork.id(), cp2.deviceId(), cp2.port(), cp2);
183
184 ConnectPoint cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
185 manager.createVirtualPort(virtualNetwork.id(), cp3.deviceId(), cp3.port(), cp3);
186
187 ConnectPoint cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
188 manager.createVirtualPort(virtualNetwork.id(), cp4.deviceId(), cp4.port(), cp4);
189
190 ConnectPoint cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
191 manager.createVirtualPort(virtualNetwork.id(), cp5.deviceId(), cp5.port(), cp5);
192
193 ConnectPoint cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
194 manager.createVirtualPort(virtualNetwork.id(), cp6.deviceId(), cp6.port(), cp6);
195
196 VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
197 virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
198 VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
199 virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
200 VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
201 virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
202 VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
203 virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
204 VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp2, cp6);
205 virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
206 VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp6, cp2);
207 virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
208
209 return virtualNetwork;
210 }
211
212 private FlowRule flowRule(int tsval, int trval) {
213 return flowRule(DID1, tsval, trval);
214 }
215
216 private FlowRule flowRule(DeviceId did, int tsval, int trval) {
217 TestSelector ts = new TestSelector(tsval);
218 TestTreatment tr = new TestTreatment(trval);
219 return DefaultFlowRule.builder()
220 .forDevice(did)
221 .withSelector(ts)
222 .withTreatment(tr)
223 .withPriority(10)
224 .fromApp(appId)
225 .makeTemporary(TIMEOUT)
226 .build();
227 }
228
229 private FlowRule addFlowRule(int hval) {
230 FlowRule rule = flowRule(hval, hval);
231 vnetFlowRuleService1.applyFlowRules(rule);
232
233 assertNotNull("rule should be found", vnetFlowRuleService1.getFlowEntries(DID1));
234 return rule;
235 }
236
237 private int flowCount(FlowRuleService service) {
238 List<FlowEntry> entries = Lists.newArrayList();
239 service.getFlowEntries(DID1).forEach(entries::add);
240 return entries.size();
241 }
242
243 @Test
244 public void getFlowEntries() {
245 assertTrue("store should be empty",
246 Sets.newHashSet(vnetFlowRuleService1.getFlowEntries(DID1)).isEmpty());
247 assertTrue("store should be empty",
248 Sets.newHashSet(vnetFlowRuleService2.getFlowEntries(DID1)).isEmpty());
249 FlowRule f1 = addFlowRule(1);
250 FlowRule f2 = addFlowRule(2);
251
252 FlowEntry fe1 = new DefaultFlowEntry(f1);
253 FlowEntry fe2 = new DefaultFlowEntry(f2);
254
255 assertEquals("2 rules should exist", 2, flowCount(vnetFlowRuleService1));
256 assertEquals("0 rules should exist", 0, flowCount(vnetFlowRuleService2));
257 }
258
259 private class TestSelector implements TrafficSelector {
260
261 //for controlling hashcode uniqueness;
262 private final int testval;
263
264 public TestSelector(int val) {
265 testval = val;
266 }
267
268 @Override
269 public Set<Criterion> criteria() {
270 return Collections.emptySet();
271 }
272
273 @Override
274 public Criterion getCriterion(
275 org.onosproject.net.flow.criteria.Criterion.Type type) {
276 return null;
277 }
278
279 @Override
280 public int hashCode() {
281 return testval;
282 }
283
284 @Override
285 public boolean equals(Object o) {
286 if (o instanceof TestSelector) {
287 return this.testval == ((TestSelector) o).testval;
288 }
289 return false;
290 }
291
292 }
293
294 private class TestTreatment implements TrafficTreatment {
295
296 //for controlling hashcode uniqueness;
297 private final int testval;
298
299 public TestTreatment(int val) {
300 testval = val;
301 }
302
303 @Override
304 public List<Instruction> deferred() {
305 return null;
306 }
307
308 @Override
309 public List<Instruction> immediate() {
310 return null;
311 }
312
313 @Override
314 public List<Instruction> allInstructions() {
315 return null;
316 }
317
318 @Override
319 public Instructions.TableTypeTransition tableTransition() {
320 return null;
321 }
322
323 @Override
324 public boolean clearedDeferred() {
325 return false;
326 }
327
328 @Override
329 public int hashCode() {
330 return testval;
331 }
332
333 @Override
334 public boolean equals(Object o) {
335 if (o instanceof TestTreatment) {
336 return this.testval == ((TestTreatment) o).testval;
337 }
338 return false;
339 }
340
341 @Override
342 public Instructions.MetadataInstruction writeMetadata() {
343 return null;
344 }
345
346 @Override
347 public Instructions.MeterInstruction metered() {
348 return null;
349 }
350 }
351
352 private class TestVirtualFlowRuleStore implements VirtualNetworkFlowRuleStore {
353
354 private final ConcurrentMap<NetworkId,
355 ConcurrentMap<DeviceId, ConcurrentMap<FlowId, List<StoredFlowEntry>>>>
356 flowEntries = new ConcurrentHashMap<>();
357
358 @Override
359 public void setDelegate(FlowRuleStoreDelegate delegate) {
360
361 }
362
363 @Override
364 public void unsetDelegate(FlowRuleStoreDelegate delegate) {
365
366 }
367
368 @Override
369 public boolean hasDelegate() {
370 return false;
371 }
372
373 @Override
374 public int getFlowRuleCount(NetworkId networkId) {
375 return 0;
376 }
377
378 @Override
379 public FlowEntry getFlowEntry(NetworkId networkId, FlowRule rule) {
380 return null;
381 }
382
383 @Override
384 public Iterable<FlowEntry> getFlowEntries(NetworkId networkId, DeviceId deviceId) {
385 HashSet<FlowEntry> entries = Sets.newHashSet();
386
387 if (flowEntries.get(networkId) == null
388 || flowEntries.get(networkId).get(deviceId) == null) {
389 return entries;
390 }
391
392 flowEntries.get(networkId).get(deviceId).values().forEach(e -> entries.addAll(e));
393
394 return entries;
395 }
396
397 @Override
398 public void storeFlowRule(NetworkId networkId, FlowRule rule) {
399 StoredFlowEntry entry = new DefaultFlowEntry(rule);
400 flowEntries.putIfAbsent(networkId, new ConcurrentHashMap<>());
401 flowEntries.get(networkId).putIfAbsent(rule.deviceId(), new ConcurrentHashMap<>());
402 flowEntries.get(networkId).get(rule.deviceId()).putIfAbsent(rule.id(), Lists.newArrayList());
403 flowEntries.get(networkId).get(rule.deviceId()).get(rule.id()).add(entry);
404 }
405
406 @Override
407 public void storeBatch(NetworkId networkId, FlowRuleBatchOperation batchOperation) {
408 for (FlowRuleBatchEntry entry : batchOperation.getOperations()) {
409 final FlowRule flowRule = entry.target();
410 if (entry.operator().equals(FlowRuleBatchEntry.FlowRuleOperation.ADD)) {
411 storeFlowRule(networkId, flowRule);
412 } else if (entry.operator().equals(FlowRuleBatchEntry.FlowRuleOperation.REMOVE)) {
413 deleteFlowRule(networkId, flowRule);
414 } else {
415 throw new UnsupportedOperationException("Unsupported operation type");
416 }
417 }
418 }
419
420 @Override
421 public void batchOperationComplete(NetworkId networkId, FlowRuleBatchEvent event) {
422
423 }
424
425 @Override
426 public void deleteFlowRule(NetworkId networkId, FlowRule rule) {
427
428 }
429
430 @Override
431 public FlowRuleEvent addOrUpdateFlowRule(NetworkId networkId, FlowEntry rule) {
432 return null;
433 }
434
435 @Override
436 public FlowRuleEvent removeFlowRule(NetworkId networkId, FlowEntry rule) {
437 return null;
438 }
439
440 @Override
441 public FlowRuleEvent pendingFlowRule(NetworkId networkId, FlowEntry rule) {
442 return null;
443 }
444
445 @Override
446 public void purgeFlowRules(NetworkId networkId) {
447
448 }
449
450 @Override
451 public FlowRuleEvent updateTableStatistics(NetworkId networkId,
452 DeviceId deviceId,
453 List<TableStatisticsEntry> tableStats) {
454 return null;
455 }
456
457 @Override
458 public Iterable<TableStatisticsEntry>
459 getTableStatistics(NetworkId networkId, DeviceId deviceId) {
460 return null;
461 }
462 }
463
464 private void validateEvents(TestFlowRuleListener listener, FlowRuleEvent.Type... events) {
465 if (events == null) {
466 assertTrue("events generated", listener.events.isEmpty());
467 }
468
469 int i = 0;
470 System.err.println("events :" + listener.events);
471 for (FlowRuleEvent e : listener.events) {
472 assertEquals("unexpected event", events[i], e.type());
473 i++;
474 }
475
476 assertEquals("mispredicted number of events",
477 events.length, listener.events.size());
478
479 listener.events.clear();
480 }
481
482 private class TestFlowRuleListener implements FlowRuleListener {
483
484 public final List<FlowRuleEvent> events = new ArrayList<>();
485
486 @Override
487 public void event(FlowRuleEvent event) {
488 events.add(event);
489 }
490 }
491
492 private class TestProvider extends AbstractVirtualProvider
493 implements VirtualFlowRuleProvider {
494
495 protected TestProvider() {
496 super(new ProviderId("test", "org.onosproject.virtual.testprovider"));
497 }
498
499 @Override
500 public void applyFlowRule(NetworkId networkId, FlowRule... flowRules) {
501
502 }
503
504 @Override
505 public void removeFlowRule(NetworkId networkId, FlowRule... flowRules) {
506
507 }
508
509 @Override
510 public void executeBatch(NetworkId networkId, FlowRuleBatchOperation batch) {
511
512 }
513 }
514}