blob: 2c39274659d6d18be45a3d540a625414ffe6adaa [file] [log] [blame]
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +02001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
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 */
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070016package org.onosproject.net.optical.intent.impl.compiler;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020017
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.Sets;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020020import org.junit.Before;
21import org.junit.Test;
Ray Milkeya7cf8c82018-02-08 15:07:06 -080022import org.onlab.graph.ScalarWeight;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020023import org.onlab.packet.ChassisId;
24import org.onosproject.TestApplicationId;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070027import org.onosproject.net.AbstractProjectableModel;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020028import org.onosproject.net.Annotations;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020029import org.onosproject.net.CltSignalType;
30import org.onosproject.net.ConnectPoint;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070031import org.onosproject.net.DefaultAnnotations;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020032import org.onosproject.net.DefaultDevice;
33import org.onosproject.net.DefaultLink;
34import org.onosproject.net.DefaultPath;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070035import org.onosproject.net.DefaultPort;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020036import org.onosproject.net.Device;
37import org.onosproject.net.DeviceId;
38import org.onosproject.net.Link;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020039import org.onosproject.net.OduSignalId;
40import org.onosproject.net.OduSignalType;
41import org.onosproject.net.OduSignalUtils;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020042import org.onosproject.net.OtuSignalType;
43import org.onosproject.net.Path;
44import org.onosproject.net.Port;
45import org.onosproject.net.PortNumber;
46import org.onosproject.net.TributarySlot;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070047import org.onosproject.net.device.DeviceServiceAdapter;
48import org.onosproject.net.driver.DriverService;
49import org.onosproject.net.driver.DriverServiceAdapter;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020050import org.onosproject.net.flow.DefaultTrafficSelector;
51import org.onosproject.net.flow.DefaultTrafficTreatment;
52import org.onosproject.net.flow.FlowRule;
53import org.onosproject.net.flow.TrafficSelector;
54import org.onosproject.net.flow.TrafficTreatment;
55import org.onosproject.net.flow.criteria.Criteria;
56import org.onosproject.net.flow.instructions.Instructions;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070057import org.onosproject.net.intent.AbstractIntentTest;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020058import org.onosproject.net.intent.FlowRuleIntent;
59import org.onosproject.net.intent.Intent;
60import org.onosproject.net.intent.IntentExtensionService;
61import org.onosproject.net.intent.Key;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020062import org.onosproject.net.intent.OpticalOduIntent;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070063import org.onosproject.net.optical.OduCltPort;
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -070064import org.onosproject.net.optical.OtuPort;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070065import org.onosproject.net.optical.impl.DefaultOduCltPort;
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -070066import org.onosproject.net.optical.impl.DefaultOtuPort;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020067import org.onosproject.net.provider.ProviderId;
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070068import org.onosproject.net.resource.MockResourceService;
Ray Milkey7483e1b2018-02-07 15:43:01 -080069import org.onosproject.net.topology.LinkWeigher;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020070import org.onosproject.net.topology.Topology;
71import org.onosproject.net.topology.TopologyServiceAdapter;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020072
73import java.util.Arrays;
74import java.util.Collection;
75import java.util.Collections;
76import java.util.HashSet;
77import java.util.List;
78import java.util.Set;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070079import java.util.stream.Collectors;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020080
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070081import static org.easymock.EasyMock.*;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020082import static org.hamcrest.MatcherAssert.assertThat;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070083import static org.hamcrest.Matchers.*;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020084import static org.junit.Assert.assertEquals;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020085import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070086import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020087import static org.onosproject.net.Device.Type.OTN;
88import static org.onosproject.net.DeviceId.deviceId;
89import static org.onosproject.net.Link.Type.OPTICAL;
90import static org.onosproject.net.NetTestTools.APP_ID;
91import static org.onosproject.net.NetTestTools.PID;
92
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070093public class OpticalOduIntentCompilerTest extends AbstractIntentTest {
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020094
95 private static final String DEV1 = "of:1";
96 private static final String DEV2 = "of:2";
97 private static final String DEV3 = "of:3";
98
99 static final Key KEY1 = Key.of(5L, APP_ID);
100
101 private static final String STATIC_TRUE = "true";
102 private static final String PNAME = "p2";
103
104 private CoreService coreService;
105 private IntentExtensionService intentExtensionService;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200106 private OpticalOduIntentCompiler sut;
107
108 private final ApplicationId appId = new TestApplicationId("test");
109 private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
110 "m", "h", "s", "n", new ChassisId(0L));
111 private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
112 "m", "h", "s", "n", new ChassisId(1L));
113 private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
114 "m", "h", "s", "n", new ChassisId(2L));
115
116 private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
117 private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
118
119 // OduClt ports with signalType=1GBE
120 private static final OduCltPort D1P1 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700121 new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(1), true, annotations1),
122 CltSignalType.CLT_1GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200123 private static final OduCltPort D3P2 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700124 new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(2), true, annotations1),
125 CltSignalType.CLT_1GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200126
127 // Otu ports with signalType=ODU2
128 private static final OtuPort D1P2 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700129 new DefaultOtuPort(new DefaultPort(device1, PortNumber.portNumber(2), true, annotations2),
130 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200131 private static final OtuPort D2P1 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700132 new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(1), true, annotations2),
133 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200134 private static final OtuPort D2P2 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700135 new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(2), true, annotations2),
136 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200137 private static final OtuPort D3P1 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700138 new DefaultOtuPort(new DefaultPort(device3, PortNumber.portNumber(1), true, annotations2),
139 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200140
141 // OduClt ports with signalType=10GBE
142 private static final OduCltPort D1P3 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700143 new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(3), true, annotations1),
144 CltSignalType.CLT_10GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200145 private static final OduCltPort D3P3 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700146 new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(3), true, annotations1),
147 CltSignalType.CLT_10GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200148
149 // OduCltPort ConnectPoints
150 private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
151 private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
152 private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
153 private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());
154
155 // OtuPort ConnectPoints
156 private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
157 private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
158 private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
159 private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());
160
161 private final List<Link> links = Arrays.asList(
162 DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
163 DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
164 );
Ray Milkeya7cf8c82018-02-08 15:07:06 -0800165 private final Path path = new DefaultPath(PID, links, ScalarWeight.toWeight(3));
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200166
167 private OpticalOduIntent intent;
168
169 /**
170 * Mocks the topology service to give paths in the test.
171 */
172 private class MockTopologyService extends TopologyServiceAdapter {
173 Set<Path> paths = Sets.newHashSet(path);
174
175 @Override
Ray Milkey7483e1b2018-02-07 15:43:01 -0800176 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeigher weight) {
177 return paths;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200178 }
179
180 @Override
Ray Milkey7483e1b2018-02-07 15:43:01 -0800181 public Topology currentTopology() {
182 return null;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200183 }
184 }
185
186 /**
187 * Mocks the device service so that devices and ports appear available in the test.
188 */
189 private static class MockDeviceService extends DeviceServiceAdapter {
190 @Override
191 public boolean isAvailable(DeviceId deviceId) {
192 return true;
193 }
194
195 @Override
196 public List<Port> getPorts(DeviceId deviceId) {
197 if (deviceId.equals(deviceId(DEV1))) {
198 return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
199 }
200
201 if (deviceId.equals(deviceId(DEV2))) {
202 return ImmutableList.of((Port) D2P1, (Port) D2P2);
203 }
204
205 if (deviceId.equals(deviceId(DEV3))) {
206 return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
207 }
208
209 return Collections.emptyList();
210 }
211
212 @Override
213 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
214 if (deviceId.equals(deviceId(DEV1))) {
215 switch (portNumber.toString()) {
216 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700217 return D1P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200218 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700219 return D1P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200220 case "3":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700221 return D1P3;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200222 default:
223 return null;
224 }
225 }
226 if (deviceId.equals(deviceId(DEV2))) {
227 switch (portNumber.toString()) {
228 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700229 return D2P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200230 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700231 return D2P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200232 default:
233 return null;
234 }
235 }
236 if (deviceId.equals(deviceId(DEV3))) {
237 switch (portNumber.toString()) {
238 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700239 return D3P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200240 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700241 return D3P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200242 case "3":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700243 return D3P3;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200244 default:
245 return null;
246 }
247 }
248 return null;
249 }
250 }
251
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700252 private static class MockDriverService extends DriverServiceAdapter
253 implements DriverService {
254 // TODO override to return appropriate driver,
255 // with DefaultOpticalDevice support, etc.
256 }
257
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200258 @Before
259 public void setUp() {
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700260 AbstractProjectableModel.setDriverService(null, new MockDriverService());
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200261 sut = new OpticalOduIntentCompiler();
262 coreService = createMock(CoreService.class);
263 expect(coreService.registerApplication("org.onosproject.net.intent"))
264 .andReturn(appId);
265 sut.coreService = coreService;
266 sut.deviceService = new MockDeviceService();
267 sut.resourceService = new MockResourceService();
268 sut.topologyService = new MockTopologyService();
269
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700270 super.setUp();
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200271
272 intentExtensionService = createMock(IntentExtensionService.class);
273 intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
274 intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
275 sut.intentManager = intentExtensionService;
276
277 replay(coreService, intentExtensionService);
278 }
279
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200280 /**
281 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
282 * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
283 * - only one TributarySlot is used
284 */
285 @Test
286 public void test1GbeMultiplexOverOdu2() {
287
288 intent = OpticalOduIntent.builder()
289 .appId(APP_ID)
290 .key(KEY1)
291 .src(d1p1)
292 .dst(d3p2)
293 .signalType(D1P1.signalType())
294 .bidirectional(false)
295 .build();
296
297 sut.activate();
298
299 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
300 assertThat(compiled, hasSize(1));
301
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700302 assertThat("key is inherited",
303 compiled.stream().map(Intent::key).collect(Collectors.toList()),
304 everyItem(is(intent.key())));
305
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200306 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
307
308 // 1st Device
309 FlowRule rule1 = rules.stream()
310 .filter(x -> x.deviceId().equals(device1.id()))
311 .findFirst()
312 .get();
313 // validate SRC selector
314 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
315 selectorBuilder1.matchInPort(d1p1.port());
316 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
317 assertThat(rule1.selector(), is(selectorBuilder1.build()));
318
319 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
320 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
321 Set<TributarySlot> slots = new HashSet<>();
322 slots.add(TributarySlot.of(1));
323 OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
324 treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
325 treatmentBuilder1.setOutput(d1p2.port());
326 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
327
328 // 2nd Device
329 FlowRule rule2 = rules.stream()
330 .filter(x -> x.deviceId().equals(device2.id()))
331 .findFirst()
332 .get();
333 // validate SRC selector
334 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
335 selectorBuilder2.matchInPort(d2p1.port());
336 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
337 selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
338 assertThat(rule2.selector(), is(selectorBuilder2.build()));
339
340 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
341 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
342 treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
343 treatmentBuilder2.setOutput(d2p2.port());
344 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
345
346
347 // 3rd Device
348 FlowRule rule3 = rules.stream()
349 .filter(x -> x.deviceId().equals(device3.id()))
350 .findFirst()
351 .get();
352 // validate DST selector (with OduSignalId, where the same TributarySlot is used)
353 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
354 selectorBuilder3.matchInPort(d3p1.port());
355 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
356 selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
357 assertThat(rule3.selector(), is(selectorBuilder3.build()));
358
359 // validate DST treatment
360 assertThat(rule3.treatment(), is(
361 DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
362 ));
363
364 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
365 intent.priority(), rule.priority()));
366
367 sut.deactivate();
368 }
369
370 /**
371 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
372 * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
373 * - All TributarySlots are used
374 */
375 @Test
376 public void test10GbeMultiplexOverOdu2() {
377
378 intent = OpticalOduIntent.builder()
379 .appId(APP_ID)
380 .key(KEY1)
381 .src(d1p3)
382 .dst(d3p3)
383 .signalType(D1P3.signalType())
384 .bidirectional(false)
385 .build();
386
387 sut.activate();
388
389 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
390 assertThat(compiled, hasSize(1));
391
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700392 assertThat("key is inherited",
393 compiled.stream().map(Intent::key).collect(Collectors.toList()),
394 everyItem(is(intent.key())));
395
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200396 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
397
398 // 1st Device
399 FlowRule rule1 = rules.stream()
400 .filter(x -> x.deviceId().equals(device1.id()))
401 .findFirst()
402 .get();
403 // validate SRC selector
404 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
405 selectorBuilder1.matchInPort(d1p3.port());
406 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
407 assertThat(rule1.selector(), is(selectorBuilder1.build()));
408
409 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
410 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
411 treatmentBuilder1.setOutput(d1p2.port());
412 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
413
414 // 2nd Device
415 FlowRule rule2 = rules.stream()
416 .filter(x -> x.deviceId().equals(device2.id()))
417 .findFirst()
418 .get();
419 // validate SRC selector
420 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
421 selectorBuilder2.matchInPort(d2p1.port());
422 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
423 assertThat(rule2.selector(), is(selectorBuilder2.build()));
424
425 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
426 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
427 treatmentBuilder2.setOutput(d2p2.port());
428 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
429
430
431 // 3rd Device
432 FlowRule rule3 = rules.stream()
433 .filter(x -> x.deviceId().equals(device3.id()))
434 .findFirst()
435 .get();
436 // validate DST selector (without OduSignalId - all TributarySlots are used)
437 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
438 selectorBuilder3.matchInPort(d3p1.port());
439 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
440 assertThat(rule3.selector(), is(selectorBuilder3.build()));
441
442 // validate DST treatment
443 assertThat(rule3.treatment(), is(
444 DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
445 ));
446
447 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
448 intent.priority(), rule.priority()));
449
450 sut.deactivate();
451 }
452
453}