blob: 17b173a1c0faf80a54ebad6ea0137879c302b168 [file] [log] [blame]
Sho SHIMIZUee2aa652015-02-25 18:56:43 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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 Santuari69fc2ff2015-12-03 17:05:35 +010022import org.onlab.packet.VlanId;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080023import org.onosproject.TestApplicationId;
Thomas Vachuskabdbdd242016-03-01 01:55:55 -080024import org.onosproject.cfg.ComponentConfigAdapter;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080025import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.core.IdGenerator;
28import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.DefaultLink;
30import org.onosproject.net.DefaultPath;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010031import org.onosproject.net.EncapsulationType;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080032import org.onosproject.net.Link;
33import org.onosproject.net.flow.DefaultTrafficSelector;
34import org.onosproject.net.flow.DefaultTrafficTreatment;
35import org.onosproject.net.flow.FlowRule;
36import org.onosproject.net.flow.TrafficSelector;
37import org.onosproject.net.flow.TrafficTreatment;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010038import org.onosproject.net.flow.instructions.Instructions;
39import org.onosproject.net.flow.instructions.L2ModificationInstruction;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080040import org.onosproject.net.intent.FlowRuleIntent;
41import org.onosproject.net.intent.Intent;
42import org.onosproject.net.intent.IntentExtensionService;
43import org.onosproject.net.intent.MockIdGenerator;
44import org.onosproject.net.intent.PathIntent;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010045import org.onosproject.net.intent.constraint.EncapsulationConstraint;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080046import org.onosproject.net.provider.ProviderId;
47
Michele Santuari69fc2ff2015-12-03 17:05:35 +010048import java.util.Arrays;
49import java.util.Collection;
50import java.util.Collections;
51import java.util.List;
52import java.util.Set;
53import java.util.stream.Collectors;
54
55import static org.easymock.EasyMock.*;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080056import static org.hamcrest.MatcherAssert.assertThat;
57import static org.hamcrest.Matchers.hasSize;
58import static org.hamcrest.Matchers.is;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010059import static org.hamcrest.number.OrderingComparison.greaterThan;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080060import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
61import static org.onosproject.net.Link.Type.DIRECT;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010062import static org.onosproject.net.NetTestTools.*;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080063
64/**
65 * Unit tests for PathIntentCompiler.
66 */
67public class PathIntentCompilerTest {
68
69 private CoreService coreService;
70 private IntentExtensionService intentExtensionService;
Thomas Vachuskabdbdd242016-03-01 01:55:55 -080071 private IntentConfigurableRegistrator registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080072 private IdGenerator idGenerator = new MockIdGenerator();
73 private PathIntentCompiler sut;
74
75 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
76 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
Michele Santuari3ea53902016-02-15 11:21:56 +010077 private final VlanId ingressVlan = VlanId.vlanId(((short) 101));
78 private final TrafficSelector vlanSelector = DefaultTrafficSelector.builder()
79 .matchVlanId(ingressVlan).build();
80 private final VlanId egressVlan = VlanId.vlanId((short) 100);
81 private final TrafficTreatment vlanTreatment = DefaultTrafficTreatment.builder()
82 .setVlanId(egressVlan).build();
83
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080084 private final ApplicationId appId = new TestApplicationId("test");
85 private final ProviderId pid = new ProviderId("of", "test");
86 private final ConnectPoint d1p1 = connectPoint("s1", 0);
87 private final ConnectPoint d2p0 = connectPoint("s2", 0);
88 private final ConnectPoint d2p1 = connectPoint("s2", 1);
89 private final ConnectPoint d3p1 = connectPoint("s3", 1);
90 private final ConnectPoint d3p0 = connectPoint("s3", 10);
91 private final ConnectPoint d1p0 = connectPoint("s1", 10);
Brian O'Connor81134662015-06-25 17:23:33 -040092 private static final int PRIORITY = 555;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080093
94 private final List<Link> links = Arrays.asList(
95 createEdgeLink(d1p0, true),
Ray Milkey2693bda2016-01-22 16:08:14 -080096 DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
97 DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build(),
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080098 createEdgeLink(d3p0, false)
99 );
100 private final int hops = links.size() - 1;
101 private PathIntent intent;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100102 private PathIntent constraintIntent;
Michele Santuari3ea53902016-02-15 11:21:56 +0100103 private PathIntent constrainIngressEgressVlanIntent;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800104
105 /**
106 * Configures objects used in all the test cases.
107 */
108 @Before
109 public void setUp() {
110 sut = new PathIntentCompiler();
111 coreService = createMock(CoreService.class);
112 expect(coreService.registerApplication("org.onosproject.net.intent"))
113 .andReturn(appId);
114 sut.coreService = coreService;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100115 sut.resourceService = new MockResourceService();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800116
117 Intent.bindIdGenerator(idGenerator);
118
119 intent = PathIntent.builder()
120 .appId(APP_ID)
121 .selector(selector)
122 .treatment(treatment)
Brian O'Connor81134662015-06-25 17:23:33 -0400123 .priority(PRIORITY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800124 .path(new DefaultPath(pid, links, hops))
125 .build();
Michele Santuari3ea53902016-02-15 11:21:56 +0100126 //Intent with VLAN encap without egress VLAN
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100127 constraintIntent = PathIntent.builder()
128 .appId(APP_ID)
129 .selector(selector)
130 .treatment(treatment)
131 .priority(PRIORITY)
132 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
133 .path(new DefaultPath(pid, links, hops))
134 .build();
Michele Santuari3ea53902016-02-15 11:21:56 +0100135 //Intent with VLAN encap with ingress and egress VLAN
136 constrainIngressEgressVlanIntent = PathIntent.builder()
137 .appId(APP_ID)
138 .selector(vlanSelector)
139 .treatment(vlanTreatment)
140 .priority(PRIORITY)
141 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
142 .path(new DefaultPath(pid, links, hops))
143 .build();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800144 intentExtensionService = createMock(IntentExtensionService.class);
145 intentExtensionService.registerCompiler(PathIntent.class, sut);
146 intentExtensionService.unregisterCompiler(PathIntent.class);
Thomas Vachuskabdbdd242016-03-01 01:55:55 -0800147
148 registrator = new IntentConfigurableRegistrator();
149 registrator.extensionService = intentExtensionService;
150 registrator.cfgService = new ComponentConfigAdapter();
151 registrator.activate();
152
153 sut.registrator = registrator;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800154
155 replay(coreService, intentExtensionService);
156 }
157
158 /**
159 * Tears down objects used in all the test cases.
160 */
161 @After
162 public void tearDown() {
163 Intent.unbindIdGenerator(idGenerator);
164 }
165
166 /**
167 * Tests the compilation behavior of the path intent compiler.
168 */
169 @Test
170 public void testCompile() {
171 sut.activate();
172
173 List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
174 assertThat(compiled, hasSize(1));
175
176 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
177
178 FlowRule rule1 = rules.stream()
179 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
180 .findFirst()
181 .get();
182 assertThat(rule1.deviceId(), is(d1p0.deviceId()));
183 assertThat(rule1.selector(),
184 is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
185 assertThat(rule1.treatment(),
186 is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400187 assertThat(rule1.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800188
189 FlowRule rule2 = rules.stream()
190 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
191 .findFirst()
192 .get();
193 assertThat(rule2.deviceId(), is(d2p0.deviceId()));
194 assertThat(rule2.selector(),
195 is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
196 assertThat(rule2.treatment(),
197 is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400198 assertThat(rule2.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800199
200 FlowRule rule3 = rules.stream()
201 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
202 .findFirst()
203 .get();
204 assertThat(rule3.deviceId(), is(d3p1.deviceId()));
205 assertThat(rule3.selector(),
206 is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
207 assertThat(rule3.treatment(),
208 is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400209 assertThat(rule3.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800210
211 sut.deactivate();
212 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100213
214 /**
215 * Tests the compilation behavior of the path intent compiler in case of
Michele Santuari3ea53902016-02-15 11:21:56 +0100216 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100217 */
218 @Test
219 public void testEncapCompile() {
220 sut.activate();
221
222 List<Intent> compiled = sut.compile(constraintIntent, Collections.emptyList(), Collections.emptySet());
223 assertThat(compiled, hasSize(1));
224
225 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
226 assertThat(rules, hasSize(3));
227
228 FlowRule rule1 = rules.stream()
229 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
230 .findFirst()
231 .get();
232 assertThat(rule1.deviceId(), is(d1p0.deviceId()));
233 assertThat(rule1.priority(), is(intent.priority()));
234 verifyEncapSelector(rule1.selector(), d1p0, VlanId.NONE);
235 VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false);
236
237 FlowRule rule2 = rules.stream()
238 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
239 .findFirst()
240 .get();
241 assertThat(rule2.deviceId(), is(d2p0.deviceId()));
242 assertThat(rule2.priority(), is(intent.priority()));
243 verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap);
244 verifyEncapTreatment(rule2.treatment(), d2p1, false, false);
245
246 FlowRule rule3 = rules.stream()
247 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
248 .findFirst()
249 .get();
250 assertThat(rule3.deviceId(), is(d3p1.deviceId()));
251 assertThat(rule3.priority(), is(intent.priority()));
252 verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap);
253 verifyEncapTreatment(rule3.treatment(), d3p0, false, true);
254
255 sut.deactivate();
256 }
257
Michele Santuari3ea53902016-02-15 11:21:56 +0100258 /**
259 * Tests the compilation behavior of the path intent compiler in case of
260 * VLAN {@link EncapsulationType} encapsulation constraint {@link EncapsulationConstraint}.
261 * This test includes a selector to match a VLAN at the ingress and a treatment to set VLAN at the egress.
262 */
263 @Test
264 public void testEncapIngressEgressVlansCompile() {
265 sut.activate();
266
267 List<Intent> compiled = sut.compile(constrainIngressEgressVlanIntent,
268 Collections.emptyList(), Collections.emptySet());
269 assertThat(compiled, hasSize(1));
270
271 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
272 assertThat(rules, hasSize(3));
273
274 FlowRule rule1 = rules.stream()
275 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
276 .findFirst()
277 .get();
278 assertThat(rule1.deviceId(), is(d1p0.deviceId()));
279 assertThat(rule1.priority(), is(intent.priority()));
280 verifyEncapSelector(rule1.selector(), d1p0, ingressVlan);
281 VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false);
282
283 FlowRule rule2 = rules.stream()
284 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
285 .findFirst()
286 .get();
287 assertThat(rule2.deviceId(), is(d2p0.deviceId()));
288 assertThat(rule2.priority(), is(intent.priority()));
289 verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap);
290 verifyEncapTreatment(rule2.treatment(), d2p1, false, false);
291
292 FlowRule rule3 = rules.stream()
293 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
294 .findFirst()
295 .get();
296 assertThat(rule3.deviceId(), is(d3p1.deviceId()));
297 assertThat(rule3.priority(), is(intent.priority()));
298 verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap);
299 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanMod = rule3.treatment().allInstructions().stream()
300 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
301 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
302 .collect(Collectors.toSet());
303 assertThat(rule3.treatment().allInstructions().stream()
304 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
305 .collect(Collectors.toSet()), hasSize(1));
306 assertThat(vlanMod.iterator().next().vlanId(), is(egressVlan));
307 assertThat(rule3.treatment().allInstructions().stream()
308 .filter(treat -> treat instanceof L2ModificationInstruction.PopVlanInstruction)
309 .collect(Collectors.toSet()), hasSize(0));
310
311 sut.deactivate();
312 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100313
314 private VlanId verifyEncapTreatment(TrafficTreatment trafficTreatment,
315 ConnectPoint egress, boolean isIngress, boolean isEgress) {
316 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
317 .filter(treat -> treat instanceof Instructions.OutputInstruction)
318 .map(treat -> (Instructions.OutputInstruction) treat)
319 .collect(Collectors.toSet());
320 assertThat(ruleOutput, hasSize(1));
321 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
322 VlanId vlanToEncap = VlanId.NONE;
323 if (isIngress && !isEgress) {
324 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
325 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
326 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
327 .collect(Collectors.toSet());
328 assertThat(vlanRules, hasSize(1));
329 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
330 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) 0));
331 vlanToEncap = vlanRule.vlanId();
332 } else if (!isIngress && !isEgress) {
333 assertThat(trafficTreatment.allInstructions().stream()
334 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
335 .collect(Collectors.toSet()), hasSize(0));
336 } else {
337 assertThat(trafficTreatment.allInstructions().stream()
338 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
339 .collect(Collectors.toSet()), hasSize(0));
340 assertThat(trafficTreatment.allInstructions().stream()
341 .filter(treat -> treat instanceof L2ModificationInstruction.PopVlanInstruction)
342 .collect(Collectors.toSet()), hasSize(1));
343
344 }
345
346 return vlanToEncap;
347
348 }
349
350 private void verifyEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) {
351
352 is(DefaultTrafficSelector.builder(selector).matchInPort(ingress.port())
353 .matchVlanId(vlanToMatch).build());
354 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800355}