blob: dda82c6d846821f8e69f7d651d76c0388f59a786 [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;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
26import org.onosproject.core.IdGenerator;
27import org.onosproject.net.ConnectPoint;
28import org.onosproject.net.DefaultLink;
29import org.onosproject.net.DefaultPath;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010030import org.onosproject.net.EncapsulationType;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080031import org.onosproject.net.Link;
32import org.onosproject.net.flow.DefaultTrafficSelector;
33import org.onosproject.net.flow.DefaultTrafficTreatment;
34import org.onosproject.net.flow.FlowRule;
35import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010037import org.onosproject.net.flow.instructions.Instructions;
38import org.onosproject.net.flow.instructions.L2ModificationInstruction;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080039import org.onosproject.net.intent.FlowRuleIntent;
40import org.onosproject.net.intent.Intent;
41import org.onosproject.net.intent.IntentExtensionService;
42import org.onosproject.net.intent.MockIdGenerator;
43import org.onosproject.net.intent.PathIntent;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010044import org.onosproject.net.intent.constraint.EncapsulationConstraint;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080045import org.onosproject.net.provider.ProviderId;
46
Michele Santuari69fc2ff2015-12-03 17:05:35 +010047import java.util.Arrays;
48import java.util.Collection;
49import java.util.Collections;
50import java.util.List;
51import java.util.Set;
52import java.util.stream.Collectors;
53
54import static org.easymock.EasyMock.*;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080055import static org.hamcrest.MatcherAssert.assertThat;
56import static org.hamcrest.Matchers.hasSize;
57import static org.hamcrest.Matchers.is;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010058import static org.hamcrest.number.OrderingComparison.greaterThan;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080059import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
60import static org.onosproject.net.Link.Type.DIRECT;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010061import static org.onosproject.net.NetTestTools.*;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080062
63/**
64 * Unit tests for PathIntentCompiler.
65 */
66public class PathIntentCompilerTest {
67
68 private CoreService coreService;
69 private IntentExtensionService intentExtensionService;
70 private IdGenerator idGenerator = new MockIdGenerator();
71 private PathIntentCompiler sut;
72
73 private final TrafficSelector selector = DefaultTrafficSelector.builder().build();
74 private final TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
75 private final ApplicationId appId = new TestApplicationId("test");
76 private final ProviderId pid = new ProviderId("of", "test");
77 private final ConnectPoint d1p1 = connectPoint("s1", 0);
78 private final ConnectPoint d2p0 = connectPoint("s2", 0);
79 private final ConnectPoint d2p1 = connectPoint("s2", 1);
80 private final ConnectPoint d3p1 = connectPoint("s3", 1);
81 private final ConnectPoint d3p0 = connectPoint("s3", 10);
82 private final ConnectPoint d1p0 = connectPoint("s1", 10);
Brian O'Connor81134662015-06-25 17:23:33 -040083 private static final int PRIORITY = 555;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080084
85 private final List<Link> links = Arrays.asList(
86 createEdgeLink(d1p0, true),
87 new DefaultLink(PID, d1p1, d2p0, DIRECT),
88 new DefaultLink(PID, d2p1, d3p1, DIRECT),
89 createEdgeLink(d3p0, false)
90 );
91 private final int hops = links.size() - 1;
92 private PathIntent intent;
Michele Santuari69fc2ff2015-12-03 17:05:35 +010093 private PathIntent constraintIntent;
Sho SHIMIZUee2aa652015-02-25 18:56:43 -080094
95 /**
96 * Configures objects used in all the test cases.
97 */
98 @Before
99 public void setUp() {
100 sut = new PathIntentCompiler();
101 coreService = createMock(CoreService.class);
102 expect(coreService.registerApplication("org.onosproject.net.intent"))
103 .andReturn(appId);
104 sut.coreService = coreService;
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100105 sut.resourceService = new MockResourceService();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800106
107 Intent.bindIdGenerator(idGenerator);
108
109 intent = PathIntent.builder()
110 .appId(APP_ID)
111 .selector(selector)
112 .treatment(treatment)
Brian O'Connor81134662015-06-25 17:23:33 -0400113 .priority(PRIORITY)
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800114 .path(new DefaultPath(pid, links, hops))
115 .build();
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100116 constraintIntent = PathIntent.builder()
117 .appId(APP_ID)
118 .selector(selector)
119 .treatment(treatment)
120 .priority(PRIORITY)
121 .constraints(ImmutableList.of(new EncapsulationConstraint(EncapsulationType.VLAN)))
122 .path(new DefaultPath(pid, links, hops))
123 .build();
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800124 intentExtensionService = createMock(IntentExtensionService.class);
125 intentExtensionService.registerCompiler(PathIntent.class, sut);
126 intentExtensionService.unregisterCompiler(PathIntent.class);
127 sut.intentManager = intentExtensionService;
128
129 replay(coreService, intentExtensionService);
130 }
131
132 /**
133 * Tears down objects used in all the test cases.
134 */
135 @After
136 public void tearDown() {
137 Intent.unbindIdGenerator(idGenerator);
138 }
139
140 /**
141 * Tests the compilation behavior of the path intent compiler.
142 */
143 @Test
144 public void testCompile() {
145 sut.activate();
146
147 List<Intent> compiled = sut.compile(intent, Collections.emptyList(), Collections.emptySet());
148 assertThat(compiled, hasSize(1));
149
150 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
151
152 FlowRule rule1 = rules.stream()
153 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
154 .findFirst()
155 .get();
156 assertThat(rule1.deviceId(), is(d1p0.deviceId()));
157 assertThat(rule1.selector(),
158 is(DefaultTrafficSelector.builder(selector).matchInPort(d1p0.port()).build()));
159 assertThat(rule1.treatment(),
160 is(DefaultTrafficTreatment.builder().setOutput(d1p1.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400161 assertThat(rule1.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800162
163 FlowRule rule2 = rules.stream()
164 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
165 .findFirst()
166 .get();
167 assertThat(rule2.deviceId(), is(d2p0.deviceId()));
168 assertThat(rule2.selector(),
169 is(DefaultTrafficSelector.builder(selector).matchInPort(d2p0.port()).build()));
170 assertThat(rule2.treatment(),
171 is(DefaultTrafficTreatment.builder().setOutput(d2p1.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400172 assertThat(rule2.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800173
174 FlowRule rule3 = rules.stream()
175 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
176 .findFirst()
177 .get();
178 assertThat(rule3.deviceId(), is(d3p1.deviceId()));
179 assertThat(rule3.selector(),
180 is(DefaultTrafficSelector.builder(selector).matchInPort(d3p1.port()).build()));
181 assertThat(rule3.treatment(),
182 is(DefaultTrafficTreatment.builder(treatment).setOutput(d3p0.port()).build()));
Brian O'Connor81134662015-06-25 17:23:33 -0400183 assertThat(rule3.priority(), is(intent.priority()));
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800184
185 sut.deactivate();
186 }
Michele Santuari69fc2ff2015-12-03 17:05:35 +0100187
188 /**
189 * Tests the compilation behavior of the path intent compiler in case of
190 * encasulation costraint {@link EncapsulationConstraint}.
191 */
192 @Test
193 public void testEncapCompile() {
194 sut.activate();
195
196 List<Intent> compiled = sut.compile(constraintIntent, Collections.emptyList(), Collections.emptySet());
197 assertThat(compiled, hasSize(1));
198
199 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
200 assertThat(rules, hasSize(3));
201
202 FlowRule rule1 = rules.stream()
203 .filter(x -> x.deviceId().equals(d1p0.deviceId()))
204 .findFirst()
205 .get();
206 assertThat(rule1.deviceId(), is(d1p0.deviceId()));
207 assertThat(rule1.priority(), is(intent.priority()));
208 verifyEncapSelector(rule1.selector(), d1p0, VlanId.NONE);
209 VlanId vlanToEncap = verifyEncapTreatment(rule1.treatment(), d1p1, true, false);
210
211 FlowRule rule2 = rules.stream()
212 .filter(x -> x.deviceId().equals(d2p0.deviceId()))
213 .findFirst()
214 .get();
215 assertThat(rule2.deviceId(), is(d2p0.deviceId()));
216 assertThat(rule2.priority(), is(intent.priority()));
217 verifyEncapSelector(rule2.selector(), d2p0, vlanToEncap);
218 verifyEncapTreatment(rule2.treatment(), d2p1, false, false);
219
220 FlowRule rule3 = rules.stream()
221 .filter(x -> x.deviceId().equals(d3p0.deviceId()))
222 .findFirst()
223 .get();
224 assertThat(rule3.deviceId(), is(d3p1.deviceId()));
225 assertThat(rule3.priority(), is(intent.priority()));
226 verifyEncapSelector(rule3.selector(), d3p1, vlanToEncap);
227 verifyEncapTreatment(rule3.treatment(), d3p0, false, true);
228
229 sut.deactivate();
230 }
231
232
233 private VlanId verifyEncapTreatment(TrafficTreatment trafficTreatment,
234 ConnectPoint egress, boolean isIngress, boolean isEgress) {
235 Set<Instructions.OutputInstruction> ruleOutput = trafficTreatment.allInstructions().stream()
236 .filter(treat -> treat instanceof Instructions.OutputInstruction)
237 .map(treat -> (Instructions.OutputInstruction) treat)
238 .collect(Collectors.toSet());
239 assertThat(ruleOutput, hasSize(1));
240 assertThat((ruleOutput.iterator().next()).port(), is(egress.port()));
241 VlanId vlanToEncap = VlanId.NONE;
242 if (isIngress && !isEgress) {
243 Set<L2ModificationInstruction.ModVlanIdInstruction> vlanRules = trafficTreatment.allInstructions().stream()
244 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
245 .map(x -> (L2ModificationInstruction.ModVlanIdInstruction) x)
246 .collect(Collectors.toSet());
247 assertThat(vlanRules, hasSize(1));
248 L2ModificationInstruction.ModVlanIdInstruction vlanRule = vlanRules.iterator().next();
249 assertThat(vlanRule.vlanId().toShort(), greaterThan((short) 0));
250 vlanToEncap = vlanRule.vlanId();
251 } else if (!isIngress && !isEgress) {
252 assertThat(trafficTreatment.allInstructions().stream()
253 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
254 .collect(Collectors.toSet()), hasSize(0));
255 } else {
256 assertThat(trafficTreatment.allInstructions().stream()
257 .filter(treat -> treat instanceof L2ModificationInstruction.ModVlanIdInstruction)
258 .collect(Collectors.toSet()), hasSize(0));
259 assertThat(trafficTreatment.allInstructions().stream()
260 .filter(treat -> treat instanceof L2ModificationInstruction.PopVlanInstruction)
261 .collect(Collectors.toSet()), hasSize(1));
262
263 }
264
265 return vlanToEncap;
266
267 }
268
269 private void verifyEncapSelector(TrafficSelector trafficSelector, ConnectPoint ingress, VlanId vlanToMatch) {
270
271 is(DefaultTrafficSelector.builder(selector).matchInPort(ingress.port())
272 .matchVlanId(vlanToMatch).build());
273 }
Sho SHIMIZUee2aa652015-02-25 18:56:43 -0800274}