blob: 62182eb67b29a8b3a19937bc2e621eb2505f759a [file] [log] [blame]
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +02001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +02003 *
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
18import org.junit.After;
19import org.junit.Before;
20import org.junit.Test;
21import org.onlab.packet.ChassisId;
22import org.onosproject.TestApplicationId;
23import org.onosproject.core.ApplicationId;
24import org.onosproject.core.CoreService;
25import org.onosproject.core.IdGenerator;
26import org.onosproject.net.Annotations;
27import org.onosproject.net.DefaultAnnotations;
28import org.onosproject.net.CltSignalType;
29import org.onosproject.net.ConnectPoint;
30import org.onosproject.net.DefaultDevice;
31import org.onosproject.net.DefaultLink;
32import org.onosproject.net.DefaultPath;
33import org.onosproject.net.Device;
34import org.onosproject.net.DeviceId;
35import org.onosproject.net.Link;
36import org.onosproject.net.OduCltPort;
37import org.onosproject.net.OduSignalId;
38import org.onosproject.net.OduSignalType;
39import org.onosproject.net.OduSignalUtils;
40import org.onosproject.net.OtuPort;
41import org.onosproject.net.OtuSignalType;
42import org.onosproject.net.Path;
43import org.onosproject.net.Port;
44import org.onosproject.net.PortNumber;
45import org.onosproject.net.TributarySlot;
46import org.onosproject.net.flow.DefaultTrafficSelector;
47import org.onosproject.net.flow.DefaultTrafficTreatment;
48import org.onosproject.net.flow.FlowRule;
49import org.onosproject.net.flow.TrafficSelector;
50import org.onosproject.net.flow.TrafficTreatment;
51import org.onosproject.net.flow.criteria.Criteria;
52import org.onosproject.net.flow.instructions.Instructions;
53import org.onosproject.net.intent.FlowRuleIntent;
54import org.onosproject.net.intent.Intent;
55import org.onosproject.net.intent.IntentExtensionService;
56import org.onosproject.net.intent.Key;
57import org.onosproject.net.intent.MockIdGenerator;
58import org.onosproject.net.intent.OpticalOduIntent;
59import org.onosproject.net.provider.ProviderId;
60import org.onosproject.net.topology.LinkWeight;
61import org.onosproject.net.topology.Topology;
62import org.onosproject.net.topology.TopologyServiceAdapter;
63import org.onosproject.net.device.DeviceServiceAdapter;
64
65import com.google.common.collect.ImmutableList;
66import com.google.common.collect.Sets;
67
68import java.util.Arrays;
69import java.util.Collection;
70import java.util.Collections;
71import java.util.HashSet;
72import java.util.List;
73import java.util.Set;
74
75import static org.easymock.EasyMock.createMock;
76import static org.easymock.EasyMock.expect;
77import static org.easymock.EasyMock.replay;
78import static org.hamcrest.MatcherAssert.assertThat;
79import static org.hamcrest.Matchers.hasSize;
80import static org.hamcrest.Matchers.is;
81import static org.junit.Assert.assertEquals;
82import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
83import static org.onosproject.net.AnnotationKeys.PORT_NAME;
84import static org.onosproject.net.Device.Type.OTN;
85import static org.onosproject.net.DeviceId.deviceId;
86import static org.onosproject.net.Link.Type.OPTICAL;
87import static org.onosproject.net.NetTestTools.APP_ID;
88import static org.onosproject.net.NetTestTools.PID;
89
90public class OpticalOduIntentCompilerTest {
91
92 private static final String DEV1 = "of:1";
93 private static final String DEV2 = "of:2";
94 private static final String DEV3 = "of:3";
95
96 static final Key KEY1 = Key.of(5L, APP_ID);
97
98 private static final String STATIC_TRUE = "true";
99 private static final String PNAME = "p2";
100
101 private CoreService coreService;
102 private IntentExtensionService intentExtensionService;
103 private final IdGenerator idGenerator = new MockIdGenerator();
104 private OpticalOduIntentCompiler sut;
105
106 private final ApplicationId appId = new TestApplicationId("test");
107 private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
108 "m", "h", "s", "n", new ChassisId(0L));
109 private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
110 "m", "h", "s", "n", new ChassisId(1L));
111 private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
112 "m", "h", "s", "n", new ChassisId(2L));
113
114 private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
115 private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
116
117 // OduClt ports with signalType=1GBE
118 private static final OduCltPort D1P1 =
119 new OduCltPort(device1, PortNumber.portNumber(1), true, CltSignalType.CLT_1GBE, annotations1);
120 private static final OduCltPort D3P2 =
121 new OduCltPort(device3, PortNumber.portNumber(2), true, CltSignalType.CLT_1GBE, annotations1);
122
123 // Otu ports with signalType=ODU2
124 private static final OtuPort D1P2 =
125 new OtuPort(device1, PortNumber.portNumber(2), true, OtuSignalType.OTU2, annotations2);
126 private static final OtuPort D2P1 =
127 new OtuPort(device2, PortNumber.portNumber(1), true, OtuSignalType.OTU2, annotations2);
128 private static final OtuPort D2P2 =
129 new OtuPort(device2, PortNumber.portNumber(2), true, OtuSignalType.OTU2, annotations2);
130 private static final OtuPort D3P1 =
131 new OtuPort(device3, PortNumber.portNumber(1), true, OtuSignalType.OTU2, annotations2);
132
133 // OduClt ports with signalType=10GBE
134 private static final OduCltPort D1P3 =
135 new OduCltPort(device1, PortNumber.portNumber(3), true, CltSignalType.CLT_10GBE, annotations1);
136 private static final OduCltPort D3P3 =
137 new OduCltPort(device3, PortNumber.portNumber(3), true, CltSignalType.CLT_10GBE, annotations1);
138
139 // OduCltPort ConnectPoints
140 private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
141 private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
142 private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
143 private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());
144
145 // OtuPort ConnectPoints
146 private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
147 private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
148 private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
149 private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());
150
151 private final List<Link> links = Arrays.asList(
152 DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
153 DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
154 );
155 private final Path path = new DefaultPath(PID, links, 3);
156
157 private OpticalOduIntent intent;
158
159 /**
160 * Mocks the topology service to give paths in the test.
161 */
162 private class MockTopologyService extends TopologyServiceAdapter {
163 Set<Path> paths = Sets.newHashSet(path);
164
165 @Override
166 public Topology currentTopology() {
167 return null;
168 }
169
170 @Override
171 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
172 return paths;
173 }
174 }
175
176 /**
177 * Mocks the device service so that devices and ports appear available in the test.
178 */
179 private static class MockDeviceService extends DeviceServiceAdapter {
180 @Override
181 public boolean isAvailable(DeviceId deviceId) {
182 return true;
183 }
184
185 @Override
186 public List<Port> getPorts(DeviceId deviceId) {
187 if (deviceId.equals(deviceId(DEV1))) {
188 return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
189 }
190
191 if (deviceId.equals(deviceId(DEV2))) {
192 return ImmutableList.of((Port) D2P1, (Port) D2P2);
193 }
194
195 if (deviceId.equals(deviceId(DEV3))) {
196 return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
197 }
198
199 return Collections.emptyList();
200 }
201
202 @Override
203 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
204 if (deviceId.equals(deviceId(DEV1))) {
205 switch (portNumber.toString()) {
206 case "1":
207 return (Port) D1P1;
208 case "2":
209 return (Port) D1P2;
210 case "3":
211 return (Port) D1P3;
212 default:
213 return null;
214 }
215 }
216 if (deviceId.equals(deviceId(DEV2))) {
217 switch (portNumber.toString()) {
218 case "1":
219 return (Port) D2P1;
220 case "2":
221 return (Port) D2P2;
222 default:
223 return null;
224 }
225 }
226 if (deviceId.equals(deviceId(DEV3))) {
227 switch (portNumber.toString()) {
228 case "1":
229 return (Port) D3P1;
230 case "2":
231 return (Port) D3P2;
232 case "3":
233 return (Port) D3P3;
234 default:
235 return null;
236 }
237 }
238 return null;
239 }
240 }
241
242 @Before
243 public void setUp() {
244 sut = new OpticalOduIntentCompiler();
245 coreService = createMock(CoreService.class);
246 expect(coreService.registerApplication("org.onosproject.net.intent"))
247 .andReturn(appId);
248 sut.coreService = coreService;
249 sut.deviceService = new MockDeviceService();
250 sut.resourceService = new MockResourceService();
251 sut.topologyService = new MockTopologyService();
252
253 Intent.bindIdGenerator(idGenerator);
254
255 intentExtensionService = createMock(IntentExtensionService.class);
256 intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
257 intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
258 sut.intentManager = intentExtensionService;
259
260 replay(coreService, intentExtensionService);
261 }
262
263 @After
264 public void tearDown() {
265 Intent.unbindIdGenerator(idGenerator);
266 }
267
268 /**
269 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
270 * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
271 * - only one TributarySlot is used
272 */
273 @Test
274 public void test1GbeMultiplexOverOdu2() {
275
276 intent = OpticalOduIntent.builder()
277 .appId(APP_ID)
278 .key(KEY1)
279 .src(d1p1)
280 .dst(d3p2)
281 .signalType(D1P1.signalType())
282 .bidirectional(false)
283 .build();
284
285 sut.activate();
286
287 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
288 assertThat(compiled, hasSize(1));
289
290 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
291
292 // 1st Device
293 FlowRule rule1 = rules.stream()
294 .filter(x -> x.deviceId().equals(device1.id()))
295 .findFirst()
296 .get();
297 // validate SRC selector
298 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
299 selectorBuilder1.matchInPort(d1p1.port());
300 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
301 assertThat(rule1.selector(), is(selectorBuilder1.build()));
302
303 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
304 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
305 Set<TributarySlot> slots = new HashSet<>();
306 slots.add(TributarySlot.of(1));
307 OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
308 treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
309 treatmentBuilder1.setOutput(d1p2.port());
310 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
311
312 // 2nd Device
313 FlowRule rule2 = rules.stream()
314 .filter(x -> x.deviceId().equals(device2.id()))
315 .findFirst()
316 .get();
317 // validate SRC selector
318 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
319 selectorBuilder2.matchInPort(d2p1.port());
320 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
321 selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
322 assertThat(rule2.selector(), is(selectorBuilder2.build()));
323
324 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
325 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
326 treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
327 treatmentBuilder2.setOutput(d2p2.port());
328 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
329
330
331 // 3rd Device
332 FlowRule rule3 = rules.stream()
333 .filter(x -> x.deviceId().equals(device3.id()))
334 .findFirst()
335 .get();
336 // validate DST selector (with OduSignalId, where the same TributarySlot is used)
337 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
338 selectorBuilder3.matchInPort(d3p1.port());
339 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
340 selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
341 assertThat(rule3.selector(), is(selectorBuilder3.build()));
342
343 // validate DST treatment
344 assertThat(rule3.treatment(), is(
345 DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
346 ));
347
348 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
349 intent.priority(), rule.priority()));
350
351 sut.deactivate();
352 }
353
354 /**
355 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
356 * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
357 * - All TributarySlots are used
358 */
359 @Test
360 public void test10GbeMultiplexOverOdu2() {
361
362 intent = OpticalOduIntent.builder()
363 .appId(APP_ID)
364 .key(KEY1)
365 .src(d1p3)
366 .dst(d3p3)
367 .signalType(D1P3.signalType())
368 .bidirectional(false)
369 .build();
370
371 sut.activate();
372
373 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
374 assertThat(compiled, hasSize(1));
375
376 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
377
378 // 1st Device
379 FlowRule rule1 = rules.stream()
380 .filter(x -> x.deviceId().equals(device1.id()))
381 .findFirst()
382 .get();
383 // validate SRC selector
384 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
385 selectorBuilder1.matchInPort(d1p3.port());
386 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
387 assertThat(rule1.selector(), is(selectorBuilder1.build()));
388
389 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
390 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
391 treatmentBuilder1.setOutput(d1p2.port());
392 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
393
394 // 2nd Device
395 FlowRule rule2 = rules.stream()
396 .filter(x -> x.deviceId().equals(device2.id()))
397 .findFirst()
398 .get();
399 // validate SRC selector
400 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
401 selectorBuilder2.matchInPort(d2p1.port());
402 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
403 assertThat(rule2.selector(), is(selectorBuilder2.build()));
404
405 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
406 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
407 treatmentBuilder2.setOutput(d2p2.port());
408 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
409
410
411 // 3rd Device
412 FlowRule rule3 = rules.stream()
413 .filter(x -> x.deviceId().equals(device3.id()))
414 .findFirst()
415 .get();
416 // validate DST selector (without OduSignalId - all TributarySlots are used)
417 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
418 selectorBuilder3.matchInPort(d3p1.port());
419 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
420 assertThat(rule3.selector(), is(selectorBuilder3.build()));
421
422 // validate DST treatment
423 assertThat(rule3.treatment(), is(
424 DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
425 ));
426
427 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
428 intent.priority(), rule.priority()));
429
430 sut.deactivate();
431 }
432
433}