blob: 3ee89aea72a6e649e526da9e5d49dde015d675ba [file] [log] [blame]
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Sho SHIMIZUee2aa652015-02-25 18:56:43 -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 */
16package org.onosproject.net.intent.impl.compiler;
17
Michele Santuari69fc2ff2015-12-03 17:05:35 +010018import com.google.common.collect.ImmutableList;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080019import org.junit.After;
20import org.junit.Before;
21import org.junit.Test;
Michele Santuari6096acd2016-02-09 17:00:37 +010022import org.onlab.packet.Ethernet;
23import org.onlab.packet.MplsLabel;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010024import org.onlab.packet.VlanId;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080025import org.onosproject.TestApplicationId;
Thomas Vachuskabdbdd242016-03-01 01:55:55 -080026import org.onosproject.cfg.ComponentConfigAdapter;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080027import org.onosproject.core.ApplicationId;
28import org.onosproject.core.CoreService;
29import org.onosproject.core.IdGenerator;
30import org.onosproject.net.ConnectPoint;
31import org.onosproject.net.DefaultLink;
32import org.onosproject.net.DefaultPath;
Michele Santuari6096acd2016-02-09 17:00:37 +010033import org.onosproject.net.DeviceId;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010034import org.onosproject.net.EncapsulationType;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080035import org.onosproject.net.Link;
36import org.onosproject.net.flow.DefaultTrafficSelector;
37import org.onosproject.net.flow.DefaultTrafficTreatment;
38import org.onosproject.net.flow.FlowRule;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010041import org.onosproject.net.flow.instructions.Instructions;
42import org.onosproject.net.flow.instructions.L2ModificationInstruction;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080043import org.onosproject.net.intent.FlowRuleIntent;
44import org.onosproject.net.intent.Intent;
45import org.onosproject.net.intent.IntentExtensionService;
46import org.onosproject.net.intent.MockIdGenerator;
47import org.onosproject.net.intent.PathIntent;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010048import org.onosproject.net.intent.constraint.EncapsulationConstraint;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080049import org.onosproject.net.provider.ProviderId;
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070050import org.onosproject.net.resource.MockResourceService;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080051
Michele Santuari69fc2ff2015-12-03 17:05:35 +010052import java.util.Arrays;
53import java.util.Collection;
54import java.util.Collections;
55import java.util.List;
56import java.util.Set;
57import java.util.stream.Collectors;
58
Michele Santuari6096acd2016-02-09 17:00:37 +010059import static org.easymock.EasyMock.createMock;
60import static org.easymock.EasyMock.expect;
61import static org.easymock.EasyMock.replay;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080062import static org.hamcrest.MatcherAssert.assertThat;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070063import static org.hamcrest.Matchers.everyItem;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080064import static org.hamcrest.Matchers.hasSize;
65import static org.hamcrest.Matchers.is;
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +020066import static org.hamcrest.Matchers.lessThan;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010067import static org.hamcrest.number.OrderingComparison.greaterThan;
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +020068import static org.junit.Assert.assertNotEquals;
69import static org.junit.Assert.assertTrue;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080070import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
71import static org.onosproject.net.Link.Type.DIRECT;
Pier1677f9f2016-07-06 15:42:17 +020072import static org.onosproject.net.Link.Type.INDIRECT;
Michele Santuari6096acd2016-02-09 17:00:37 +010073import static org.onosproject.net.NetTestTools.APP_ID;
74import static org.onosproject.net.NetTestTools.PID;
75import static org.onosproject.net.NetTestTools.connectPoint;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080076
77/**
78 * Unit tests for PathIntentCompiler.
79 */
80public class PathIntentCompilerTest {
81
82 private CoreService coreService;
83 private IntentExtensionService intentExtensionService;
Thomas Vachuskabdbdd242016-03-01 01:55:55 -080084 private IntentConfigurableRegistrator registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080085 private IdGenerator idGenerator = new MockIdGenerator();
86 private PathIntentCompiler sut;
87
88 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
89 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
Michele Santuari3ea53902016-02-15 11:21:56 +010090 private final VlanId ingressVlan = VlanId.vlanId(((short) 101));
91 private final TrafficSelector vlanSelector = DefaultTrafficSelector.builder()
92 .matchVlanId(ingressVlan).build();
93 private final VlanId egressVlan = VlanId.vlanId((short) 100);
94 private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment.builder()
95 .setVlanId(egressVlan).build();
96
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080097 private final ApplicationId appId = new TestApplicationId("test");
98 private final ProviderId pid = new ProviderId("of", "test");
Pier1677f9f2016-07-06 15:42:17 +020099
100 // Edge scenario
101 private final ConnectPoint d1p2 = connectPoint("s1", 2);
102 private final ConnectPoint d1p3 = connectPoint("s1", 3);
103 private final List<Link> edgeNet = Arrays.asList(
104 createEdgeLink(d1p2, true),
105 createEdgeLink(d1p3, false)
106 );
107 private final int edgeHops = edgeNet.size() - 1;
108 private PathIntent edgeIntentNoVlan;
109 private PathIntent edgeIntentIngressVlan;
110 private PathIntent edgeIntentEgressVlan;
111 private PathIntent edgeIntentVlan;
112
113 // Single-hop scenario - indirect
114 private final ConnectPoint d1p4 = connectPoint("s1", 4);
115 private final ConnectPoint d2p2 = connectPoint("s2", 2);
116 private final ConnectPoint d2p3 = connectPoint("s2", 3);
117 private final ConnectPoint d3p2 = connectPoint("s3", 2);
118 private final List<Link> singleHopIndirect = Arrays.asList(
119 DefaultLink.builder().providerId(PID).src(d1p4).dst(d2p2).type(DIRECT).build(),
120 DefaultLink.builder().providerId(PID).src(d2p3).dst(d3p2).type(INDIRECT).build()
121 );
122 private final int singleHopIndirectHops = singleHopIndirect.size() - 1;
123 private PathIntent singleHopIndirectIntentNoVlan;
124 private PathIntent singleHopIndirectIntentIngressVlan;
125 private PathIntent singleHopIndirectIntentEgressVlan;
126 private PathIntent singleHopIndirectIntentVlan;
127
128
129 // Single-hop scenario- direct
130 private final ConnectPoint d1p5 = connectPoint("s1", 5);
131 private final ConnectPoint d2p4 = connectPoint("s2", 4);
132 private final ConnectPoint d2p5 = connectPoint("s2", 5);
133 private final ConnectPoint d3p3 = connectPoint("s3", 3);
134 private final List<Link> singleHopDirect = Arrays.asList(
135 DefaultLink.builder().providerId(PID).src(d1p5).dst(d2p4).type(DIRECT).build(),
136 DefaultLink.builder().providerId(PID).src(d2p5).dst(d3p3).type(DIRECT).build()
137 );
138 private final int singleHopDirectHops = singleHopDirect.size() - 1;
139 private PathIntent singleHopDirectIntentNoVlan;
140 private PathIntent singleHopDirectIntentIngressVlan;
141 private PathIntent singleHopDirectIntentEgressVlan;
142 private PathIntent singleHopDirectIntentVlan;
143
144
145 // Multi-hop scenario
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800146 private final ConnectPoint d1p1 = connectPoint("s1", 0);
147 private final ConnectPoint d2p0 = connectPoint("s2", 0);
148 private final ConnectPoint d2p1 = connectPoint("s2", 1);
149 private final ConnectPoint d3p1 = connectPoint("s3", 1);
150 private final ConnectPoint d3p0 = connectPoint("s3", 10);
151 private final ConnectPoint d1p0 = connectPoint("s1", 10);
Brian O'Connor81134662015-06-25 17:23:33 -0400152 private static final int PRIORITY = 555;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800153
154 private final List<Link> links = Arrays.asList(
155 createEdgeLink(d1p0, true),
Ray Milkey2693bda2016-01-22 16:08:14 -0800156 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
157 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800158 createEdgeLink(d3p0, false)
159 );
160 private final int hops = links.size() - 1;
161 private PathIntent intent;
Michele Santuari6096acd2016-02-09 17:00:37 +0100162 private PathIntent constraintVlanIntent;
Michele Santuari3ea53902016-02-15 11:21:56 +0100163 private PathIntent constrainIngressEgressVlanIntent;
Michele Santuari6096acd2016-02-09 17:00:37 +0100164 private PathIntent constraintMplsIntent;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800165
166 /**
Pier Ventref8543d82016-09-28 19:49:33 -0700167 * Configures mock objects used in all the test cases.
168 * Creates the intents to test as well.
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800169 */
170 @Before
171 public void setUp() {
172 sut = new PathIntentCompiler();
173 coreService = createMock(CoreService.class);
174 expect(coreService.registerApplication("org.onosproject.net.intent"))
175 .andReturn(appId);
176 sut.coreService = coreService;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100177 sut.resourceService = new MockResourceService();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800178
Thomas Vachuska23235962017-02-03 11:44:15 -0800179 Intent.unbindIdGenerator(idGenerator);
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800180 Intent.bindIdGenerator(idGenerator);
181
182 intent = PathIntent.builder()
183 .appId(APP_ID)
184 .selector(selector)
185 .treatment(treatment)
Brian O'Connor81134662015-06-25 17:23:33 -0400186 .priority(PRIORITY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800187 .path(new DefaultPath(pid, links, hops))
188 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100189
Michele Santuari3ea53902016-02-15 11:21:56 +0100190 //Intent with VLAN encap without egress VLAN
Michele Santuari6096acd2016-02-09 17:00:37 +0100191 constraintVlanIntent = PathIntent.builder()
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100192 .appId(APP_ID)
193 .selector(selector)
194 .treatment(treatment)
195 .priority(PRIORITY)
196 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
197 .path(new DefaultPath(pid, links, hops))
198 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100199
Michele Santuari3ea53902016-02-15 11:21:56 +0100200 //Intent with VLAN encap with ingress and egress VLAN
201 constrainIngressEgressVlanIntent = PathIntent.builder()
202 .appId(APP_ID)
203 .selector(vlanSelector)
204 .treatment(vlanTreatment)
205 .priority(PRIORITY)
206 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
207 .path(new DefaultPath(pid, links, hops))
208 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100209
210 constraintMplsIntent = PathIntent.builder()
211 .appId(APP_ID)
212 .selector(selector)
213 .treatment(treatment)
214 .priority(PRIORITY)
215 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.MPLS)))
216 .path(new DefaultPath(pid, links, hops))
217 .build();
Pier1677f9f2016-07-06 15:42:17 +0200218
219 edgeIntentNoVlan = PathIntent.builder()
220 .appId(APP_ID)
221 .selector(selector)
222 .treatment(treatment)
223 .priority(PRIORITY)
224 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
225 .path(new DefaultPath(pid, edgeNet, edgeHops))
226 .build();
227
228 edgeIntentIngressVlan = PathIntent.builder()
229 .appId(APP_ID)
230 .selector(vlanSelector)
231 .treatment(treatment)
232 .priority(PRIORITY)
233 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
234 .path(new DefaultPath(pid, edgeNet, edgeHops))
235 .build();
236
237 edgeIntentEgressVlan = PathIntent.builder()
238 .appId(APP_ID)
239 .selector(selector)
240 .treatment(vlanTreatment)
241 .priority(PRIORITY)
242 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
243 .path(new DefaultPath(pid, edgeNet, edgeHops))
244 .build();
245
246 edgeIntentVlan = PathIntent.builder()
247 .appId(APP_ID)
248 .selector(vlanSelector)
249 .treatment(vlanTreatment)
250 .priority(PRIORITY)
251 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
252 .path(new DefaultPath(pid, edgeNet, edgeHops))
253 .build();
254
255 singleHopIndirectIntentNoVlan = PathIntent.builder()
256 .appId(APP_ID)
257 .selector(selector)
258 .treatment(treatment)
259 .priority(PRIORITY)
260 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
261 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
262 .build();
263
264 singleHopIndirectIntentIngressVlan = PathIntent.builder()
265 .appId(APP_ID)
266 .selector(vlanSelector)
267 .treatment(treatment)
268 .priority(PRIORITY)
269 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
270 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
271 .build();
272
273 singleHopIndirectIntentEgressVlan = PathIntent.builder()
274 .appId(APP_ID)
275 .selector(selector)
276 .treatment(vlanTreatment)
277 .priority(PRIORITY)
278 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
279 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
280 .build();
281
282 singleHopIndirectIntentVlan = PathIntent.builder()
283 .appId(APP_ID)
284 .selector(vlanSelector)
285 .treatment(vlanTreatment)
286 .priority(PRIORITY)
287 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
288 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
289 .build();
290
291 singleHopDirectIntentNoVlan = PathIntent.builder()
292 .appId(APP_ID)
293 .selector(selector)
294 .treatment(treatment)
295 .priority(PRIORITY)
296 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
297 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
298 .build();
299
300 singleHopDirectIntentIngressVlan = PathIntent.builder()
301 .appId(APP_ID)
302 .selector(vlanSelector)
303 .treatment(treatment)
304 .priority(PRIORITY)
305 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
306 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
307 .build();
308
309 singleHopDirectIntentEgressVlan = PathIntent.builder()
310 .appId(APP_ID)
311 .selector(selector)
312 .treatment(vlanTreatment)
313 .priority(PRIORITY)
314 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
315 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
316 .build();
317
318 singleHopDirectIntentVlan = PathIntent.builder()
319 .appId(APP_ID)
320 .selector(vlanSelector)
321 .treatment(vlanTreatment)
322 .priority(PRIORITY)
323 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
324 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
325 .build();
326
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800327 intentExtensionService = createMock(IntentExtensionService.class);
328 intentExtensionService.registerCompiler(PathIntent.class, sut);
329 intentExtensionService.unregisterCompiler(PathIntent.class);
Thomas Vachuskabdbdd242016-03-01 01:55:55 -0800330
331 registrator = new IntentConfigurableRegistrator();
332 registrator.extensionService = intentExtensionService;
333 registrator.cfgService = new ComponentConfigAdapter();
334 registrator.activate();
335
336 sut.registrator = registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800337
338 replay(coreService, intentExtensionService);
339 }
340
341 /**
342 * Tears down objects used in all the test cases.
343 */
344 @After
345 public void tearDown() {
346 Intent.unbindIdGenerator(idGenerator);
347 }
348
Pier1677f9f2016-07-06 15:42:17 +0200349
350 /**
351 * Tests the compilation behavior of the path intent compiler in case of
352 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
353 * and edge communication. No ingress VLAN. No egress VLAN.
354 */
355 @Test
356 public void testVlanEncapCompileEdgeNoVlan() {
357 sut.activate();
358
359 List<Intent> compiled = sut.compile(edgeIntentNoVlan, Collections.emptyList());
360 assertThat(compiled, hasSize(1));
361
362 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
363 assertThat(rules, hasSize(1));
364
365 FlowRule rule = rules.stream()
366 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
367 .findFirst()
368 .get();
369 verifyIdAndPriority(rule, d1p2.deviceId());
370
371 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
372 .build()));
373 assertThat(rule.treatment(),
374 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
375
376 sut.deactivate();
377 }
378
379 /**
380 * Tests the compilation behavior of the path intent compiler in case of
381 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
382 * and edge communication. Ingress VLAN. No egress VLAN.
383 */
384 @Test
385 public void testVlanEncapCompileEdgeIngressVlan() {
386 sut.activate();
387
388 List<Intent> compiled = sut.compile(edgeIntentIngressVlan, Collections.emptyList());
389 assertThat(compiled, hasSize(1));
390
391 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
392 assertThat(rules, hasSize(1));
393
394 FlowRule rule = rules.stream()
395 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
396 .findFirst()
397 .get();
398 verifyIdAndPriority(rule, d1p2.deviceId());
399
400 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
401 .matchVlanId(ingressVlan).build()));
402 assertThat(rule.treatment(),
403 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
404
405 sut.deactivate();
406 }
407
408 /**
409 * Tests the compilation behavior of the path intent compiler in case of
410 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
411 * and edge communication. No ingress VLAN. Egress VLAN.
412 */
413 @Test
414 public void testVlanEncapCompileEdgeEgressVlan() {
415 sut.activate();
416
417 List<Intent> compiled = sut.compile(edgeIntentEgressVlan, Collections.emptyList());
418 assertThat(compiled, hasSize(1));
419
420 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
421 assertThat(rules, hasSize(1));
422
423 FlowRule rule = rules.stream()
424 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
425 .findFirst()
426 .get();
427 verifyIdAndPriority(rule, d1p2.deviceId());
428
429 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
430 .build()));
431 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
432 .setOutput(d1p3.port()).build()));
433
434 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
435 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
436 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
437 .collect(Collectors.toSet());
438 assertThat(rule.treatment().allInstructions().stream()
439 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
440 .collect(Collectors.toSet()), hasSize(1));
441 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
442 assertThat(rule.treatment().allInstructions().stream()
443 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
444 .collect(Collectors.toSet()), hasSize(0));
445
446 sut.deactivate();
447 }
448
449 /**
450 * Tests the compilation behavior of the path intent compiler in case of
451 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
452 * and edge communication. Ingress VLAN. Egress VLAN.
453 */
454 @Test
455 public void testVlanEncapCompileEdgeVlan() {
456 sut.activate();
457
458 List<Intent> compiled = sut.compile(edgeIntentVlan, Collections.emptyList());
459 assertThat(compiled, hasSize(1));
460
461 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
462 assertThat(rules, hasSize(1));
463
464 FlowRule rule = rules.stream()
465 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
466 .findFirst()
467 .get();
468 verifyIdAndPriority(rule, d1p2.deviceId());
469
470 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
471 .matchVlanId(ingressVlan).build()));
472 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
473 .setOutput(d1p3.port()).build()));
474
475 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
476 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
477 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
478 .collect(Collectors.toSet());
479 assertThat(rule.treatment().allInstructions().stream()
480 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
481 .collect(Collectors.toSet()), hasSize(1));
482 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
483 assertThat(rule.treatment().allInstructions().stream()
484 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
485 .collect(Collectors.toSet()), hasSize(0));
486
487 sut.deactivate();
488 }
489
490 /**
491 * Tests the compilation behavior of the path intent compiler in case of
492 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
493 * and single-hop-indirect-link scenario. No ingress VLAN. No egress VLAN.
494 */
495 @Test
496 public void testVlanEncapCompileSingleHopIndirectNoVlan() {
497 sut.activate();
498
499 List<Intent> compiled = sut.compile(singleHopIndirectIntentNoVlan, Collections.emptyList());
500 assertThat(compiled, hasSize(1));
501
502 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
503 assertThat(rules, hasSize(1));
504
505
506 FlowRule rule = rules.stream()
507 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
508 .findFirst()
509 .get();
510 verifyIdAndPriority(rule, d2p2.deviceId());
511
512 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
513 .build()));
514 assertThat(rule.treatment(),
515 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
516
517 sut.deactivate();
518 }
519
520 /**
521 * Tests the compilation behavior of the path intent compiler in case of
522 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
523 * and single-hop-indirect-link scenario. Ingress VLAN. No egress VLAN.
524 */
525 @Test
526 public void testVlanEncapCompileSingleHopIndirectIngressVlan() {
527 sut.activate();
528
529 List<Intent> compiled = sut.compile(singleHopIndirectIntentIngressVlan, Collections.emptyList());
530 assertThat(compiled, hasSize(1));
531
532 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
533 assertThat(rules, hasSize(1));
534
535
536 FlowRule rule = rules.stream()
537 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
538 .findFirst()
539 .get();
540 verifyIdAndPriority(rule, d2p2.deviceId());
541
542 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
543 .matchVlanId(ingressVlan).build()));
544 assertThat(rule.treatment(),
545 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
546
547 sut.deactivate();
548 }
549
550 /**
551 * Tests the compilation behavior of the path intent compiler in case of
552 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
553 * and single-hop-indirect-link scenario. No ingress VLAN. Egress VLAN.
554 */
555 @Test
556 public void testVlanEncapCompileSingleHopIndirectEgressVlan() {
557 sut.activate();
558
559 List<Intent> compiled = sut.compile(singleHopIndirectIntentEgressVlan, Collections.emptyList());
560 assertThat(compiled, hasSize(1));
561
562 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
563 assertThat(rules, hasSize(1));
564
565
566 FlowRule rule = rules.stream()
567 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
568 .findFirst()
569 .get();
570 verifyIdAndPriority(rule, d2p2.deviceId());
571
572 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
573 .build()));
574 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
575 .setOutput(d2p3.port()).build()));
576
577 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
578 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
579 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
580 .collect(Collectors.toSet());
581 assertThat(rule.treatment().allInstructions().stream()
582 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
583 .collect(Collectors.toSet()), hasSize(1));
584 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
585 assertThat(rule.treatment().allInstructions().stream()
586 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
587 .collect(Collectors.toSet()), hasSize(0));
588
589 sut.deactivate();
590 }
591
592 /**
593 * Tests the compilation behavior of the path intent compiler in case of
594 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
595 * and single-hop-indirect-link scenario. Ingress VLAN. Egress VLAN.
596 */
597 @Test
598 public void testVlanEncapCompileSingleHopIndirectVlan() {
599 sut.activate();
600
601 List<Intent> compiled = sut.compile(singleHopIndirectIntentVlan, Collections.emptyList());
602 assertThat(compiled, hasSize(1));
603
604 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
605 assertThat(rules, hasSize(1));
606
607
608 FlowRule rule = rules.stream()
609 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
610 .findFirst()
611 .get();
612 verifyIdAndPriority(rule, d2p2.deviceId());
613
614 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
615 .matchVlanId(ingressVlan).build()));
616 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
617 .setOutput(d2p3.port()).build()));
618
619 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
620 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
621 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
622 .collect(Collectors.toSet());
623 assertThat(rule.treatment().allInstructions().stream()
624 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
625 .collect(Collectors.toSet()), hasSize(1));
626 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
627 assertThat(rule.treatment().allInstructions().stream()
628 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
629 .collect(Collectors.toSet()), hasSize(0));
630
631 sut.deactivate();
632 }
633
634 /**
635 * Tests the compilation behavior of the path intent compiler in case of
636 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
637 * and single-hop-direct-link scenario. No ingress VLAN. No egress VLAN.
638 */
639 @Test
640 public void testVlanEncapCompileSingleHopDirectNoVlan() {
641 sut.activate();
642
643 List<Intent> compiled = sut.compile(singleHopDirectIntentNoVlan, Collections.emptyList());
644 assertThat(compiled, hasSize(1));
645
646 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
647 assertThat(rules, hasSize(1));
648
649
650 FlowRule rule = rules.stream()
651 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
652 .findFirst()
653 .get();
654 verifyIdAndPriority(rule, d2p4.deviceId());
655
656 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
657 .build()));
658 assertThat(rule.treatment(),
659 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
660
661 sut.deactivate();
662 }
663
664 /**
665 * Tests the compilation behavior of the path intent compiler in case of
666 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
667 * and single-hop-direct-link scenario. Ingress VLAN. No egress VLAN.
668 */
669 @Test
670 public void testVlanEncapCompileSingleHopDirectIngressVlan() {
671 sut.activate();
672
673 List<Intent> compiled = sut.compile(singleHopDirectIntentIngressVlan, Collections.emptyList());
674 assertThat(compiled, hasSize(1));
675
676 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
677 assertThat(rules, hasSize(1));
678
679
680 FlowRule rule = rules.stream()
681 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
682 .findFirst()
683 .get();
684 verifyIdAndPriority(rule, d2p4.deviceId());
685
686 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
687 .matchVlanId(ingressVlan).build()));
688 assertThat(rule.treatment(),
689 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
690
691 sut.deactivate();
692 }
693
694 /**
695 * Tests the compilation behavior of the path intent compiler in case of
696 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
697 * and single-hop-direct-link scenario. No ingress VLAN. Egress VLAN.
698 */
699 @Test
700 public void testVlanEncapCompileSingleHopDirectEgressVlan() {
701 sut.activate();
702
703 List<Intent> compiled = sut.compile(singleHopDirectIntentEgressVlan, Collections.emptyList());
704 assertThat(compiled, hasSize(1));
705
706 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
707 assertThat(rules, hasSize(1));
708
709
710 FlowRule rule = rules.stream()
711 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
712 .findFirst()
713 .get();
714 verifyIdAndPriority(rule, d2p4.deviceId());
715
716 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
717 .build()));
718 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
719 .setOutput(d2p5.port()).build()));
720
721 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
722 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
723 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
724 .collect(Collectors.toSet());
725 assertThat(rule.treatment().allInstructions().stream()
726 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
727 .collect(Collectors.toSet()), hasSize(1));
728 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
729 assertThat(rule.treatment().allInstructions().stream()
730 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
731 .collect(Collectors.toSet()), hasSize(0));
732
733 sut.deactivate();
734 }
735
736 /**
737 * Tests the compilation behavior of the path intent compiler in case of
738 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
739 * and single-hop-direct-link scenario. Ingress VLAN. Egress VLAN.
740 */
741 @Test
742 public void testVlanEncapCompileSingleHopDirectVlan() {
743 sut.activate();
744
745 List<Intent> compiled = sut.compile(singleHopDirectIntentVlan, Collections.emptyList());
746 assertThat(compiled, hasSize(1));
747
748 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
749 assertThat(rules, hasSize(1));
750
751
752 FlowRule rule = rules.stream()
753 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
754 .findFirst()
755 .get();
756 verifyIdAndPriority(rule, d2p4.deviceId());
757
758 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
759 .matchVlanId(ingressVlan).build()));
760 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
761 .setOutput(d2p5.port()).build()));
762
763 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
764 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
765 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
766 .collect(Collectors.toSet());
767 assertThat(rule.treatment().allInstructions().stream()
768 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
769 .collect(Collectors.toSet()), hasSize(1));
770 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
771 assertThat(rule.treatment().allInstructions().stream()
772 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
773 .collect(Collectors.toSet()), hasSize(0));
774
775 sut.deactivate();
776 }
777
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800778 /**
779 * Tests the compilation behavior of the path intent compiler.
780 */
781 @Test
782 public void testCompile() {
783 sut.activate();
784
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800785 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800786 assertThat(compiled, hasSize(1));
787
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700788 assertThat("key is inherited",
789 compiled.stream().map(Intent::key).collect(Collectors.toList()),
790 everyItem(is(intent.key())));
791
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800792 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
793
794 FlowRule rule1 = rules.stream()
795 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
796 .findFirst()
797 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100798 verifyIdAndPriority(rule1, d1p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800799 assertThat(rule1.selector(),
800 is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
801 assertThat(rule1.treatment(),
802 is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
Michele Santuari6096acd2016-02-09 17:00:37 +0100803
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800804
805 FlowRule rule2 = rules.stream()
806 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
807 .findFirst()
808 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100809 verifyIdAndPriority(rule2, d2p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800810 assertThat(rule2.selector(),
811 is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
812 assertThat(rule2.treatment(),
813 is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
814
815 FlowRule rule3 = rules.stream()
816 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
817 .findFirst()
818 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100819 verifyIdAndPriority(rule3, d3p1.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800820 assertThat(rule3.selector(),
821 is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
822 assertThat(rule3.treatment(),
823 is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800824
825 sut.deactivate();
826 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100827
828 /**
829 * Tests the compilation behavior of the path intent compiler in case of
Michele Santuari3ea53902016-02-15 11:21:56 +0100830 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100831 */
832 @Test
Michele Santuari6096acd2016-02-09 17:00:37 +0100833 public void testVlanEncapCompile() {
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100834 sut.activate();
835
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800836 List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100837 assertThat(compiled, hasSize(1));
838
839 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
840 assertThat(rules, hasSize(3));
841
842 FlowRule rule1 = rules.stream()
843 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
844 .findFirst()
845 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100846 verifyIdAndPriority(rule1, d1p0.deviceId());
847 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
848 .matchInPort(d1p0.port()).build()));
849 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100850
851 FlowRule rule2 = rules.stream()
852 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
853 .findFirst()
854 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100855 verifyIdAndPriority(rule2, d2p0.deviceId());
856 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200857 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100858
859 FlowRule rule3 = rules.stream()
860 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
861 .findFirst()
862 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100863 verifyIdAndPriority(rule3, d3p1.deviceId());
864 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
865 verifyVlanEncapTreatment(rule3.treatment(), d3p0, false, true);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100866
867 sut.deactivate();
868 }
869
Michele Santuari3ea53902016-02-15 11:21:56 +0100870 /**
871 * Tests the compilation behavior of the path intent compiler in case of
872 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
873 * This test includes a selector to match a VLAN at the ingress and a treatment to set VLAN at the egress.
874 */
875 @Test
876 public void testEncapIngressEgressVlansCompile() {
877 sut.activate();
878
879 List<Intent> compiled = sut.compile(constrainIngressEgressVlanIntent,
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800880 Collections.emptyList());
Michele Santuari3ea53902016-02-15 11:21:56 +0100881 assertThat(compiled, hasSize(1));
882
883 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
884 assertThat(rules, hasSize(3));
885
886 FlowRule rule1 = rules.stream()
887 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
888 .findFirst()
889 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100890 verifyIdAndPriority(rule1, d1p0.deviceId());
891 verifyVlanEncapSelector(rule1.selector(), d1p0, ingressVlan);
892 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100893
894 FlowRule rule2 = rules.stream()
895 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
896 .findFirst()
897 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100898 verifyIdAndPriority(rule2, d2p0.deviceId());
899 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200900 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100901
902 FlowRule rule3 = rules.stream()
903 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
904 .findFirst()
905 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100906 verifyIdAndPriority(rule3, d3p1.deviceId());
907 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
Michele Santuari3ea53902016-02-15 11:21:56 +0100908 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream()
909 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
910 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
911 .collect(Collectors.toSet());
912 assertThat(rule3.treatment().allInstructions().stream()
913 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
914 .collect(Collectors.toSet()), hasSize(1));
915 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
916 assertThat(rule3.treatment().allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -0700917 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari3ea53902016-02-15 11:21:56 +0100918 .collect(Collectors.toSet()), hasSize(0));
919
920 sut.deactivate();
921 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100922
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200923 /**
Pier Ventref8543d82016-09-28 19:49:33 -0700924 * Tests the random selection of VLAN Ids in the PathCompiler.
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200925 * It can fail randomly (it is unlikely)
926 */
927 @Test
928 public void testRandomVlanSelection() {
929
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200930 sut.activate();
931
932 List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
933 assertThat(compiled, hasSize(1));
934
935 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
936 assertThat(rules, hasSize(3));
937
938 FlowRule rule1 = rules.stream()
939 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
940 .findFirst()
941 .get();
942 verifyIdAndPriority(rule1, d1p0.deviceId());
943 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
944 .matchInPort(d1p0.port()).build()));
945
946 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
947
948 assertTrue(VlanId.NO_VID < vlanToEncap.toShort() && vlanToEncap.toShort() < VlanId.MAX_VLAN);
949
Sho SHIMIZU3437bdb2016-08-12 14:57:37 -0700950 /*
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200951 * This second part is meant to test if the random selection is working properly.
952 * We are compiling the same intent in order to verify if the VLAN ID is different
953 * from the previous one.
954 */
955
956 List<Intent> compiled2 = sut.compile(constraintVlanIntent, Collections.emptyList());
957 assertThat(compiled2, hasSize(1));
958
959 Collection<FlowRule> rules2 = ((FlowRuleIntent) compiled2.get(0)).flowRules();
960 assertThat(rules2, hasSize(3));
961
962 FlowRule rule2 = rules2.stream()
963 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
964 .findFirst()
965 .get();
966 verifyIdAndPriority(rule2, d1p0.deviceId());
967 assertThat(rule2.selector(), is(DefaultTrafficSelector.builder(selector)
968 .matchInPort(d1p0.port()).build()));
969
970 VlanId vlanToEncap2 = verifyVlanEncapTreatment(rule2.treatment(), d1p1, true, false);
971
972 assertTrue(VlanId.NO_VID < vlanToEncap2.toShort() && vlanToEncap2.toShort() < VlanId.MAX_VLAN);
973 assertNotEquals(vlanToEncap, vlanToEncap2);
974
975 sut.deactivate();
976
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200977
978 }
979
Michele Santuari6096acd2016-02-09 17:00:37 +0100980 private VlanId verifyVlanEncapTreatment(TrafficTreatment trafficTreatment,
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100981 ConnectPoint egress, boolean isIngress, boolean isEgress) {
982 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
983 .filter(treat -> treat instanceof Instructions.OutputInstruction)
984 .map(treat -> (Instructions.OutputInstruction) treat)
985 .collect(Collectors.toSet());
986 assertThat(ruleOutput, hasSize(1));
987 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
988 VlanId vlanToEncap = VlanId.NONE;
989 if (isIngress && !isEgress) {
990 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
991 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
992 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
993 .collect(Collectors.toSet());
994 assertThat(vlanRules, hasSize(1));
995 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700996 assertThat(vlanRule.vlanId().toShort(), greaterThan(VlanId.NO_VID));
997 assertThat(vlanRule.vlanId().toShort(), lessThan(VlanId.MAX_VLAN));
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100998 vlanToEncap = vlanRule.vlanId();
999 } else if (!isIngress && !isEgress) {
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +02001000
1001 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
1002 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
1003 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
1004 .collect(Collectors.toSet());
1005 assertThat(vlanRules, hasSize(1));
1006 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -07001007 assertThat(vlanRule.vlanId().toShort(), greaterThan(VlanId.NO_VID));
1008 assertThat(vlanRule.vlanId().toShort(), lessThan(VlanId.MAX_VLAN));
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +02001009 vlanToEncap = vlanRule.vlanId();
1010
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001011 } else {
1012 assertThat(trafficTreatment.allInstructions().stream()
1013 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
1014 .collect(Collectors.toSet()), hasSize(0));
1015 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001016 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001017 .collect(Collectors.toSet()), hasSize(1));
1018
1019 }
1020
1021 return vlanToEncap;
1022
1023 }
1024
Michele Santuari6096acd2016-02-09 17:00:37 +01001025 private void verifyVlanEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) {
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001026
Michele Santuari6096acd2016-02-09 17:00:37 +01001027 assertThat(trafficSelector, is(DefaultTrafficSelector.builder().matchInPort(ingress.port())
1028 .matchVlanId(vlanToMatch).build()));
1029 }
1030
1031 /**
1032 * Tests the compilation behavior of the path intent compiler in case of
1033 * encasulation costraint {@link EncapsulationConstraint}.
1034 */
1035 @Test
1036 public void testMplsEncapCompile() {
1037 sut.activate();
1038
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -08001039 List<Intent> compiled = sut.compile(constraintMplsIntent, Collections.emptyList());
Michele Santuari6096acd2016-02-09 17:00:37 +01001040 assertThat(compiled, hasSize(1));
1041
1042 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
1043 assertThat(rules, hasSize(3));
1044
1045 FlowRule rule1 = rules.stream()
1046 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
1047 .findFirst()
1048 .get();
1049 verifyIdAndPriority(rule1, d1p0.deviceId());
Pier Ventref8543d82016-09-28 19:49:33 -07001050 assertThat(rule1.selector(), is(DefaultTrafficSelector
1051 .builder(selector)
1052 .matchInPort(d1p0.port())
1053 .build()));
Michele Santuari6096acd2016-02-09 17:00:37 +01001054 MplsLabel mplsLabelToEncap = verifyMplsEncapTreatment(rule1.treatment(), d1p1, true, false);
1055
1056 FlowRule rule2 = rules.stream()
1057 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
1058 .findFirst()
1059 .get();
1060 verifyIdAndPriority(rule2, d2p0.deviceId());
1061 verifyMplsEncapSelector(rule2.selector(), d2p0, mplsLabelToEncap);
Pier Ventref8543d82016-09-28 19:49:33 -07001062 mplsLabelToEncap = verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari6096acd2016-02-09 17:00:37 +01001063
1064 FlowRule rule3 = rules.stream()
1065 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
1066 .findFirst()
1067 .get();
1068 verifyIdAndPriority(rule3, d3p1.deviceId());
1069 verifyMplsEncapSelector(rule3.selector(), d3p1, mplsLabelToEncap);
1070 verifyMplsEncapTreatment(rule3.treatment(), d3p0, false, true);
1071
1072 sut.deactivate();
1073 }
1074
1075
1076 private MplsLabel verifyMplsEncapTreatment(TrafficTreatment trafficTreatment,
1077 ConnectPoint egress, boolean isIngress, boolean isEgress) {
1078 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
1079 .filter(treat -> treat instanceof Instructions.OutputInstruction)
1080 .map(treat -> (Instructions.OutputInstruction) treat)
1081 .collect(Collectors.toSet());
1082 assertThat(ruleOutput, hasSize(1));
1083 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
1084 MplsLabel mplsToEncap = MplsLabel.mplsLabel(0);
1085 if (isIngress && !isEgress) {
Pier Ventref8543d82016-09-28 19:49:33 -07001086 Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
1087 .allInstructions()
1088 .stream()
1089 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1090 .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
1091 .collect(Collectors.toSet());
Michele Santuari6096acd2016-02-09 17:00:37 +01001092 assertThat(mplsRules, hasSize(1));
1093 L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
Pier Ventref8543d82016-09-28 19:49:33 -07001094 assertThat(mplsRule.label().toInt(), greaterThan(0));
1095 assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
1096 mplsToEncap = mplsRule.label();
Michele Santuari6096acd2016-02-09 17:00:37 +01001097 } else if (!isIngress && !isEgress) {
Pier Ventref8543d82016-09-28 19:49:33 -07001098 Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
1099 .allInstructions()
1100 .stream()
1101 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1102 .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
1103 .collect(Collectors.toSet());
1104 assertThat(mplsRules, hasSize(1));
1105 L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
1106 assertThat(mplsRule.label().toInt(), greaterThan(0));
1107 assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
1108 mplsToEncap = mplsRule.label();
Michele Santuari6096acd2016-02-09 17:00:37 +01001109 } else {
1110 assertThat(trafficTreatment.allInstructions().stream()
1111 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1112 .collect(Collectors.toSet()), hasSize(0));
1113 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001114 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsHeaderInstruction)
Michele Santuari6096acd2016-02-09 17:00:37 +01001115 .collect(Collectors.toSet()), hasSize(1));
1116
1117 }
Michele Santuari6096acd2016-02-09 17:00:37 +01001118 return mplsToEncap;
1119
1120 }
1121
1122 private void verifyMplsEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, MplsLabel mplsLabel) {
1123
1124 assertThat(trafficSelector, is(DefaultTrafficSelector.builder()
1125 .matchInPort(ingress.port()).matchEthType(Ethernet.MPLS_UNICAST)
1126 .matchMplsLabel(mplsLabel).build()));
1127 }
1128
1129 private void verifyIdAndPriority(FlowRule rule, DeviceId deviceId) {
1130 assertThat(rule.deviceId(), is(deviceId));
1131 assertThat(rule.priority(), is(PRIORITY));
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001132 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001133}