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