blob: e9f517004f2edbd039a35644032d0bdc11b6eb4e [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 /**
Pier Ventref8543d82016-09-28 19:49:33 -0700166 * Configures mock objects used in all the test cases.
167 * Creates the intents to test as well.
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800168 */
169 @Before
170 public void setUp() {
171 sut = new PathIntentCompiler();
172 coreService = createMock(CoreService.class);
173 expect(coreService.registerApplication("org.onosproject.net.intent"))
174 .andReturn(appId);
175 sut.coreService = coreService;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100176 sut.resourceService = new MockResourceService();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800177
178 Intent.bindIdGenerator(idGenerator);
179
180 intent = PathIntent.builder()
181 .appId(APP_ID)
182 .selector(selector)
183 .treatment(treatment)
Brian O'Connor81134662015-06-25 17:23:33 -0400184 .priority(PRIORITY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800185 .path(new DefaultPath(pid, links, hops))
186 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100187
Michele Santuari3ea53902016-02-15 11:21:56 +0100188 //Intent with VLAN encap without egress VLAN
Michele Santuari6096acd2016-02-09 17:00:37 +0100189 constraintVlanIntent = PathIntent.builder()
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100190 .appId(APP_ID)
191 .selector(selector)
192 .treatment(treatment)
193 .priority(PRIORITY)
194 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
195 .path(new DefaultPath(pid, links, hops))
196 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100197
Michele Santuari3ea53902016-02-15 11:21:56 +0100198 //Intent with VLAN encap with ingress and egress VLAN
199 constrainIngressEgressVlanIntent = PathIntent.builder()
200 .appId(APP_ID)
201 .selector(vlanSelector)
202 .treatment(vlanTreatment)
203 .priority(PRIORITY)
204 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
205 .path(new DefaultPath(pid, links, hops))
206 .build();
Michele Santuari6096acd2016-02-09 17:00:37 +0100207
208 constraintMplsIntent = PathIntent.builder()
209 .appId(APP_ID)
210 .selector(selector)
211 .treatment(treatment)
212 .priority(PRIORITY)
213 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.MPLS)))
214 .path(new DefaultPath(pid, links, hops))
215 .build();
Pier1677f9f2016-07-06 15:42:17 +0200216
217 edgeIntentNoVlan = PathIntent.builder()
218 .appId(APP_ID)
219 .selector(selector)
220 .treatment(treatment)
221 .priority(PRIORITY)
222 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
223 .path(new DefaultPath(pid, edgeNet, edgeHops))
224 .build();
225
226 edgeIntentIngressVlan = PathIntent.builder()
227 .appId(APP_ID)
228 .selector(vlanSelector)
229 .treatment(treatment)
230 .priority(PRIORITY)
231 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
232 .path(new DefaultPath(pid, edgeNet, edgeHops))
233 .build();
234
235 edgeIntentEgressVlan = PathIntent.builder()
236 .appId(APP_ID)
237 .selector(selector)
238 .treatment(vlanTreatment)
239 .priority(PRIORITY)
240 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
241 .path(new DefaultPath(pid, edgeNet, edgeHops))
242 .build();
243
244 edgeIntentVlan = PathIntent.builder()
245 .appId(APP_ID)
246 .selector(vlanSelector)
247 .treatment(vlanTreatment)
248 .priority(PRIORITY)
249 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
250 .path(new DefaultPath(pid, edgeNet, edgeHops))
251 .build();
252
253 singleHopIndirectIntentNoVlan = PathIntent.builder()
254 .appId(APP_ID)
255 .selector(selector)
256 .treatment(treatment)
257 .priority(PRIORITY)
258 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
259 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
260 .build();
261
262 singleHopIndirectIntentIngressVlan = PathIntent.builder()
263 .appId(APP_ID)
264 .selector(vlanSelector)
265 .treatment(treatment)
266 .priority(PRIORITY)
267 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
268 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
269 .build();
270
271 singleHopIndirectIntentEgressVlan = PathIntent.builder()
272 .appId(APP_ID)
273 .selector(selector)
274 .treatment(vlanTreatment)
275 .priority(PRIORITY)
276 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
277 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
278 .build();
279
280 singleHopIndirectIntentVlan = PathIntent.builder()
281 .appId(APP_ID)
282 .selector(vlanSelector)
283 .treatment(vlanTreatment)
284 .priority(PRIORITY)
285 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
286 .path(new DefaultPath(pid, singleHopIndirect, singleHopIndirectHops))
287 .build();
288
289 singleHopDirectIntentNoVlan = PathIntent.builder()
290 .appId(APP_ID)
291 .selector(selector)
292 .treatment(treatment)
293 .priority(PRIORITY)
294 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
295 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
296 .build();
297
298 singleHopDirectIntentIngressVlan = PathIntent.builder()
299 .appId(APP_ID)
300 .selector(vlanSelector)
301 .treatment(treatment)
302 .priority(PRIORITY)
303 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
304 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
305 .build();
306
307 singleHopDirectIntentEgressVlan = PathIntent.builder()
308 .appId(APP_ID)
309 .selector(selector)
310 .treatment(vlanTreatment)
311 .priority(PRIORITY)
312 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
313 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
314 .build();
315
316 singleHopDirectIntentVlan = PathIntent.builder()
317 .appId(APP_ID)
318 .selector(vlanSelector)
319 .treatment(vlanTreatment)
320 .priority(PRIORITY)
321 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
322 .path(new DefaultPath(pid, singleHopDirect, singleHopDirectHops))
323 .build();
324
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800325 intentExtensionService = createMock(IntentExtensionService.class);
326 intentExtensionService.registerCompiler(PathIntent.class, sut);
327 intentExtensionService.unregisterCompiler(PathIntent.class);
Thomas Vachuskabdbdd242016-03-01 01:55:55 -0800328
329 registrator = new IntentConfigurableRegistrator();
330 registrator.extensionService = intentExtensionService;
331 registrator.cfgService = new ComponentConfigAdapter();
332 registrator.activate();
333
334 sut.registrator = registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800335
336 replay(coreService, intentExtensionService);
337 }
338
339 /**
340 * Tears down objects used in all the test cases.
341 */
342 @After
343 public void tearDown() {
344 Intent.unbindIdGenerator(idGenerator);
345 }
346
Pier1677f9f2016-07-06 15:42:17 +0200347
348 /**
349 * Tests the compilation behavior of the path intent compiler in case of
350 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
351 * and edge communication. No ingress VLAN. No egress VLAN.
352 */
353 @Test
354 public void testVlanEncapCompileEdgeNoVlan() {
355 sut.activate();
356
357 List<Intent> compiled = sut.compile(edgeIntentNoVlan, Collections.emptyList());
358 assertThat(compiled, hasSize(1));
359
360 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
361 assertThat(rules, hasSize(1));
362
363 FlowRule rule = rules.stream()
364 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
365 .findFirst()
366 .get();
367 verifyIdAndPriority(rule, d1p2.deviceId());
368
369 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
370 .build()));
371 assertThat(rule.treatment(),
372 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
373
374 sut.deactivate();
375 }
376
377 /**
378 * Tests the compilation behavior of the path intent compiler in case of
379 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
380 * and edge communication. Ingress VLAN. No egress VLAN.
381 */
382 @Test
383 public void testVlanEncapCompileEdgeIngressVlan() {
384 sut.activate();
385
386 List<Intent> compiled = sut.compile(edgeIntentIngressVlan, Collections.emptyList());
387 assertThat(compiled, hasSize(1));
388
389 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
390 assertThat(rules, hasSize(1));
391
392 FlowRule rule = rules.stream()
393 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
394 .findFirst()
395 .get();
396 verifyIdAndPriority(rule, d1p2.deviceId());
397
398 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
399 .matchVlanId(ingressVlan).build()));
400 assertThat(rule.treatment(),
401 is(DefaultTrafficTreatment.builder().setOutput(d1p3.port()).build()));
402
403 sut.deactivate();
404 }
405
406 /**
407 * Tests the compilation behavior of the path intent compiler in case of
408 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
409 * and edge communication. No ingress VLAN. Egress VLAN.
410 */
411 @Test
412 public void testVlanEncapCompileEdgeEgressVlan() {
413 sut.activate();
414
415 List<Intent> compiled = sut.compile(edgeIntentEgressVlan, Collections.emptyList());
416 assertThat(compiled, hasSize(1));
417
418 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
419 assertThat(rules, hasSize(1));
420
421 FlowRule rule = rules.stream()
422 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
423 .findFirst()
424 .get();
425 verifyIdAndPriority(rule, d1p2.deviceId());
426
427 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
428 .build()));
429 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
430 .setOutput(d1p3.port()).build()));
431
432 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
433 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
434 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
435 .collect(Collectors.toSet());
436 assertThat(rule.treatment().allInstructions().stream()
437 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
438 .collect(Collectors.toSet()), hasSize(1));
439 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
440 assertThat(rule.treatment().allInstructions().stream()
441 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
442 .collect(Collectors.toSet()), hasSize(0));
443
444 sut.deactivate();
445 }
446
447 /**
448 * Tests the compilation behavior of the path intent compiler in case of
449 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
450 * and edge communication. Ingress VLAN. Egress VLAN.
451 */
452 @Test
453 public void testVlanEncapCompileEdgeVlan() {
454 sut.activate();
455
456 List<Intent> compiled = sut.compile(edgeIntentVlan, Collections.emptyList());
457 assertThat(compiled, hasSize(1));
458
459 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
460 assertThat(rules, hasSize(1));
461
462 FlowRule rule = rules.stream()
463 .filter(x -> x.deviceId().equals(d1p2.deviceId()))
464 .findFirst()
465 .get();
466 verifyIdAndPriority(rule, d1p2.deviceId());
467
468 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d1p2.port())
469 .matchVlanId(ingressVlan).build()));
470 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
471 .setOutput(d1p3.port()).build()));
472
473 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
474 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
475 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
476 .collect(Collectors.toSet());
477 assertThat(rule.treatment().allInstructions().stream()
478 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
479 .collect(Collectors.toSet()), hasSize(1));
480 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
481 assertThat(rule.treatment().allInstructions().stream()
482 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
483 .collect(Collectors.toSet()), hasSize(0));
484
485 sut.deactivate();
486 }
487
488 /**
489 * Tests the compilation behavior of the path intent compiler in case of
490 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
491 * and single-hop-indirect-link scenario. No ingress VLAN. No egress VLAN.
492 */
493 @Test
494 public void testVlanEncapCompileSingleHopIndirectNoVlan() {
495 sut.activate();
496
497 List<Intent> compiled = sut.compile(singleHopIndirectIntentNoVlan, Collections.emptyList());
498 assertThat(compiled, hasSize(1));
499
500 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
501 assertThat(rules, hasSize(1));
502
503
504 FlowRule rule = rules.stream()
505 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
506 .findFirst()
507 .get();
508 verifyIdAndPriority(rule, d2p2.deviceId());
509
510 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
511 .build()));
512 assertThat(rule.treatment(),
513 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
514
515 sut.deactivate();
516 }
517
518 /**
519 * Tests the compilation behavior of the path intent compiler in case of
520 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
521 * and single-hop-indirect-link scenario. Ingress VLAN. No egress VLAN.
522 */
523 @Test
524 public void testVlanEncapCompileSingleHopIndirectIngressVlan() {
525 sut.activate();
526
527 List<Intent> compiled = sut.compile(singleHopIndirectIntentIngressVlan, Collections.emptyList());
528 assertThat(compiled, hasSize(1));
529
530 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
531 assertThat(rules, hasSize(1));
532
533
534 FlowRule rule = rules.stream()
535 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
536 .findFirst()
537 .get();
538 verifyIdAndPriority(rule, d2p2.deviceId());
539
540 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
541 .matchVlanId(ingressVlan).build()));
542 assertThat(rule.treatment(),
543 is(DefaultTrafficTreatment.builder().setOutput(d2p3.port()).build()));
544
545 sut.deactivate();
546 }
547
548 /**
549 * Tests the compilation behavior of the path intent compiler in case of
550 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
551 * and single-hop-indirect-link scenario. No ingress VLAN. Egress VLAN.
552 */
553 @Test
554 public void testVlanEncapCompileSingleHopIndirectEgressVlan() {
555 sut.activate();
556
557 List<Intent> compiled = sut.compile(singleHopIndirectIntentEgressVlan, Collections.emptyList());
558 assertThat(compiled, hasSize(1));
559
560 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
561 assertThat(rules, hasSize(1));
562
563
564 FlowRule rule = rules.stream()
565 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
566 .findFirst()
567 .get();
568 verifyIdAndPriority(rule, d2p2.deviceId());
569
570 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
571 .build()));
572 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
573 .setOutput(d2p3.port()).build()));
574
575 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
576 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
577 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
578 .collect(Collectors.toSet());
579 assertThat(rule.treatment().allInstructions().stream()
580 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
581 .collect(Collectors.toSet()), hasSize(1));
582 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
583 assertThat(rule.treatment().allInstructions().stream()
584 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
585 .collect(Collectors.toSet()), hasSize(0));
586
587 sut.deactivate();
588 }
589
590 /**
591 * Tests the compilation behavior of the path intent compiler in case of
592 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
593 * and single-hop-indirect-link scenario. Ingress VLAN. Egress VLAN.
594 */
595 @Test
596 public void testVlanEncapCompileSingleHopIndirectVlan() {
597 sut.activate();
598
599 List<Intent> compiled = sut.compile(singleHopIndirectIntentVlan, Collections.emptyList());
600 assertThat(compiled, hasSize(1));
601
602 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
603 assertThat(rules, hasSize(1));
604
605
606 FlowRule rule = rules.stream()
607 .filter(x -> x.deviceId().equals(d2p2.deviceId()))
608 .findFirst()
609 .get();
610 verifyIdAndPriority(rule, d2p2.deviceId());
611
612 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p2.port())
613 .matchVlanId(ingressVlan).build()));
614 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
615 .setOutput(d2p3.port()).build()));
616
617 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
618 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
619 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
620 .collect(Collectors.toSet());
621 assertThat(rule.treatment().allInstructions().stream()
622 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
623 .collect(Collectors.toSet()), hasSize(1));
624 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
625 assertThat(rule.treatment().allInstructions().stream()
626 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
627 .collect(Collectors.toSet()), hasSize(0));
628
629 sut.deactivate();
630 }
631
632 /**
633 * Tests the compilation behavior of the path intent compiler in case of
634 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
635 * and single-hop-direct-link scenario. No ingress VLAN. No egress VLAN.
636 */
637 @Test
638 public void testVlanEncapCompileSingleHopDirectNoVlan() {
639 sut.activate();
640
641 List<Intent> compiled = sut.compile(singleHopDirectIntentNoVlan, Collections.emptyList());
642 assertThat(compiled, hasSize(1));
643
644 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
645 assertThat(rules, hasSize(1));
646
647
648 FlowRule rule = rules.stream()
649 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
650 .findFirst()
651 .get();
652 verifyIdAndPriority(rule, d2p4.deviceId());
653
654 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
655 .build()));
656 assertThat(rule.treatment(),
657 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
658
659 sut.deactivate();
660 }
661
662 /**
663 * Tests the compilation behavior of the path intent compiler in case of
664 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
665 * and single-hop-direct-link scenario. Ingress VLAN. No egress VLAN.
666 */
667 @Test
668 public void testVlanEncapCompileSingleHopDirectIngressVlan() {
669 sut.activate();
670
671 List<Intent> compiled = sut.compile(singleHopDirectIntentIngressVlan, Collections.emptyList());
672 assertThat(compiled, hasSize(1));
673
674 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
675 assertThat(rules, hasSize(1));
676
677
678 FlowRule rule = rules.stream()
679 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
680 .findFirst()
681 .get();
682 verifyIdAndPriority(rule, d2p4.deviceId());
683
684 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
685 .matchVlanId(ingressVlan).build()));
686 assertThat(rule.treatment(),
687 is(DefaultTrafficTreatment.builder().setOutput(d2p5.port()).build()));
688
689 sut.deactivate();
690 }
691
692 /**
693 * Tests the compilation behavior of the path intent compiler in case of
694 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
695 * and single-hop-direct-link scenario. No ingress VLAN. Egress VLAN.
696 */
697 @Test
698 public void testVlanEncapCompileSingleHopDirectEgressVlan() {
699 sut.activate();
700
701 List<Intent> compiled = sut.compile(singleHopDirectIntentEgressVlan, Collections.emptyList());
702 assertThat(compiled, hasSize(1));
703
704 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
705 assertThat(rules, hasSize(1));
706
707
708 FlowRule rule = rules.stream()
709 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
710 .findFirst()
711 .get();
712 verifyIdAndPriority(rule, d2p4.deviceId());
713
714 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
715 .build()));
716 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
717 .setOutput(d2p5.port()).build()));
718
719 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
720 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
721 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
722 .collect(Collectors.toSet());
723 assertThat(rule.treatment().allInstructions().stream()
724 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
725 .collect(Collectors.toSet()), hasSize(1));
726 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
727 assertThat(rule.treatment().allInstructions().stream()
728 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
729 .collect(Collectors.toSet()), hasSize(0));
730
731 sut.deactivate();
732 }
733
734 /**
735 * Tests the compilation behavior of the path intent compiler in case of
736 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}
737 * and single-hop-direct-link scenario. Ingress VLAN. Egress VLAN.
738 */
739 @Test
740 public void testVlanEncapCompileSingleHopDirectVlan() {
741 sut.activate();
742
743 List<Intent> compiled = sut.compile(singleHopDirectIntentVlan, Collections.emptyList());
744 assertThat(compiled, hasSize(1));
745
746 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
747 assertThat(rules, hasSize(1));
748
749
750 FlowRule rule = rules.stream()
751 .filter(x -> x.deviceId().equals(d2p4.deviceId()))
752 .findFirst()
753 .get();
754 verifyIdAndPriority(rule, d2p4.deviceId());
755
756 assertThat(rule.selector(), is(DefaultTrafficSelector.builder().matchInPort(d2p4.port())
757 .matchVlanId(ingressVlan).build()));
758 assertThat(rule.treatment(), is(DefaultTrafficTreatment.builder().setVlanId(egressVlan)
759 .setOutput(d2p5.port()).build()));
760
761 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule.treatment().allInstructions().stream()
762 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
763 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
764 .collect(Collectors.toSet());
765 assertThat(rule.treatment().allInstructions().stream()
766 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
767 .collect(Collectors.toSet()), hasSize(1));
768 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
769 assertThat(rule.treatment().allInstructions().stream()
770 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
771 .collect(Collectors.toSet()), hasSize(0));
772
773 sut.deactivate();
774 }
775
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800776 /**
777 * Tests the compilation behavior of the path intent compiler.
778 */
779 @Test
780 public void testCompile() {
781 sut.activate();
782
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800783 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800784 assertThat(compiled, hasSize(1));
785
786 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
787
788 FlowRule rule1 = rules.stream()
789 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
790 .findFirst()
791 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100792 verifyIdAndPriority(rule1, d1p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800793 assertThat(rule1.selector(),
794 is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
795 assertThat(rule1.treatment(),
796 is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
Michele Santuari6096acd2016-02-09 17:00:37 +0100797
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800798
799 FlowRule rule2 = rules.stream()
800 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
801 .findFirst()
802 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100803 verifyIdAndPriority(rule2, d2p0.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800804 assertThat(rule2.selector(),
805 is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
806 assertThat(rule2.treatment(),
807 is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
808
809 FlowRule rule3 = rules.stream()
810 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
811 .findFirst()
812 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100813 verifyIdAndPriority(rule3, d3p1.deviceId());
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800814 assertThat(rule3.selector(),
815 is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
816 assertThat(rule3.treatment(),
817 is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800818
819 sut.deactivate();
820 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100821
822 /**
823 * Tests the compilation behavior of the path intent compiler in case of
Michele Santuari3ea53902016-02-15 11:21:56 +0100824 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100825 */
826 @Test
Michele Santuari6096acd2016-02-09 17:00:37 +0100827 public void testVlanEncapCompile() {
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100828 sut.activate();
829
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800830 List<Intent> compiled = sut.compile(constraintVlanIntent, Collections.emptyList());
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100831 assertThat(compiled, hasSize(1));
832
833 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
834 assertThat(rules, hasSize(3));
835
836 FlowRule rule1 = rules.stream()
837 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
838 .findFirst()
839 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100840 verifyIdAndPriority(rule1, d1p0.deviceId());
841 assertThat(rule1.selector(), is(DefaultTrafficSelector.builder(selector)
842 .matchInPort(d1p0.port()).build()));
843 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100844
845 FlowRule rule2 = rules.stream()
846 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
847 .findFirst()
848 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100849 verifyIdAndPriority(rule2, d2p0.deviceId());
850 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200851 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100852
853 FlowRule rule3 = rules.stream()
854 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
855 .findFirst()
856 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100857 verifyIdAndPriority(rule3, d3p1.deviceId());
858 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
859 verifyVlanEncapTreatment(rule3.treatment(), d3p0, false, true);
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100860
861 sut.deactivate();
862 }
863
Michele Santuari3ea53902016-02-15 11:21:56 +0100864 /**
865 * Tests the compilation behavior of the path intent compiler in case of
866 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
867 * This test includes a selector to match a VLAN at the ingress and a treatment to set VLAN at the egress.
868 */
869 @Test
870 public void testEncapIngressEgressVlansCompile() {
871 sut.activate();
872
873 List<Intent> compiled = sut.compile(constrainIngressEgressVlanIntent,
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800874 Collections.emptyList());
Michele Santuari3ea53902016-02-15 11:21:56 +0100875 assertThat(compiled, hasSize(1));
876
877 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
878 assertThat(rules, hasSize(3));
879
880 FlowRule rule1 = rules.stream()
881 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
882 .findFirst()
883 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100884 verifyIdAndPriority(rule1, d1p0.deviceId());
885 verifyVlanEncapSelector(rule1.selector(), d1p0, ingressVlan);
886 VlanId vlanToEncap = verifyVlanEncapTreatment(rule1.treatment(), d1p1, true, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100887
888 FlowRule rule2 = rules.stream()
889 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
890 .findFirst()
891 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100892 verifyIdAndPriority(rule2, d2p0.deviceId());
893 verifyVlanEncapSelector(rule2.selector(), d2p0, vlanToEncap);
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200894 vlanToEncap = verifyVlanEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari3ea53902016-02-15 11:21:56 +0100895
896 FlowRule rule3 = rules.stream()
897 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
898 .findFirst()
899 .get();
Michele Santuari6096acd2016-02-09 17:00:37 +0100900 verifyIdAndPriority(rule3, d3p1.deviceId());
901 verifyVlanEncapSelector(rule3.selector(), d3p1, vlanToEncap);
Michele Santuari3ea53902016-02-15 11:21:56 +0100902 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream()
903 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
904 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
905 .collect(Collectors.toSet());
906 assertThat(rule3.treatment().allInstructions().stream()
907 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
908 .collect(Collectors.toSet()), hasSize(1));
909 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
910 assertThat(rule3.treatment().allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -0700911 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari3ea53902016-02-15 11:21:56 +0100912 .collect(Collectors.toSet()), hasSize(0));
913
914 sut.deactivate();
915 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100916
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200917 /**
Pier Ventref8543d82016-09-28 19:49:33 -0700918 * Tests the random selection of VLAN Ids in the PathCompiler.
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200919 * It can fail randomly (it is unlikely)
920 */
921 @Test
922 public void testRandomVlanSelection() {
923
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200924 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
Sho SHIMIZU3437bdb2016-08-12 14:57:37 -0700944 /*
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200945 * 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
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200971
972 }
973
Michele Santuari6096acd2016-02-09 17:00:37 +0100974 private VlanId verifyVlanEncapTreatment(TrafficTreatment trafficTreatment,
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100975 ConnectPoint egress, boolean isIngress, boolean isEgress) {
976 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
977 .filter(treat -> treat instanceof Instructions.OutputInstruction)
978 .map(treat -> (Instructions.OutputInstruction) treat)
979 .collect(Collectors.toSet());
980 assertThat(ruleOutput, hasSize(1));
981 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
982 VlanId vlanToEncap = VlanId.NONE;
983 if (isIngress && !isEgress) {
984 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
985 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
986 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
987 .collect(Collectors.toSet());
988 assertThat(vlanRules, hasSize(1));
989 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200990 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) VlanId.NO_VID));
991 assertThat(vlanRule.vlanId().toShort(), lessThan((short) VlanId.MAX_VLAN));
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100992 vlanToEncap = vlanRule.vlanId();
993 } else if (!isIngress && !isEgress) {
Pier Luigi Ventre51313bd2016-06-02 10:50:30 +0200994
995 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
996 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
997 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
998 .collect(Collectors.toSet());
999 assertThat(vlanRules, hasSize(1));
1000 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
1001 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) VlanId.NO_VID));
1002 assertThat(vlanRule.vlanId().toShort(), lessThan((short) VlanId.MAX_VLAN));
1003 vlanToEncap = vlanRule.vlanId();
1004
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001005 } else {
1006 assertThat(trafficTreatment.allInstructions().stream()
1007 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
1008 .collect(Collectors.toSet()), hasSize(0));
1009 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001010 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanHeaderInstruction)
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001011 .collect(Collectors.toSet()), hasSize(1));
1012
1013 }
1014
1015 return vlanToEncap;
1016
1017 }
1018
Michele Santuari6096acd2016-02-09 17:00:37 +01001019 private void verifyVlanEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) {
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001020
Michele Santuari6096acd2016-02-09 17:00:37 +01001021 assertThat(trafficSelector, is(DefaultTrafficSelector.builder().matchInPort(ingress.port())
1022 .matchVlanId(vlanToMatch).build()));
1023 }
1024
1025 /**
1026 * Tests the compilation behavior of the path intent compiler in case of
1027 * encasulation costraint {@link EncapsulationConstraint}.
1028 */
1029 @Test
1030 public void testMplsEncapCompile() {
1031 sut.activate();
1032
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -08001033 List<Intent> compiled = sut.compile(constraintMplsIntent, Collections.emptyList());
Michele Santuari6096acd2016-02-09 17:00:37 +01001034 assertThat(compiled, hasSize(1));
1035
1036 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
1037 assertThat(rules, hasSize(3));
1038
1039 FlowRule rule1 = rules.stream()
1040 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
1041 .findFirst()
1042 .get();
1043 verifyIdAndPriority(rule1, d1p0.deviceId());
Pier Ventref8543d82016-09-28 19:49:33 -07001044 assertThat(rule1.selector(), is(DefaultTrafficSelector
1045 .builder(selector)
1046 .matchInPort(d1p0.port())
1047 .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);
Pier Ventref8543d82016-09-28 19:49:33 -07001056 mplsLabelToEncap = verifyMplsEncapTreatment(rule2.treatment(), d2p1, false, false);
Michele Santuari6096acd2016-02-09 17:00:37 +01001057
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) {
Pier Ventref8543d82016-09-28 19:49:33 -07001080 Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
1081 .allInstructions()
1082 .stream()
1083 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1084 .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
1085 .collect(Collectors.toSet());
Michele Santuari6096acd2016-02-09 17:00:37 +01001086 assertThat(mplsRules, hasSize(1));
1087 L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
Pier Ventref8543d82016-09-28 19:49:33 -07001088 assertThat(mplsRule.label().toInt(), greaterThan(0));
1089 assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
1090 mplsToEncap = mplsRule.label();
Michele Santuari6096acd2016-02-09 17:00:37 +01001091 } else if (!isIngress && !isEgress) {
Pier Ventref8543d82016-09-28 19:49:33 -07001092 Set<L2ModificationInstruction.ModMplsLabelInstruction> mplsRules = trafficTreatment
1093 .allInstructions()
1094 .stream()
1095 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1096 .map(x -> (L2ModificationInstruction.ModMplsLabelInstruction) x)
1097 .collect(Collectors.toSet());
1098 assertThat(mplsRules, hasSize(1));
1099 L2ModificationInstruction.ModMplsLabelInstruction mplsRule = mplsRules.iterator().next();
1100 assertThat(mplsRule.label().toInt(), greaterThan(0));
1101 assertThat(mplsRule.label().toInt(), lessThan(MplsLabel.MAX_MPLS));
1102 mplsToEncap = mplsRule.label();
Michele Santuari6096acd2016-02-09 17:00:37 +01001103 } else {
1104 assertThat(trafficTreatment.allInstructions().stream()
1105 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsLabelInstruction)
1106 .collect(Collectors.toSet()), hasSize(0));
1107 assertThat(trafficTreatment.allInstructions().stream()
Jian Li11260a02016-05-19 13:07:22 -07001108 .filter(treat -> treat instanceof L2ModificationInstruction.ModMplsHeaderInstruction)
Michele Santuari6096acd2016-02-09 17:00:37 +01001109 .collect(Collectors.toSet()), hasSize(1));
1110
1111 }
Michele Santuari6096acd2016-02-09 17:00:37 +01001112 return mplsToEncap;
1113
1114 }
1115
1116 private void verifyMplsEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, MplsLabel mplsLabel) {
1117
1118 assertThat(trafficSelector, is(DefaultTrafficSelector.builder()
1119 .matchInPort(ingress.port()).matchEthType(Ethernet.MPLS_UNICAST)
1120 .matchMplsLabel(mplsLabel).build()));
1121 }
1122
1123 private void verifyIdAndPriority(FlowRule rule, DeviceId deviceId) {
1124 assertThat(rule.deviceId(), is(deviceId));
1125 assertThat(rule.priority(), is(PRIORITY));
Michele Santuari69fc2ff2015-12-03 17:05:35 +01001126 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001127}