blob: 4992b1a30cfb89838c00753347b6b9ddfab33c96 [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 */
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;
22import org.onlab.packet.ChassisId;
23import org.onosproject.TestApplicationId;
24import org.onosproject.core.ApplicationId;
25import org.onosproject.core.CoreService;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070026import org.onosproject.net.AbstractProjectableModel;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020027import org.onosproject.net.Annotations;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020028import org.onosproject.net.CltSignalType;
29import org.onosproject.net.ConnectPoint;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070030import org.onosproject.net.DefaultAnnotations;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020031import org.onosproject.net.DefaultDevice;
32import org.onosproject.net.DefaultLink;
33import org.onosproject.net.DefaultPath;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070034import org.onosproject.net.DefaultPort;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020035import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.Link;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020038import org.onosproject.net.OduSignalId;
39import org.onosproject.net.OduSignalType;
40import org.onosproject.net.OduSignalUtils;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020041import org.onosproject.net.OtuSignalType;
42import org.onosproject.net.Path;
43import org.onosproject.net.Port;
44import org.onosproject.net.PortNumber;
45import org.onosproject.net.TributarySlot;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070046import org.onosproject.net.device.DeviceServiceAdapter;
47import org.onosproject.net.driver.DriverService;
48import org.onosproject.net.driver.DriverServiceAdapter;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020049import org.onosproject.net.flow.DefaultTrafficSelector;
50import org.onosproject.net.flow.DefaultTrafficTreatment;
51import org.onosproject.net.flow.FlowRule;
52import org.onosproject.net.flow.TrafficSelector;
53import org.onosproject.net.flow.TrafficTreatment;
54import org.onosproject.net.flow.criteria.Criteria;
55import org.onosproject.net.flow.instructions.Instructions;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070056import org.onosproject.net.intent.AbstractIntentTest;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020057import org.onosproject.net.intent.FlowRuleIntent;
58import org.onosproject.net.intent.Intent;
59import org.onosproject.net.intent.IntentExtensionService;
60import org.onosproject.net.intent.Key;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020061import org.onosproject.net.intent.OpticalOduIntent;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070062import org.onosproject.net.optical.OduCltPort;
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -070063import org.onosproject.net.optical.OtuPort;
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -070064import org.onosproject.net.optical.impl.DefaultOduCltPort;
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -070065import org.onosproject.net.optical.impl.DefaultOtuPort;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020066import org.onosproject.net.provider.ProviderId;
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070067import org.onosproject.net.resource.MockResourceService;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020068import org.onosproject.net.topology.LinkWeight;
69import org.onosproject.net.topology.Topology;
70import org.onosproject.net.topology.TopologyServiceAdapter;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020071
72import java.util.Arrays;
73import java.util.Collection;
74import java.util.Collections;
75import java.util.HashSet;
76import java.util.List;
77import java.util.Set;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070078import java.util.stream.Collectors;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020079
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070080import static org.easymock.EasyMock.*;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020081import static org.hamcrest.MatcherAssert.assertThat;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070082import static org.hamcrest.Matchers.*;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020083import static org.junit.Assert.assertEquals;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020084import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070085import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020086import static org.onosproject.net.Device.Type.OTN;
87import static org.onosproject.net.DeviceId.deviceId;
88import static org.onosproject.net.Link.Type.OPTICAL;
89import static org.onosproject.net.NetTestTools.APP_ID;
90import static org.onosproject.net.NetTestTools.PID;
91
Thomas Vachuska2048c1f2017-05-10 19:32:22 -070092public class OpticalOduIntentCompilerTest extends AbstractIntentTest {
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +020093
94 private static final String DEV1 = "of:1";
95 private static final String DEV2 = "of:2";
96 private static final String DEV3 = "of:3";
97
98 static final Key KEY1 = Key.of(5L, APP_ID);
99
100 private static final String STATIC_TRUE = "true";
101 private static final String PNAME = "p2";
102
103 private CoreService coreService;
104 private IntentExtensionService intentExtensionService;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200105 private OpticalOduIntentCompiler sut;
106
107 private final ApplicationId appId = new TestApplicationId("test");
108 private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
109 "m", "h", "s", "n", new ChassisId(0L));
110 private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
111 "m", "h", "s", "n", new ChassisId(1L));
112 private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
113 "m", "h", "s", "n", new ChassisId(2L));
114
115 private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
116 private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
117
118 // OduClt ports with signalType=1GBE
119 private static final OduCltPort D1P1 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700120 new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(1), true, annotations1),
121 CltSignalType.CLT_1GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200122 private static final OduCltPort D3P2 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700123 new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(2), true, annotations1),
124 CltSignalType.CLT_1GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200125
126 // Otu ports with signalType=ODU2
127 private static final OtuPort D1P2 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700128 new DefaultOtuPort(new DefaultPort(device1, PortNumber.portNumber(2), true, annotations2),
129 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200130 private static final OtuPort D2P1 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700131 new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(1), true, annotations2),
132 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200133 private static final OtuPort D2P2 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700134 new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(2), true, annotations2),
135 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200136 private static final OtuPort D3P1 =
HIGUCHI Yuta5be3e822016-05-03 13:51:42 -0700137 new DefaultOtuPort(new DefaultPort(device3, PortNumber.portNumber(1), true, annotations2),
138 OtuSignalType.OTU2);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200139
140 // OduClt ports with signalType=10GBE
141 private static final OduCltPort D1P3 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700142 new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(3), true, annotations1),
143 CltSignalType.CLT_10GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200144 private static final OduCltPort D3P3 =
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700145 new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(3), true, annotations1),
146 CltSignalType.CLT_10GBE);
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200147
148 // OduCltPort ConnectPoints
149 private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
150 private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
151 private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
152 private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());
153
154 // OtuPort ConnectPoints
155 private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
156 private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
157 private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
158 private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());
159
160 private final List<Link> links = Arrays.asList(
161 DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
162 DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
163 );
164 private final Path path = new DefaultPath(PID, links, 3);
165
166 private OpticalOduIntent intent;
167
168 /**
169 * Mocks the topology service to give paths in the test.
170 */
171 private class MockTopologyService extends TopologyServiceAdapter {
172 Set<Path> paths = Sets.newHashSet(path);
173
174 @Override
175 public Topology currentTopology() {
176 return null;
177 }
178
179 @Override
180 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
181 return paths;
182 }
183 }
184
185 /**
186 * Mocks the device service so that devices and ports appear available in the test.
187 */
188 private static class MockDeviceService extends DeviceServiceAdapter {
189 @Override
190 public boolean isAvailable(DeviceId deviceId) {
191 return true;
192 }
193
194 @Override
195 public List<Port> getPorts(DeviceId deviceId) {
196 if (deviceId.equals(deviceId(DEV1))) {
197 return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
198 }
199
200 if (deviceId.equals(deviceId(DEV2))) {
201 return ImmutableList.of((Port) D2P1, (Port) D2P2);
202 }
203
204 if (deviceId.equals(deviceId(DEV3))) {
205 return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
206 }
207
208 return Collections.emptyList();
209 }
210
211 @Override
212 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
213 if (deviceId.equals(deviceId(DEV1))) {
214 switch (portNumber.toString()) {
215 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700216 return D1P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200217 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700218 return D1P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200219 case "3":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700220 return D1P3;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200221 default:
222 return null;
223 }
224 }
225 if (deviceId.equals(deviceId(DEV2))) {
226 switch (portNumber.toString()) {
227 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700228 return D2P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200229 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700230 return D2P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200231 default:
232 return null;
233 }
234 }
235 if (deviceId.equals(deviceId(DEV3))) {
236 switch (portNumber.toString()) {
237 case "1":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700238 return D3P1;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200239 case "2":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700240 return D3P2;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200241 case "3":
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700242 return D3P3;
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200243 default:
244 return null;
245 }
246 }
247 return null;
248 }
249 }
250
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700251 private static class MockDriverService extends DriverServiceAdapter
252 implements DriverService {
253 // TODO override to return appropriate driver,
254 // with DefaultOpticalDevice support, etc.
255 }
256
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200257 @Before
258 public void setUp() {
HIGUCHI Yuta4c0ef6b2016-05-02 19:45:41 -0700259 AbstractProjectableModel.setDriverService(null, new MockDriverService());
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200260 sut = new OpticalOduIntentCompiler();
261 coreService = createMock(CoreService.class);
262 expect(coreService.registerApplication("org.onosproject.net.intent"))
263 .andReturn(appId);
264 sut.coreService = coreService;
265 sut.deviceService = new MockDeviceService();
266 sut.resourceService = new MockResourceService();
267 sut.topologyService = new MockTopologyService();
268
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700269 super.setUp();
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200270
271 intentExtensionService = createMock(IntentExtensionService.class);
272 intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
273 intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
274 sut.intentManager = intentExtensionService;
275
276 replay(coreService, intentExtensionService);
277 }
278
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200279 /**
280 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
281 * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
282 * - only one TributarySlot is used
283 */
284 @Test
285 public void test1GbeMultiplexOverOdu2() {
286
287 intent = OpticalOduIntent.builder()
288 .appId(APP_ID)
289 .key(KEY1)
290 .src(d1p1)
291 .dst(d3p2)
292 .signalType(D1P1.signalType())
293 .bidirectional(false)
294 .build();
295
296 sut.activate();
297
298 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
299 assertThat(compiled, hasSize(1));
300
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700301 assertThat("key is inherited",
302 compiled.stream().map(Intent::key).collect(Collectors.toList()),
303 everyItem(is(intent.key())));
304
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200305 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
306
307 // 1st Device
308 FlowRule rule1 = rules.stream()
309 .filter(x -> x.deviceId().equals(device1.id()))
310 .findFirst()
311 .get();
312 // validate SRC selector
313 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
314 selectorBuilder1.matchInPort(d1p1.port());
315 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
316 assertThat(rule1.selector(), is(selectorBuilder1.build()));
317
318 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
319 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
320 Set<TributarySlot> slots = new HashSet<>();
321 slots.add(TributarySlot.of(1));
322 OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
323 treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
324 treatmentBuilder1.setOutput(d1p2.port());
325 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
326
327 // 2nd Device
328 FlowRule rule2 = rules.stream()
329 .filter(x -> x.deviceId().equals(device2.id()))
330 .findFirst()
331 .get();
332 // validate SRC selector
333 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
334 selectorBuilder2.matchInPort(d2p1.port());
335 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
336 selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
337 assertThat(rule2.selector(), is(selectorBuilder2.build()));
338
339 // validate SRC treatment (with OduSignalId, where 1 TributarySlot is used)
340 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
341 treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
342 treatmentBuilder2.setOutput(d2p2.port());
343 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
344
345
346 // 3rd Device
347 FlowRule rule3 = rules.stream()
348 .filter(x -> x.deviceId().equals(device3.id()))
349 .findFirst()
350 .get();
351 // validate DST selector (with OduSignalId, where the same TributarySlot is used)
352 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
353 selectorBuilder3.matchInPort(d3p1.port());
354 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
355 selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
356 assertThat(rule3.selector(), is(selectorBuilder3.build()));
357
358 // validate DST treatment
359 assertThat(rule3.treatment(), is(
360 DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
361 ));
362
363 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
364 intent.priority(), rule.priority()));
365
366 sut.deactivate();
367 }
368
369 /**
370 * Tests compile of OpticalOduIntent with allocation of TributarySlots.
371 * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
372 * - All TributarySlots are used
373 */
374 @Test
375 public void test10GbeMultiplexOverOdu2() {
376
377 intent = OpticalOduIntent.builder()
378 .appId(APP_ID)
379 .key(KEY1)
380 .src(d1p3)
381 .dst(d3p3)
382 .signalType(D1P3.signalType())
383 .bidirectional(false)
384 .build();
385
386 sut.activate();
387
388 List<Intent> compiled = sut.compile(intent, Collections.emptyList());
389 assertThat(compiled, hasSize(1));
390
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700391 assertThat("key is inherited",
392 compiled.stream().map(Intent::key).collect(Collectors.toList()),
393 everyItem(is(intent.key())));
394
Rimon Ashkenazy27438ff2016-03-22 15:57:45 +0200395 Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
396
397 // 1st Device
398 FlowRule rule1 = rules.stream()
399 .filter(x -> x.deviceId().equals(device1.id()))
400 .findFirst()
401 .get();
402 // validate SRC selector
403 TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
404 selectorBuilder1.matchInPort(d1p3.port());
405 selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
406 assertThat(rule1.selector(), is(selectorBuilder1.build()));
407
408 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
409 TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
410 treatmentBuilder1.setOutput(d1p2.port());
411 assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
412
413 // 2nd Device
414 FlowRule rule2 = rules.stream()
415 .filter(x -> x.deviceId().equals(device2.id()))
416 .findFirst()
417 .get();
418 // validate SRC selector
419 TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
420 selectorBuilder2.matchInPort(d2p1.port());
421 selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
422 assertThat(rule2.selector(), is(selectorBuilder2.build()));
423
424 // validate SRC treatment (without OduSignalId - all TributarySlots are used)
425 TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
426 treatmentBuilder2.setOutput(d2p2.port());
427 assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
428
429
430 // 3rd Device
431 FlowRule rule3 = rules.stream()
432 .filter(x -> x.deviceId().equals(device3.id()))
433 .findFirst()
434 .get();
435 // validate DST selector (without OduSignalId - all TributarySlots are used)
436 TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
437 selectorBuilder3.matchInPort(d3p1.port());
438 selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
439 assertThat(rule3.selector(), is(selectorBuilder3.build()));
440
441 // validate DST treatment
442 assertThat(rule3.treatment(), is(
443 DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
444 ));
445
446 rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
447 intent.priority(), rule.priority()));
448
449 sut.deactivate();
450 }
451
452}