blob: 1a1c2358bb595e25ec96d968b2b38c16a0e66ee5 [file] [log] [blame]
Yoonseon Hanc70b4e02016-10-20 15:24:33 -07001/*
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.provider;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableSet;
21import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.osgi.ServiceDirectory;
25import org.onlab.packet.IpAddress;
26import org.onlab.packet.MacAddress;
27import org.onlab.packet.VlanId;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
30import org.onosproject.core.DefaultApplicationId;
31import org.onosproject.core.IdGenerator;
32import org.onosproject.core.Version;
33import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
34import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
35import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
36import org.onosproject.incubator.net.virtual.NetworkId;
37import org.onosproject.incubator.net.virtual.TenantId;
38import org.onosproject.incubator.net.virtual.VirtualDevice;
39import org.onosproject.incubator.net.virtual.VirtualHost;
40import org.onosproject.incubator.net.virtual.VirtualLink;
41import org.onosproject.incubator.net.virtual.VirtualNetwork;
42import org.onosproject.incubator.net.virtual.VirtualNetworkAdminService;
43import org.onosproject.incubator.net.virtual.VirtualPort;
44import org.onosproject.net.ConnectPoint;
45import org.onosproject.net.DefaultAnnotations;
46import org.onosproject.net.DefaultDevice;
47import org.onosproject.net.DefaultLink;
48import org.onosproject.net.DefaultPath;
49import org.onosproject.net.DefaultPort;
50import org.onosproject.net.Device;
51import org.onosproject.net.DeviceId;
52import org.onosproject.net.DisjointPath;
53import org.onosproject.net.HostId;
54import org.onosproject.net.HostLocation;
55import org.onosproject.net.Link;
56import org.onosproject.net.Path;
57import org.onosproject.net.Port;
58import org.onosproject.net.PortNumber;
59import org.onosproject.net.device.DeviceServiceAdapter;
60import org.onosproject.net.flow.DefaultFlowEntry;
61import org.onosproject.net.flow.DefaultFlowRule;
62import org.onosproject.net.flow.DefaultTrafficSelector;
63import org.onosproject.net.flow.DefaultTrafficTreatment;
64import org.onosproject.net.flow.FlowEntry;
65import org.onosproject.net.flow.FlowRule;
66import org.onosproject.net.flow.FlowRuleListener;
67import org.onosproject.net.flow.FlowRuleOperations;
68import org.onosproject.net.flow.FlowRuleService;
69import org.onosproject.net.flow.TableStatisticsEntry;
70import org.onosproject.net.flow.TrafficSelector;
71import org.onosproject.net.flow.TrafficTreatment;
72import org.onosproject.net.flow.instructions.Instruction;
73import org.onosproject.net.flow.instructions.L2ModificationInstruction;
74import org.onosproject.net.provider.ProviderId;
75import org.onosproject.net.topology.ClusterId;
76import org.onosproject.net.topology.LinkWeight;
77import org.onosproject.net.topology.Topology;
78import org.onosproject.net.topology.TopologyCluster;
79import org.onosproject.net.topology.TopologyGraph;
80import org.onosproject.net.topology.TopologyListener;
Yuta HIGUCHI03c234e2017-01-23 17:21:34 -080081import org.onosproject.net.topology.TopologyServiceAdapter;
Yoonseon Hanc70b4e02016-10-20 15:24:33 -070082
83import java.util.HashSet;
84import java.util.Map;
85import java.util.Set;
86import java.util.stream.Collectors;
87
88import static org.junit.Assert.assertEquals;
89
90public class DefaultVirtualFlowRuleProviderTest {
91 private static final ProviderId PID = new ProviderId("of", "foo");
92
93 private static final DeviceId DID1 = DeviceId.deviceId("of:001");
94 private static final DeviceId DID2 = DeviceId.deviceId("of:002");
95 private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
96 private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
97
98 private static final DefaultAnnotations ANNOTATIONS =
99 DefaultAnnotations.builder().set("foo", "bar").build();
100
101 private static final Device DEV1 =
102 new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
103 private static final Device DEV2 =
104 new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
105 private static final Port PORT11 =
106 new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
107 private static final Port PORT12 =
108 new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
109 private static final Port PORT21 =
110 new DefaultPort(DEV2, PORT_NUM1, true, ANNOTATIONS);
111 private static final Port PORT22 =
112 new DefaultPort(DEV2, PORT_NUM2, true, ANNOTATIONS);
113
114 private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
115 private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
116 private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM1);
117 private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM2);
118 private static final Link LINK1 = DefaultLink.builder()
119 .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
120
121 private static final NetworkId VNET_ID = NetworkId.networkId(1);
122 private static final DeviceId VDID = DeviceId.deviceId("of:100");
123
124 private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
125 VNET_ID, TenantId.tenantId("t1"));
126 private static final VirtualDevice VDEV =
127 new DefaultVirtualDevice(VNET_ID, VDID);
128 private static final VirtualPort VPORT1 =
129 new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM1, CP11);
130 private static final VirtualPort VPORT2 =
131 new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM2, CP22);
132
133 private static final int TIMEOUT = 10;
134
135
136 protected DefaultVirtualFlowRuleProvider virtualProvider;
137
138 private ApplicationId vAppId;
139
140 @Before
141 public void setUp() {
142 virtualProvider = new DefaultVirtualFlowRuleProvider();
143
144 virtualProvider.deviceService = new TestDeviceService();
145 virtualProvider.coreService = new TestCoreService();
146 virtualProvider.virtualNetworkAdminService =
147 new TestVirtualNetworkAdminService();
148 virtualProvider.topologyService = new TestTopologyService();
149 virtualProvider.flowRuleService = new TestFlowRuleService();
150 virtualProvider.providerRegistryService = new VirtualProviderManager();
151
152 virtualProvider.activate();
153 vAppId = new TestApplicationId(0, "Virtual App");
154 }
155
156 @After
157 public void tearDown() {
158 virtualProvider.deactivate();
159 virtualProvider.deviceService = null;
160 virtualProvider.coreService = null;
161 }
162
163 @Test
164 public void virtualizeFlowRuleWithInPort() {
165 TrafficSelector ts = DefaultTrafficSelector.builder()
166 .matchInPort(PORT_NUM1).build();
167 TrafficTreatment tr = DefaultTrafficTreatment.builder()
168 .setOutput(PORT_NUM2).build();
169
170 FlowRule r1 = DefaultFlowRule.builder()
171 .forDevice(VDID)
172 .withSelector(ts)
173 .withTreatment(tr)
174 .withPriority(10)
175 .fromApp(vAppId)
176 .makeTemporary(TIMEOUT)
177 .build();
178
179 virtualProvider.applyFlowRule(VNET_ID, r1);
180
181 assertEquals("2 rules should exist", 2,
182 virtualProvider.flowRuleService.getFlowRuleCount());
183
184 Set<FlowEntry> phyRules = new HashSet<>();
185 for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
186 phyRules.add(i);
187 }
188 for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
189 phyRules.add(i);
190 }
191
192 FlowRule in = null;
193 FlowRule out = null;
194
195 for (FlowRule rule : phyRules) {
196
197 L2ModificationInstruction i = (L2ModificationInstruction)
198 rule.treatment().allInstructions().get(0);
199
200 if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
201 in = rule;
202 } else {
203 out = rule;
204 }
205
206 }
207
208 assertEquals(DID1, in.deviceId());
209 assertEquals(DID2, out.deviceId());
210 }
211
212 @Test
213 public void virtualizeFlowRuleWithoutInPort() {
214 TrafficSelector ts = DefaultTrafficSelector.builder().build();
215 TrafficTreatment tr = DefaultTrafficTreatment.builder()
216 .setOutput(PORT_NUM2).build();
217
218 FlowRule r1 = DefaultFlowRule.builder()
219 .forDevice(VDID)
220 .withSelector(ts)
221 .withTreatment(tr)
222 .withPriority(10)
223 .fromApp(vAppId)
224 .makeTemporary(TIMEOUT)
225 .build();
226
227 virtualProvider.applyFlowRule(VNET_ID, r1);
228
229 assertEquals("3 rules should exist", 3,
230 virtualProvider.flowRuleService.getFlowRuleCount());
231
232 FlowRule inFromDID1 = null;
233 FlowRule inFromDID2 = null;
234 FlowRule out = null;
235
236 Set<FlowEntry> phyRules = new HashSet<>();
237 for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
238 phyRules.add(i);
239 }
240 for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
241 phyRules.add(i);
242 }
243
244 for (FlowRule rule : phyRules) {
245 for (Instruction inst : rule.treatment().allInstructions()) {
246 if (inst.type() == Instruction.Type.L2MODIFICATION) {
247 L2ModificationInstruction i = (L2ModificationInstruction) inst;
248 if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
249 inFromDID1 = rule;
250 break;
251 } else {
252 out = rule;
253 break;
254 }
255 } else {
256 inFromDID2 = rule;
257 break;
258 }
259 }
260 }
261
262 assertEquals(DID1, inFromDID1.deviceId());
263 assertEquals(DID2, inFromDID2.deviceId());
264 assertEquals(DID2, out.deviceId());
265 }
266
267 @Test
268 public void removeVirtualizeFlowRule() {
269 TrafficSelector ts = DefaultTrafficSelector.builder().build();
270 TrafficTreatment tr = DefaultTrafficTreatment.builder()
271 .setOutput(PORT_NUM2).build();
272
273 FlowRule r1 = DefaultFlowRule.builder()
274 .forDevice(VDID)
275 .withSelector(ts)
276 .withTreatment(tr)
277 .withPriority(10)
278 .fromApp(vAppId)
279 .makeTemporary(TIMEOUT)
280 .build();
281
282 virtualProvider.removeFlowRule(VNET_ID, r1);
283
284 assertEquals("0 rules should exist", 0,
285 virtualProvider.flowRuleService.getFlowRuleCount());
286 }
287
288
289 private static class TestDeviceService extends DeviceServiceAdapter {
290 @Override
291 public int getDeviceCount() {
292 return 2;
293 }
294
295 @Override
296 public Iterable<Device> getDevices() {
297 return ImmutableList.of(DEV1, DEV2);
298 }
299
300 @Override
301 public Iterable<Device> getAvailableDevices() {
302 return getDevices();
303 }
304
305 @Override
306 public Device getDevice(DeviceId deviceId) {
307 return deviceId.equals(DID2) ? DEV2 : DEV1;
308 }
309 }
310
311 private static class TestCoreService implements CoreService {
312
313 @Override
314 public Version version() {
315 return null;
316 }
317
318 @Override
319 public Set<ApplicationId> getAppIds() {
320 return null;
321 }
322
323 @Override
324 public ApplicationId getAppId(Short id) {
325 return null;
326 }
327
328 @Override
329 public ApplicationId getAppId(String name) {
330 return null;
331 }
332
333 @Override
334 public ApplicationId registerApplication(String name) {
335 return new TestApplicationId(1, name);
336 }
337
338 @Override
339 public ApplicationId registerApplication(String name,
340 Runnable preDeactivate) {
341 return null;
342 }
343
344 @Override
345 public IdGenerator getIdGenerator(String topic) {
346 return null;
347 }
348 }
349
350 private static class TestApplicationId extends DefaultApplicationId {
351 public TestApplicationId(int id, String name) {
352 super(id, name);
353 }
354 }
355
356 private static class TestVirtualNetworkAdminService
357 implements VirtualNetworkAdminService {
358
359 @Override
360 public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
361 return null;
362 }
363
364 @Override
365 public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
366 return ImmutableSet.of(VDEV);
367 }
368
369 @Override
370 public Set<VirtualHost> getVirtualHosts(NetworkId networkId) {
371 return null;
372 }
373
374 @Override
375 public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
376 return null;
377 }
378
379 @Override
380 public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
381 DeviceId deviceId) {
382 return ImmutableSet.of(VPORT1, VPORT2);
383 }
384
385 @Override
386 public <T> T get(NetworkId networkId, Class<T> serviceClass) {
387 return null;
388 }
389
390 @Override
391 public ServiceDirectory getServiceDirectory() {
392 return null;
393 }
394
395 @Override
396 public void registerTenantId(TenantId tenantId) {
397
398 }
399
400 @Override
401 public void unregisterTenantId(TenantId tenantId) {
402
403 }
404
405 @Override
406 public Set<TenantId> getTenantIds() {
407 return null;
408 }
409
410 @Override
411 public VirtualNetwork createVirtualNetwork(TenantId tenantId) {
412 return null;
413 }
414
415 @Override
416 public void removeVirtualNetwork(NetworkId networkId) {
417
418 }
419
420 @Override
421 public VirtualDevice createVirtualDevice(NetworkId networkId,
422 DeviceId deviceId) {
423 return null;
424 }
425
426 @Override
427 public void removeVirtualDevice(NetworkId networkId, DeviceId deviceId) {
428
429 }
430
431 @Override
432 public VirtualHost createVirtualHost(NetworkId networkId, HostId hostId,
433 MacAddress mac, VlanId vlan,
434 HostLocation location,
435 Set<IpAddress> ips) {
436 return null;
437 }
438
439 @Override
440 public void removeVirtualHost(NetworkId networkId, HostId hostId) {
441
442 }
443
444 @Override
445 public VirtualLink createVirtualLink(NetworkId networkId,
446 ConnectPoint src, ConnectPoint dst) {
447 return null;
448 }
449
450 @Override
451 public void removeVirtualLink(NetworkId networkId,
452 ConnectPoint src, ConnectPoint dst) {
453
454 }
455
456 @Override
457 public VirtualPort createVirtualPort(NetworkId networkId,
458 DeviceId deviceId,
459 PortNumber portNumber,
460 ConnectPoint realizedBy) {
461 return null;
462 }
463
464 @Override
465 public void bindVirtualPort(NetworkId networkId,
466 DeviceId deviceId,
467 PortNumber portNumber,
468 ConnectPoint realizedBy) {
469
470 }
471
472 @Override
473 public void removeVirtualPort(NetworkId networkId, DeviceId deviceId,
474 PortNumber portNumber) {
475
476 }
477 }
478
Yuta HIGUCHI03c234e2017-01-23 17:21:34 -0800479 private static class TestTopologyService extends TopologyServiceAdapter {
Yoonseon Hanc70b4e02016-10-20 15:24:33 -0700480
481 @Override
482 public void addListener(TopologyListener listener) {
483
484 }
485
486 @Override
487 public void removeListener(TopologyListener listener) {
488
489 }
490
491 @Override
492 public Topology currentTopology() {
493 return null;
494 }
495
496 @Override
497 public boolean isLatest(Topology topology) {
498 return false;
499 }
500
501 @Override
502 public TopologyGraph getGraph(Topology topology) {
503 return null;
504 }
505
506 @Override
507 public Set<TopologyCluster> getClusters(Topology topology) {
508 return null;
509 }
510
511 @Override
512 public TopologyCluster getCluster(Topology topology, ClusterId clusterId) {
513 return null;
514 }
515
516 @Override
517 public Set<DeviceId> getClusterDevices(Topology topology,
518 TopologyCluster cluster) {
519 return null;
520 }
521
522 @Override
523 public Set<Link> getClusterLinks(Topology topology,
524 TopologyCluster cluster) {
525 return null;
526 }
527
528 @Override
529 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
530 DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
531 100, ANNOTATIONS);
532 return ImmutableSet.of(path);
533 }
534
535 @Override
536 public Set<Path> getPaths(Topology topology, DeviceId src,
537 DeviceId dst, LinkWeight weight) {
538 DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
539 100, ANNOTATIONS);
540 return ImmutableSet.of(path);
541 }
542
543 @Override
544 public Set<DisjointPath> getDisjointPaths(Topology topology,
545 DeviceId src, DeviceId dst) {
546 return null;
547 }
548
549 @Override
550 public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
551 DeviceId dst, LinkWeight weight) {
552 return null;
553 }
554
555 @Override
556 public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
557 DeviceId dst,
558 Map<Link, Object> riskProfile) {
559 return null;
560 }
561
562 @Override
563 public Set<DisjointPath> getDisjointPaths(Topology topology, DeviceId src,
564 DeviceId dst, LinkWeight weight,
565 Map<Link, Object> riskProfile) {
566 return null;
567 }
568
569 @Override
570 public boolean isInfrastructure(Topology topology,
571 ConnectPoint connectPoint) {
572 return false;
573 }
574
575 @Override
576 public boolean isBroadcastPoint(Topology topology,
577 ConnectPoint connectPoint) {
578 return false;
579 }
580 }
581
582 private static class TestFlowRuleService implements FlowRuleService {
583 static Set<FlowRule> ruleCollection = new HashSet<>();
584
585 @Override
586 public void addListener(FlowRuleListener listener) {
587
588 }
589
590 @Override
591 public void removeListener(FlowRuleListener listener) {
592
593 }
594
595 @Override
596 public int getFlowRuleCount() {
597 return ruleCollection.size();
598 }
599
600 @Override
601 public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
602 return ruleCollection.stream()
603 .filter(r -> r.deviceId().equals(deviceId))
604 .map(r -> new DefaultFlowEntry(r))
605 .collect(Collectors.toSet());
606 }
607
608 @Override
609 public void applyFlowRules(FlowRule... flowRules) {
610 for (FlowRule rule : flowRules) {
611 ruleCollection.add(rule);
612 }
613 }
614
615 @Override
616 public void purgeFlowRules(DeviceId deviceId) {
617
618 }
619
620 @Override
621 public void removeFlowRules(FlowRule... flowRules) {
622 Set<FlowRule> candidates = new HashSet<>();
623 for (FlowRule rule : flowRules) {
624 ruleCollection.stream()
625 .filter(r -> r.exactMatch(rule))
626 .forEach(candidates::add);
627 }
628 ruleCollection.removeAll(candidates);
629 }
630
631 @Override
632 public void removeFlowRulesById(ApplicationId appId) {
633
634 }
635
636 @Override
637 public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
638 return null;
639 }
640
641 @Override
642 public Iterable<FlowEntry> getFlowEntriesById(ApplicationId id) {
643 return null;
644 }
645
646 @Override
647 public Iterable<FlowRule> getFlowRulesByGroupId(ApplicationId appId,
648 short groupId) {
649 return null;
650 }
651
652 @Override
653 public void apply(FlowRuleOperations ops) {
654
655 }
656
657 @Override
658 public Iterable<TableStatisticsEntry>
659 getFlowTableStatistics(DeviceId deviceId) {
660 return null;
661 }
662 }
663}