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