blob: c88082325f7f033ae8096b89da89af3c7e5950fc [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;
50
Michele Santuari69fc2ff2015-12-03 17:05:35 +010051import java.util.Arrays;
52import java.util.Collection;
53import java.util.Collections;
54import java.util.List;
55import java.util.Set;
56import java.util.stream.Collectors;
57
Michele Santuari6096acd2016-02-09 17:00:37 +010058import static org.easymock.EasyMock.createMock;
59import static org.easymock.EasyMock.expect;
60import static org.easymock.EasyMock.replay;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080061import static org.hamcrest.MatcherAssert.assertThat;
62import static org.hamcrest.Matchers.hasSize;
63import static org.hamcrest.Matchers.is;
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +020064import static org.hamcrest.Matchers.lessThan;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010065import static org.hamcrest.number.OrderingComparison.greaterThan;
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +020066import static org.junit.Assert.assertNotEquals;
67import static org.junit.Assert.assertTrue;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080068import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
69import static org.onosproject.net.Link.Type.DIRECT;
Pier1677f9f2016-07-06 15:42:17 +020070import static org.onosproject.net.Link.Type.INDIRECT;
Michele Santuari6096acd2016-02-09 17:00:37 +010071import static org.onosproject.net.NetTestTools.APP_ID;
72import static org.onosproject.net.NetTestTools.PID;
73import static org.onosproject.net.NetTestTools.connectPoint;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080074
75/**
76 * Unit tests for PathIntentCompiler.
77 */
78public class PathIntentCompilerTest {
79
80 private CoreService coreService;
81 private IntentExtensionService intentExtensionService;
Thomas Vachuskabdbdd242016-03-01 01:55:55 -080082 private IntentConfigurableRegistrator registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080083 private IdGenerator idGenerator = new MockIdGenerator();
84 private PathIntentCompiler sut;
85
86 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
87 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
Michele Santuari3ea53902016-02-15 11:21:56 +010088 private final VlanId ingressVlan = VlanId.vlanId(((short) 101));
89 private final TrafficSelector vlanSelector = DefaultTrafficSelector.builder()
90 .matchVlanId(ingressVlan).build();
91 private final VlanId egressVlan = VlanId.vlanId((short) 100);
92 private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment.builder()
93 .setVlanId(egressVlan).build();
94
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080095 private final ApplicationId appId = new TestApplicationId("test");
96 private final ProviderId pid = new ProviderId("of", "test");
Pier1677f9f2016-07-06 15:42:17 +020097
98 // Edge scenario
99 private final ConnectPoint d1p2 = connectPoint("s1", 2);
100 private final ConnectPoint d1p3 = connectPoint("s1", 3);
101 private final List<Link> edgeNet = Arrays.asList(
102 createEdgeLink(d1p2, true),
103 createEdgeLink(d1p3, false)
104 );
105 private final int edgeHops = edgeNet.size() - 1;
106 private PathIntent edgeIntentNoVlan;
107 private PathIntent edgeIntentIngressVlan;
108 private PathIntent edgeIntentEgressVlan;
109 private PathIntent edgeIntentVlan;
110
111 // Single-hop scenario - indirect
112 private final ConnectPoint d1p4 = connectPoint("s1", 4);
113 private final ConnectPoint d2p2 = connectPoint("s2", 2);
114 private final ConnectPoint d2p3 = connectPoint("s2", 3);
115 private final ConnectPoint d3p2 = connectPoint("s3", 2);
116 private final List<Link> singleHopIndirect = Arrays.asList(
117 DefaultLink.builder().providerId(PID).src(d1p4).dst(d2p2).type(DIRECT).build(),
118 DefaultLink.builder().providerId(PID).src(d2p3).dst(d3p2).type(INDIRECT).build()
119 );
120 private final int singleHopIndirectHops = singleHopIndirect.size() - 1;
121 private PathIntent singleHopIndirectIntentNoVlan;
122 private PathIntent singleHopIndirectIntentIngressVlan;
123 private PathIntent singleHopIndirectIntentEgressVlan;
124 private PathIntent singleHopIndirectIntentVlan;
125
126
127 // Single-hop scenario- direct
128 private final ConnectPoint d1p5 = connectPoint("s1", 5);
129 private final ConnectPoint d2p4 = connectPoint("s2", 4);
130 private final ConnectPoint d2p5 = connectPoint("s2", 5);
131 private final ConnectPoint d3p3 = connectPoint("s3", 3);
132 private final List<Link> singleHopDirect = Arrays.asList(
133 DefaultLink.builder().providerId(PID).src(d1p5).dst(d2p4).type(DIRECT).build(),
134 DefaultLink.builder().providerId(PID).src(d2p5).dst(d3p3).type(DIRECT).build()
135 );
136 private final int singleHopDirectHops = singleHopDirect.size() - 1;
137 private PathIntent singleHopDirectIntentNoVlan;
138 private PathIntent singleHopDirectIntentIngressVlan;
139 private PathIntent singleHopDirectIntentEgressVlan;
140 private PathIntent singleHopDirectIntentVlan;
141
142
143 // Multi-hop scenario
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800144 private final ConnectPoint d1p1 = connectPoint("s1", 0);
145 private final ConnectPoint d2p0 = connectPoint("s2", 0);
146 private final ConnectPoint d2p1 = connectPoint("s2", 1);
147 private final ConnectPoint d3p1 = connectPoint("s3", 1);
148 private final ConnectPoint d3p0 = connectPoint("s3", 10);
149 private final ConnectPoint d1p0 = connectPoint("s1", 10);
Brian O'Connor81134662015-06-25 17:23:33 -0400150 private static final int PRIORITY = 555;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800151
152 private final List<Link> links = Arrays.asList(
153 createEdgeLink(d1p0, true),
Ray Milkey2693bda2016-01-22 16:08:14 -0800154 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
155 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800156 createEdgeLink(d3p0, false)
157 );
158 private final int hops = links.size() - 1;
159 private PathIntent intent;
Michele Santuari6096acd2016-02-09 17:00:37 +0100160 private PathIntent constraintVlanIntent;
Michele Santuari3ea53902016-02-15 11:21:56 +0100161 private PathIntent constrainIngressEgressVlanIntent;
Michele Santuari6096acd2016-02-09 17:00:37 +0100162 private PathIntent constraintMplsIntent;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800163
164 /**
165 * Configures objects used in all the test cases.
166 */
167 @Before
168 public void setUp() {
169 sut = new PathIntentCompiler();
170 coreService = createMock(CoreService.class);
171 expect(coreService.registerApplication("org.onosproject.net.intent"))
172 .andReturn(appId);
173 sut.coreService = coreService;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100174 sut.resourceService = new MockResourceService();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800175
176 Intent.bindIdGenerator(idGenerator);
177
178 intent = PathIntent.builder()
179 .appId(APP_ID)
180 .selector(selector)
181 .treatment(treatment)
Brian O'Connor81134662015-06-25 17:23:33 -0400182 .priority(PRIORITY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800183 .path(new DefaultPath(pid, links, hops))
184 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100185
Michele Santuari3ea53902016-02-15 11:21:56 +0100186 //Intent with VLAN encap without egress VLAN
Michele Santuari6096acd2016-02-09 17:00:37 +0100187 constraintVlanIntent = PathIntent.builder()
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100188 .appId(APP_ID)
189 .selector(selector)
190 .treatment(treatment)
191 .priority(PRIORITY)
192 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
193 .path(new DefaultPath(pid, links, hops))
194 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100195
Michele Santuari3ea53902016-02-15 11:21:56 +0100196 //Intent with VLAN encap with ingress and egress VLAN
197 constrainIngressEgressVlanIntent = PathIntent.builder()
198 .appId(APP_ID)
199 .selector(vlanSelector)
200 .treatment(vlanTreatment)
201 .priority(PRIORITY)
202 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
203 .path(new DefaultPath(pid, links, hops))
204 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100205
206 constraintMplsIntent = PathIntent.builder()
207 .appId(APP_ID)
208 .selector(selector)
209 .treatment(treatment)
210 .priority(PRIORITY)
211 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.MPLS)))
212 .path(new DefaultPath(pid, links, hops))
213 .build();
Pier1677f9f2016-07-06 15:42:17 +0200214
215 edgeIntentNoVlan = PathIntent.builder()
216 .appId(APP_ID)
217 .selector(selector)
218 .treatment(treatment)
219 .priority(PRIORITY)
220 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
221 .path(new DefaultPath(pid, edgeNet, edgeHops))
222 .build();
223
224 edgeIntentIngressVlan = PathIntent.builder()
225 .appId(APP_ID)
226 .selector(vlanSelector)
227 .treatment(treatment)
228 .priority(PRIORITY)
229 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
230 .path(new DefaultPath(pid, edgeNet, edgeHops))
231 .build();
232
233 edgeIntentEgressVlan = PathIntent.builder()
234 .appId(APP_ID)
235 .selector(selector)
236 .treatment(vlanTreatment)
237 .priority(PRIORITY)
238 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
239 .path(new DefaultPath(pid, edgeNet, edgeHops))
240 .build();
241
242 edgeIntentVlan = PathIntent.builder()
243 .appId(APP_ID)
244 .selector(vlanSelector)
245 .treatment(vlanTreatment)
246 .priority(PRIORITY)
247 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
248 .path(new DefaultPath(pid, edgeNet, edgeHops))
249 .build();
250
251 singleHopIndirectIntentNoVlan = PathIntent.builder()
252 .appId(APP_ID)
253 .selector(selector)
254 .treatment(treatment)
255 .priority(PRIORITY)
256 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
257 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
258 .build();
259
260 singleHopIndirectIntentIngressVlan = PathIntent.builder()
261 .appId(APP_ID)
262 .selector(vlanSelector)
263 .treatment(treatment)
264 .priority(PRIORITY)
265 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
266 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
267 .build();
268
269 singleHopIndirectIntentEgressVlan = PathIntent.builder()
270 .appId(APP_ID)
271 .selector(selector)
272 .treatment(vlanTreatment)
273 .priority(PRIORITY)
274 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
275 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
276 .build();
277
278 singleHopIndirectIntentVlan = PathIntent.builder()
279 .appId(APP_ID)
280 .selector(vlanSelector)
281 .treatment(vlanTreatment)
282 .priority(PRIORITY)
283 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
284 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
285 .build();
286
287 singleHopDirectIntentNoVlan = PathIntent.builder()
288 .appId(APP_ID)
289 .selector(selector)
290 .treatment(treatment)
291 .priority(PRIORITY)
292 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
293 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
294 .build();
295
296 singleHopDirectIntentIngressVlan = PathIntent.builder()
297 .appId(APP_ID)
298 .selector(vlanSelector)
299 .treatment(treatment)
300 .priority(PRIORITY)
301 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
302 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
303 .build();
304
305 singleHopDirectIntentEgressVlan = PathIntent.builder()
306 .appId(APP_ID)
307 .selector(selector)
308 .treatment(vlanTreatment)
309 .priority(PRIORITY)
310 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
311 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
312 .build();
313
314 singleHopDirectIntentVlan = PathIntent.builder()
315 .appId(APP_ID)
316 .selector(vlanSelector)
317 .treatment(vlanTreatment)
318 .priority(PRIORITY)
319 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
320 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
321 .build();
322
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800323 intentExtensionService = createMock(IntentExtensionService.class);
324 intentExtensionService.registerCompiler(PathIntent.class, sut);
325 intentExtensionService.unregisterCompiler(PathIntent.class);
Thomas Vachuskabdbdd242016-03-01 01:55:55 -0800326
327 registrator = new IntentConfigurableRegistrator();
328 registrator.extensionService = intentExtensionService;
329 registrator.cfgService = new ComponentConfigAdapter();
330 registrator.activate();
331
332 sut.registrator = registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800333
334 replay(coreService, intentExtensionService);
335 }
336
337 /**
338 * Tears down objects used in all the test cases.
339 */
340 @After
341 public void tearDown() {
342 Intent.unbindIdGenerator(idGenerator);
343 }
344
Pier1677f9f2016-07-06 15:42:17 +0200345
346 /**
347 * Tests the compilation behavior of the path intent compiler in case of
348 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
349 * and edge communication. No ingress VLAN. No egress VLAN.
350 */
351 @Test
352 public void testVlanEncapCompileEdgeNoVlan() {
353 sut.activate();
354
355 List<Intent> compiled = sut.compile(edgeIntentNoVlan, Collections.emptyList());
356 assertThat(compiled, hasSize(1));
357
358 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
359 assertThat(rules, hasSize(1));
360
361 FlowRule rule = rules.stream()
362 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
363 .findFirst()
364 .get();
365 verifyIdAndPriority(rule, d1p2.deviceId());
366
367 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
368 .build()));
369 assertThat(rule.treatment(),
370 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
371
372 sut.deactivate();
373 }
374
375 /**
376 * Tests the compilation behavior of the path intent compiler in case of
377 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
378 * and edge communication. Ingress VLAN. No egress VLAN.
379 */
380 @Test
381 public void testVlanEncapCompileEdgeIngressVlan() {
382 sut.activate();
383
384 List<Intent> compiled = sut.compile(edgeIntentIngressVlan, Collections.emptyList());
385 assertThat(compiled, hasSize(1));
386
387 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
388 assertThat(rules, hasSize(1));
389
390 FlowRule rule = rules.stream()
391 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
392 .findFirst()
393 .get();
394 verifyIdAndPriority(rule, d1p2.deviceId());
395
396 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
397 .matchVlanId(ingressVlan).build()));
398 assertThat(rule.treatment(),
399 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
400
401 sut.deactivate();
402 }
403
404 /**
405 * Tests the compilation behavior of the path intent compiler in case of
406 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
407 * and edge communication. No ingress VLAN. Egress VLAN.
408 */
409 @Test
410 public void testVlanEncapCompileEdgeEgressVlan() {
411 sut.activate();
412
413 List<Intent> compiled = sut.compile(edgeIntentEgressVlan, Collections.emptyList());
414 assertThat(compiled, hasSize(1));
415
416 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
417 assertThat(rules, hasSize(1));
418
419 FlowRule rule = rules.stream()
420 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
421 .findFirst()
422 .get();
423 verifyIdAndPriority(rule, d1p2.deviceId());
424
425 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
426 .build()));
427 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
428 .setOutput(d1p3.port()).build()));
429
430 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
431 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
432 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
433 .collect(Collectors.toSet());
434 assertThat(rule.treatment().allInstructions().stream()
435 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
436 .collect(Collectors.toSet()), hasSize(1));
437 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
438 assertThat(rule.treatment().allInstructions().stream()
439 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
440 .collect(Collectors.toSet()), hasSize(0));
441
442 sut.deactivate();
443 }
444
445 /**
446 * Tests the compilation behavior of the path intent compiler in case of
447 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
448 * and edge communication. Ingress VLAN. Egress VLAN.
449 */
450 @Test
451 public void testVlanEncapCompileEdgeVlan() {
452 sut.activate();
453
454 List<Intent> compiled = sut.compile(edgeIntentVlan, Collections.emptyList());
455 assertThat(compiled, hasSize(1));
456
457 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
458 assertThat(rules, hasSize(1));
459
460 FlowRule rule = rules.stream()
461 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
462 .findFirst()
463 .get();
464 verifyIdAndPriority(rule, d1p2.deviceId());
465
466 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
467 .matchVlanId(ingressVlan).build()));
468 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
469 .setOutput(d1p3.port()).build()));
470
471 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
472 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
473 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
474 .collect(Collectors.toSet());
475 assertThat(rule.treatment().allInstructions().stream()
476 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
477 .collect(Collectors.toSet()), hasSize(1));
478 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
479 assertThat(rule.treatment().allInstructions().stream()
480 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
481 .collect(Collectors.toSet()), hasSize(0));
482
483 sut.deactivate();
484 }
485
486 /**
487 * Tests the compilation behavior of the path intent compiler in case of
488 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
489 * and single-hop-indirect-link scenario. No ingress VLAN. No egress VLAN.
490 */
491 @Test
492 public void testVlanEncapCompileSingleHopIndirectNoVlan() {
493 sut.activate();
494
495 List<Intent> compiled = sut.compile(singleHopIndirectIntentNoVlan, Collections.emptyList());
496 assertThat(compiled, hasSize(1));
497
498 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
499 assertThat(rules, hasSize(1));
500
501
502 FlowRule rule = rules.stream()
503 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
504 .findFirst()
505 .get();
506 verifyIdAndPriority(rule, d2p2.deviceId());
507
508 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
509 .build()));
510 assertThat(rule.treatment(),
511 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
512
513 sut.deactivate();
514 }
515
516 /**
517 * Tests the compilation behavior of the path intent compiler in case of
518 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
519 * and single-hop-indirect-link scenario. Ingress VLAN. No egress VLAN.
520 */
521 @Test
522 public void testVlanEncapCompileSingleHopIndirectIngressVlan() {
523 sut.activate();
524
525 List<Intent> compiled = sut.compile(singleHopIndirectIntentIngressVlan, Collections.emptyList());
526 assertThat(compiled, hasSize(1));
527
528 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
529 assertThat(rules, hasSize(1));
530
531
532 FlowRule rule = rules.stream()
533 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
534 .findFirst()
535 .get();
536 verifyIdAndPriority(rule, d2p2.deviceId());
537
538 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
539 .matchVlanId(ingressVlan).build()));
540 assertThat(rule.treatment(),
541 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
542
543 sut.deactivate();
544 }
545
546 /**
547 * Tests the compilation behavior of the path intent compiler in case of
548 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
549 * and single-hop-indirect-link scenario. No ingress VLAN. Egress VLAN.
550 */
551 @Test
552 public void testVlanEncapCompileSingleHopIndirectEgressVlan() {
553 sut.activate();
554
555 List<Intent> compiled = sut.compile(singleHopIndirectIntentEgressVlan, Collections.emptyList());
556 assertThat(compiled, hasSize(1));
557
558 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
559 assertThat(rules, hasSize(1));
560
561
562 FlowRule rule = rules.stream()
563 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
564 .findFirst()
565 .get();
566 verifyIdAndPriority(rule, d2p2.deviceId());
567
568 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
569 .build()));
570 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
571 .setOutput(d2p3.port()).build()));
572
573 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
574 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
575 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
576 .collect(Collectors.toSet());
577 assertThat(rule.treatment().allInstructions().stream()
578 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
579 .collect(Collectors.toSet()), hasSize(1));
580 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
581 assertThat(rule.treatment().allInstructions().stream()
582 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
583 .collect(Collectors.toSet()), hasSize(0));
584
585 sut.deactivate();
586 }
587
588 /**
589 * Tests the compilation behavior of the path intent compiler in case of
590 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
591 * and single-hop-indirect-link scenario. Ingress VLAN. Egress VLAN.
592 */
593 @Test
594 public void testVlanEncapCompileSingleHopIndirectVlan() {
595 sut.activate();
596
597 List<Intent> compiled = sut.compile(singleHopIndirectIntentVlan, Collections.emptyList());
598 assertThat(compiled, hasSize(1));
599
600 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
601 assertThat(rules, hasSize(1));
602
603
604 FlowRule rule = rules.stream()
605 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
606 .findFirst()
607 .get();
608 verifyIdAndPriority(rule, d2p2.deviceId());
609
610 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
611 .matchVlanId(ingressVlan).build()));
612 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
613 .setOutput(d2p3.port()).build()));
614
615 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
616 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
617 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
618 .collect(Collectors.toSet());
619 assertThat(rule.treatment().allInstructions().stream()
620 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
621 .collect(Collectors.toSet()), hasSize(1));
622 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
623 assertThat(rule.treatment().allInstructions().stream()
624 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
625 .collect(Collectors.toSet()), hasSize(0));
626
627 sut.deactivate();
628 }
629
630 /**
631 * Tests the compilation behavior of the path intent compiler in case of
632 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
633 * and single-hop-direct-link scenario. No ingress VLAN. No egress VLAN.
634 */
635 @Test
636 public void testVlanEncapCompileSingleHopDirectNoVlan() {
637 sut.activate();
638
639 List<Intent> compiled = sut.compile(singleHopDirectIntentNoVlan, Collections.emptyList());
640 assertThat(compiled, hasSize(1));
641
642 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
643 assertThat(rules, hasSize(1));
644
645
646 FlowRule rule = rules.stream()
647 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
648 .findFirst()
649 .get();
650 verifyIdAndPriority(rule, d2p4.deviceId());
651
652 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
653 .build()));
654 assertThat(rule.treatment(),
655 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
656
657 sut.deactivate();
658 }
659
660 /**
661 * Tests the compilation behavior of the path intent compiler in case of
662 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
663 * and single-hop-direct-link scenario. Ingress VLAN. No egress VLAN.
664 */
665 @Test
666 public void testVlanEncapCompileSingleHopDirectIngressVlan() {
667 sut.activate();
668
669 List<Intent> compiled = sut.compile(singleHopDirectIntentIngressVlan, Collections.emptyList());
670 assertThat(compiled, hasSize(1));
671
672 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
673 assertThat(rules, hasSize(1));
674
675
676 FlowRule rule = rules.stream()
677 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
678 .findFirst()
679 .get();
680 verifyIdAndPriority(rule, d2p4.deviceId());
681
682 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
683 .matchVlanId(ingressVlan).build()));
684 assertThat(rule.treatment(),
685 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
686
687 sut.deactivate();
688 }
689
690 /**
691 * Tests the compilation behavior of the path intent compiler in case of
692 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
693 * and single-hop-direct-link scenario. No ingress VLAN. Egress VLAN.
694 */
695 @Test
696 public void testVlanEncapCompileSingleHopDirectEgressVlan() {
697 sut.activate();
698
699 List<Intent> compiled = sut.compile(singleHopDirectIntentEgressVlan, Collections.emptyList());
700 assertThat(compiled, hasSize(1));
701
702 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
703 assertThat(rules, hasSize(1));
704
705
706 FlowRule rule = rules.stream()
707 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
708 .findFirst()
709 .get();
710 verifyIdAndPriority(rule, d2p4.deviceId());
711
712 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
713 .build()));
714 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
715 .setOutput(d2p5.port()).build()));
716
717 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
718 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
719 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
720 .collect(Collectors.toSet());
721 assertThat(rule.treatment().allInstructions().stream()
722 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
723 .collect(Collectors.toSet()), hasSize(1));
724 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
725 assertThat(rule.treatment().allInstructions().stream()
726 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
727 .collect(Collectors.toSet()), hasSize(0));
728
729 sut.deactivate();
730 }
731
732 /**
733 * Tests the compilation behavior of the path intent compiler in case of
734 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
735 * and single-hop-direct-link scenario. Ingress VLAN. Egress VLAN.
736 */
737 @Test
738 public void testVlanEncapCompileSingleHopDirectVlan() {
739 sut.activate();
740
741 List<Intent> compiled = sut.compile(singleHopDirectIntentVlan, Collections.emptyList());
742 assertThat(compiled, hasSize(1));
743
744 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
745 assertThat(rules, hasSize(1));
746
747
748 FlowRule rule = rules.stream()
749 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
750 .findFirst()
751 .get();
752 verifyIdAndPriority(rule, d2p4.deviceId());
753
754 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
755 .matchVlanId(ingressVlan).build()));
756 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
757 .setOutput(d2p5.port()).build()));
758
759 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
760 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
761 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
762 .collect(Collectors.toSet());
763 assertThat(rule.treatment().allInstructions().stream()
764 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
765 .collect(Collectors.toSet()), hasSize(1));
766 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
767 assertThat(rule.treatment().allInstructions().stream()
768 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
769 .collect(Collectors.toSet()), hasSize(0));
770
771 sut.deactivate();
772 }
773
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800774 /**
775 * Tests the compilation behavior of the path intent compiler.
776 */
777 @Test
778 public void testCompile() {
779 sut.activate();
780
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800781 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800782 assertThat(compiled, hasSize(1));
783
784 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
785
786 FlowRule rule1 = rules.stream()
787 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
788 .findFirst()
789 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100790 verifyIdAndPriority(rule1, d1p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800791 assertThat(rule1.selector(),
792 is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
793 assertThat(rule1.treatment(),
794 is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
Michele Santuari6096acd2016-02-09 17:00:37 +0100795
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800796
797 FlowRule rule2 = rules.stream()
798 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
799 .findFirst()
800 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100801 verifyIdAndPriority(rule2, d2p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800802 assertThat(rule2.selector(),
803 is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
804 assertThat(rule2.treatment(),
805 is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
806
807 FlowRule rule3 = rules.stream()
808 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
809 .findFirst()
810 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100811 verifyIdAndPriority(rule3, d3p1.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800812 assertThat(rule3.selector(),
813 is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
814 assertThat(rule3.treatment(),
815 is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800816
817 sut.deactivate();
818 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100819
820 /**
821 * Tests the compilation behavior of the path intent compiler in case of
Michele Santuari3ea53902016-02-15 11:21:56 +0100822 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100823 */
824 @Test
Michele Santuari6096acd2016-02-09 17:00:37 +0100825 public void testVlanEncapCompile() {
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100826 sut.activate();
827
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800828 List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100829 assertThat(compiled, hasSize(1));
830
831 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
832 assertThat(rules, hasSize(3));
833
834 FlowRule rule1 = rules.stream()
835 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
836 .findFirst()
837 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100838 verifyIdAndPriority(rule1, d1p0.deviceId());
839 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
840 .matchInPort(d1p0.port()).build()));
841 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100842
843 FlowRule rule2 = rules.stream()
844 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
845 .findFirst()
846 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100847 verifyIdAndPriority(rule2, d2p0.deviceId());
848 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200849 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100850
851 FlowRule rule3 = rules.stream()
852 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
853 .findFirst()
854 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100855 verifyIdAndPriority(rule3, d3p1.deviceId());
856 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
857 verifyVlanEncapTreatment(rule3.treatment(), d3p0, false, true);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100858
859 sut.deactivate();
860 }
861
Michele Santuari3ea53902016-02-15 11:21:56 +0100862 /**
863 * Tests the compilation behavior of the path intent compiler in case of
864 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
865 * This test includes a selector to match a VLAN at the ingress and a treatment to set VLAN at the egress.
866 */
867 @Test
868 public void testEncapIngressEgressVlansCompile() {
869 sut.activate();
870
871 List<Intent> compiled = sut.compile(constrainIngressEgressVlanIntent,
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800872 Collections.emptyList());
Michele Santuari3ea53902016-02-15 11:21:56 +0100873 assertThat(compiled, hasSize(1));
874
875 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
876 assertThat(rules, hasSize(3));
877
878 FlowRule rule1 = rules.stream()
879 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
880 .findFirst()
881 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100882 verifyIdAndPriority(rule1, d1p0.deviceId());
883 verifyVlanEncapSelector(rule1.selector(), d1p0, ingressVlan);
884 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100885
886 FlowRule rule2 = rules.stream()
887 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
888 .findFirst()
889 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100890 verifyIdAndPriority(rule2, d2p0.deviceId());
891 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200892 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100893
894 FlowRule rule3 = rules.stream()
895 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
896 .findFirst()
897 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100898 verifyIdAndPriority(rule3, d3p1.deviceId());
899 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
Michele Santuari3ea53902016-02-15 11:21:56 +0100900 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream()
901 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
902 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
903 .collect(Collectors.toSet());
904 assertThat(rule3.treatment().allInstructions().stream()
905 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
906 .collect(Collectors.toSet()), hasSize(1));
907 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
908 assertThat(rule3.treatment().allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -0700909 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari3ea53902016-02-15 11:21:56 +0100910 .collect(Collectors.toSet()), hasSize(0));
911
912 sut.deactivate();
913 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100914
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200915 /**
916 * Tests the random selection of VlanIds in the PathCompiler.
917 * It can fail randomly (it is unlikely)
918 */
919 @Test
920 public void testRandomVlanSelection() {
921
922 if (PathCompiler.RANDOM_SELECTION) {
923
924 sut.activate();
925
926 List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
927 assertThat(compiled, hasSize(1));
928
929 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
930 assertThat(rules, hasSize(3));
931
932 FlowRule rule1 = rules.stream()
933 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
934 .findFirst()
935 .get();
936 verifyIdAndPriority(rule1, d1p0.deviceId());
937 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
938 .matchInPort(d1p0.port()).build()));
939
940 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
941
942 assertTrue(VlanId.NO_VID < vlanToEncap.toShort() && vlanToEncap.toShort() < VlanId.MAX_VLAN);
943
944 /**
945 * This second part is meant to test if the random selection is working properly.
946 * We are compiling the same intent in order to verify if the VLAN ID is different
947 * from the previous one.
948 */
949
950 List<Intent> compiled2 = sut.compile(constraintVlanIntent, Collections.emptyList());
951 assertThat(compiled2, hasSize(1));
952
953 Collection<FlowRule> rules2 = ((FlowRuleIntent) compiled2.get(0)).flowRules();
954 assertThat(rules2, hasSize(3));
955
956 FlowRule rule2 = rules2.stream()
957 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
958 .findFirst()
959 .get();
960 verifyIdAndPriority(rule2, d1p0.deviceId());
961 assertThat(rule2.selector(), is(DefaultTrafficSelector.builder(selector)
962 .matchInPort(d1p0.port()).build()));
963
964 VlanId vlanToEncap2 = verifyVlanEncapTreatment(rule2.treatment(), d1p1, true, false);
965
966 assertTrue(VlanId.NO_VID < vlanToEncap2.toShort() && vlanToEncap2.toShort() < VlanId.MAX_VLAN);
967 assertNotEquals(vlanToEncap, vlanToEncap2);
968
969 sut.deactivate();
970
971 }
972
973 }
974
Michele Santuari6096acd2016-02-09 17:00:37 +0100975 private VlanId verifyVlanEncapTreatment(TrafficTreatment trafficTreatment,
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100976 ConnectPoint egress, boolean isIngress, boolean isEgress) {
977 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
978 .filter(treat -> treat instanceof Instructions.OutputInstruction)
979 .map(treat -> (Instructions.OutputInstruction) treat)
980 .collect(Collectors.toSet());
981 assertThat(ruleOutput, hasSize(1));
982 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
983 VlanId vlanToEncap = VlanId.NONE;
984 if (isIngress && !isEgress) {
985 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
986 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
987 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
988 .collect(Collectors.toSet());
989 assertThat(vlanRules, hasSize(1));
990 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200991 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) VlanId.NO_VID));
992 assertThat(vlanRule.vlanId().toShort(), lessThan((short) VlanId.MAX_VLAN));
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100993 vlanToEncap = vlanRule.vlanId();
994 } else if (!isIngress && !isEgress) {
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200995
996 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
997 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
998 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
999 .collect(Collectors.toSet());
1000 assertThat(vlanRules, hasSize(1));
1001 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
1002 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) VlanId.NO_VID));
1003 assertThat(vlanRule.vlanId().toShort(), lessThan((short) VlanId.MAX_VLAN));
1004 vlanToEncap = vlanRule.vlanId();
1005
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001006 } else {
1007 assertThat(trafficTreatment.allInstructions().stream()
1008 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
1009 .collect(Collectors.toSet()), hasSize(0));
1010 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001011 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001012 .collect(Collectors.toSet()), hasSize(1));
1013
1014 }
1015
1016 return vlanToEncap;
1017
1018 }
1019
Michele Santuari6096acd2016-02-09 17:00:37 +01001020 private void verifyVlanEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) {
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001021
Michele Santuari6096acd2016-02-09 17:00:37 +01001022 assertThat(trafficSelector, is(DefaultTrafficSelector.builder().matchInPort(ingress.port())
1023 .matchVlanId(vlanToMatch).build()));
1024 }
1025
1026 /**
1027 * Tests the compilation behavior of the path intent compiler in case of
1028 * encasulation costraint {@link EncapsulationConstraint}.
1029 */
1030 @Test
1031 public void testMplsEncapCompile() {
1032 sut.activate();
1033
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -08001034 List<Intent> compiled = sut.compile(constraintMplsIntent, Collections.emptyList());
Michele Santuari6096acd2016-02-09 17:00:37 +01001035 assertThat(compiled, hasSize(1));
1036
1037 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
1038 assertThat(rules, hasSize(3));
1039
1040 FlowRule rule1 = rules.stream()
1041 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
1042 .findFirst()
1043 .get();
1044 verifyIdAndPriority(rule1, d1p0.deviceId());
1045 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +02001046 .matchInPort(d1p0.port()).build()));
Michele Santuari6096acd2016-02-09 17:00:37 +01001047 MplsLabel mplsLabelToEncap = verifyMplsEncapTreatment(rule1.treatment(), d1p1, true, false);
1048
1049 FlowRule rule2 = rules.stream()
1050 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
1051 .findFirst()
1052 .get();
1053 verifyIdAndPriority(rule2, d2p0.deviceId());
1054 verifyMplsEncapSelector(rule2.selector(), d2p0, mplsLabelToEncap);
1055 verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false);
1056
1057 FlowRule rule3 = rules.stream()
1058 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
1059 .findFirst()
1060 .get();
1061 verifyIdAndPriority(rule3, d3p1.deviceId());
1062 verifyMplsEncapSelector(rule3.selector(), d3p1, mplsLabelToEncap);
1063 verifyMplsEncapTreatment(rule3.treatment(), d3p0, false, true);
1064
1065 sut.deactivate();
1066 }
1067
1068
1069 private MplsLabel verifyMplsEncapTreatment(TrafficTreatment trafficTreatment,
1070 ConnectPoint egress, boolean isIngress, boolean isEgress) {
1071 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
1072 .filter(treat -> treat instanceof Instructions.OutputInstruction)
1073 .map(treat -> (Instructions.OutputInstruction) treat)
1074 .collect(Collectors.toSet());
1075 assertThat(ruleOutput, hasSize(1));
1076 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
1077 MplsLabel mplsToEncap = MplsLabel.mplsLabel(0);
1078 if (isIngress && !isEgress) {
1079 Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules =
1080 trafficTreatment.allInstructions().stream()
1081 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1082 .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
1083 .collect(Collectors.toSet());
1084 assertThat(mplsRules, hasSize(1));
1085 L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
1086 assertThat(mplsRule.mplsLabel().toInt(), greaterThan(0));
1087 mplsToEncap = mplsRule.mplsLabel();
1088 } else if (!isIngress && !isEgress) {
1089 assertThat(trafficTreatment.allInstructions().stream()
1090 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1091 .collect(Collectors.toSet()), hasSize(0));
1092 } else {
1093 assertThat(trafficTreatment.allInstructions().stream()
1094 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1095 .collect(Collectors.toSet()), hasSize(0));
1096 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001097 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsHeaderInstruction)
Michele Santuari6096acd2016-02-09 17:00:37 +01001098 .collect(Collectors.toSet()), hasSize(1));
1099
1100 }
1101
1102 return mplsToEncap;
1103
1104 }
1105
1106 private void verifyMplsEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, MplsLabel mplsLabel) {
1107
1108 assertThat(trafficSelector, is(DefaultTrafficSelector.builder()
1109 .matchInPort(ingress.port()).matchEthType(Ethernet.MPLS_UNICAST)
1110 .matchMplsLabel(mplsLabel).build()));
1111 }
1112
1113 private void verifyIdAndPriority(FlowRule rule, DeviceId deviceId) {
1114 assertThat(rule.deviceId(), is(deviceId));
1115 assertThat(rule.priority(), is(PRIORITY));
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001116 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001117}