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