blob: 54bd151f28da612dccaac07342c99bce5af8ac4d [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.lldp.impl;
alshabib0ed6a202014-10-19 12:42:57 -070017
Ray Milkeyeb130702018-06-21 15:19:33 -070018import com.google.common.collect.ArrayListMultimap;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.ImmutableSet;
22import com.google.common.collect.Lists;
23import com.google.common.util.concurrent.MoreExecutors;
alshabib0ed6a202014-10-19 12:42:57 -070024import org.junit.After;
25import org.junit.Before;
26import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080027import org.onlab.packet.ChassisId;
28import org.onlab.packet.Ethernet;
Charles Chan928ff8b2017-05-04 12:22:54 -070029import org.onlab.packet.MacAddress;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070031import org.onosproject.cfg.ComponentConfigAdapter;
Ayaka Koshibe07e9d412016-05-20 13:37:16 -070032import org.onosproject.cluster.ClusterMetadataServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.cluster.NodeId;
34import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080035import org.onosproject.core.ApplicationId;
36import org.onosproject.core.CoreService;
37import org.onosproject.core.DefaultApplicationId;
Ray Milkeyeb130702018-06-21 15:19:33 -070038import org.onosproject.mastership.MastershipServiceAdapter;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070039import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070041import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.DefaultDevice;
43import org.onosproject.net.DefaultPort;
44import org.onosproject.net.Device;
45import org.onosproject.net.DeviceId;
46import org.onosproject.net.MastershipRole;
47import org.onosproject.net.Port;
48import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060049import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060050import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080051import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060052import org.onosproject.net.config.NetworkConfigListener;
53import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080054import org.onosproject.net.device.DeviceEvent;
55import org.onosproject.net.device.DeviceListener;
56import org.onosproject.net.device.DeviceServiceAdapter;
57import org.onosproject.net.flow.TrafficTreatment;
Ray Milkeycd6ab182016-02-03 11:13:09 -080058import org.onosproject.net.link.LinkProviderRegistryAdapter;
59import org.onosproject.net.link.LinkProviderServiceAdapter;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070060import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080061import org.onosproject.net.packet.DefaultInboundPacket;
62import org.onosproject.net.packet.InboundPacket;
63import org.onosproject.net.packet.OutboundPacket;
64import org.onosproject.net.packet.PacketContext;
65import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070066import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080067import org.onosproject.net.provider.ProviderId;
Ray Milkey957390e2016-02-09 10:02:46 -080068import org.onosproject.provider.lldpcommon.LinkDiscovery;
alshabib0ed6a202014-10-19 12:42:57 -070069
Ray Milkeyeb130702018-06-21 15:19:33 -070070import java.nio.ByteBuffer;
71import java.util.Collections;
72import java.util.HashMap;
73import java.util.HashSet;
74import java.util.List;
75import java.util.Map;
76import java.util.Set;
77import java.util.concurrent.CompletableFuture;
Thomas Vachuska27bee092015-06-23 19:03:10 -070078
Naoki Shiota399a0b32015-11-15 20:36:13 -060079import static org.easymock.EasyMock.createMock;
80import static org.easymock.EasyMock.expect;
81import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060082import static org.junit.Assert.assertEquals;
Ray Milkeycd6ab182016-02-03 11:13:09 -080083import static org.junit.Assert.assertFalse;
84import static org.junit.Assert.assertNotNull;
85import static org.junit.Assert.assertNull;
Naoki Shiota399a0b32015-11-15 20:36:13 -060086import static org.junit.Assert.assertTrue;
Thomas Vachuskab5f6f522016-03-01 13:52:10 -080087import static org.onlab.junit.TestTools.assertAfter;
Naoki Shiota399a0b32015-11-15 20:36:13 -060088import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
Naoki Shiota399a0b32015-11-15 20:36:13 -060089
alshabib0ed6a202014-10-19 12:42:57 -070090
Jonathan Hartb35540a2015-11-17 09:30:56 -080091public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -070092
93 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
94 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070095 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
Thomas Vachuskab5f6f522016-03-01 13:52:10 -080096 private static final int EVENT_MS = 500;
alshabib0ed6a202014-10-19 12:42:57 -070097
98 private static Port pd1;
99 private static Port pd2;
100 private static Port pd3;
101 private static Port pd4;
102
Jonathan Hartb35540a2015-11-17 09:30:56 -0800103 private final LldpLinkProvider provider = new LldpLinkProvider();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800104 private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700105 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700106 private final TestPacketService packetService = new TestPacketService();
107 private final TestDeviceService deviceService = new TestDeviceService();
108 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600109 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700110
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800111 private CoreService coreService;
Ray Milkeycd6ab182016-02-03 11:13:09 -0800112 private LinkProviderServiceAdapter providerService;
alshabib0ed6a202014-10-19 12:42:57 -0700113
114 private PacketProcessor testProcessor;
115 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600116 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700117
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800118 private ApplicationId appId =
119 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800120
Naoki Shiota399a0b32015-11-15 20:36:13 -0600121 private TestSuppressionConfig cfg;
122
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800123 private Set<DeviceId> deviceBlacklist;
124
125 private Set<ConnectPoint> portBlacklist;
126
alshabib0ed6a202014-10-19 12:42:57 -0700127 @Before
128 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800129 deviceBlacklist = new HashSet<>();
130 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600131 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800132 coreService = createMock(CoreService.class);
133 expect(coreService.registerApplication(appId.name()))
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800134 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800135 replay(coreService);
136
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700137 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800138 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600139 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800140
alshabib0ed6a202014-10-19 12:42:57 -0700141 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700142 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800143 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700144 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700145 provider.masterService = masterService;
Ayaka Koshibe07e9d412016-05-20 13:37:16 -0700146 provider.clusterMetadataService = new ClusterMetadataServiceAdapter();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800147
Saurav Dasc313c402015-02-27 10:09:47 -0800148 provider.activate(null);
Ray Milkeycd6ab182016-02-03 11:13:09 -0800149
Ray Milkeyd9bbde82016-06-09 11:35:00 -0700150 provider.eventExecutor = MoreExecutors.newDirectExecutorService();
151
Ray Milkeycd6ab182016-02-03 11:13:09 -0800152 providerService = linkRegistry.registeredProvider();
alshabib0ed6a202014-10-19 12:42:57 -0700153 }
154
155 @Test
156 public void basics() {
157 assertNotNull("registration expected", providerService);
158 assertEquals("incorrect provider", provider, providerService.provider());
159 }
160
161 @Test
162 public void switchAdd() {
163 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
164 deviceListener.event(de);
165
166 assertFalse("Device not added", provider.discoverers.isEmpty());
167 }
168
169 @Test
170 public void switchRemove() {
171 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
172 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
173
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700174 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
175 if (linkDiscovery != null) {
176 // If LinkDiscovery helper is there after DEVICE_REMOVED,
177 // it should be stopped
178 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
179 }
alshabib0ed6a202014-10-19 12:42:57 -0700180 assertTrue("Device is not gone.", vanishedDpid(DID1));
181 }
182
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700183 /**
184 * Checks that links on a reconfigured switch are properly removed.
185 */
186 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800187 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600188
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700189 // add device to stub DeviceService
190 deviceService.putDevice(device(DID3));
191 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
192
193 assertFalse("Device not added", provider.discoverers.isEmpty());
194
195 // update device in stub DeviceService with suppression config
196 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800197 .set(LldpLinkProvider.NO_LLDP, "true")
198 .build()));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700199 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
200
Naoki Shiota399a0b32015-11-15 20:36:13 -0600201 // discovery on device is expected to be gone or stopped
202 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
203 if (linkDiscovery != null) {
204 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
205 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700206 }
207
alshabib0ed6a202014-10-19 12:42:57 -0700208 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800209 public void switchSuppressByBlacklist() {
210 // add device in stub DeviceService
211 deviceService.putDevice(device(DID3));
212 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
213
214 // add deviveId to device blacklist
215 deviceBlacklist.add(DID3);
216 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
217 DID3,
218 LinkDiscoveryFromDevice.class));
219
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800220 assertAfter(EVENT_MS, () -> {
221 // discovery helper for device is expected to be gone or stopped
222 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
223 if (linkDiscovery != null) {
224 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
225 }
226 });
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800227 }
228
229 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700230 public void portUp() {
231 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
232 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
233
234 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700235 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700236 }
237
238 @Test
239 public void portDown() {
240
241 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
242 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
243
alshabib0ed6a202014-10-19 12:42:57 -0700244 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700245 provider.discoverers.get(DID1).containsPort(1L));
246 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700247 }
248
249 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700250 public void portRemoved() {
251 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
252 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
253 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
254
255 assertTrue("Port is not gone.", vanishedPort(3L));
256 assertFalse("Port was not removed from discoverer",
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800257 provider.discoverers.get(DID1).containsPort(3L));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700258 }
259
260 /**
261 * Checks that discovery on reconfigured switch are properly restarted.
262 */
263 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600264 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700265
266 /// When Device is configured with suppression:ON, Port also is same
267
268 // add device in stub DeviceService with suppression configured
269 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800270 .set(LldpLinkProvider.NO_LLDP, "true")
271 .build()));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700272 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
273
274 // non-suppressed port added to suppressed device
275 final long portno3 = 3L;
276 deviceService.putPorts(DID3, port(DID3, portno3, true));
277 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
278
279 // discovery on device is expected to be stopped
280 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
281 if (linkDiscovery != null) {
282 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
283 }
284
285 /// When Device is reconfigured without suppression:OFF,
286 /// Port should be included for discovery
287
288 // update device in stub DeviceService without suppression configured
289 deviceService.putDevice(device(DID3));
290 // update the Port in stub DeviceService. (Port has reference to Device)
291 deviceService.putPorts(DID3, port(DID3, portno3, true));
292 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
293
294 // discovery should come back on
295 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
296 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
297 }
298
299 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600300 * Checks that discovery on reconfigured switch are properly restarted.
301 */
302 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800303 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600304
305 /// When Device is configured without suppression:OFF,
306 /// Port should be included for discovery
307
308 // add device in stub DeviceService without suppression configured
309 deviceService.putDevice(device(DID3));
310 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
311
312 // non-suppressed port added to suppressed device
313 final long portno3 = 3L;
314 deviceService.putPorts(DID3, port(DID3, portno3, true));
315 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
316
317 // discovery should succeed
318 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
319 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
320
321 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800322 deviceBlacklist.add(DID3);
323 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
324 DID3,
325 LinkDiscoveryFromDevice.class));
326
Naoki Shiota399a0b32015-11-15 20:36:13 -0600327
328 /// When Device is reconfigured with suppression:ON, Port also is same
329
330 // update device in stub DeviceService with suppression configured
331 deviceService.putDevice(device(DID3));
332 // update the Port in stub DeviceService. (Port has reference to Device)
333 deviceService.putPorts(DID3, port(DID3, portno3, true));
334 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
335
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800336 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600337 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
338 if (linkDiscovery != null) {
339 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
340 }
341 }
342
343 /**
344 * Checks that discovery on reconfigured switch are properly restarted.
345 */
346 @Test
347 public void portSuppressedByDeviceTypeConfig() {
348
349 /// When Device is configured without suppression:OFF,
350 /// Port should be included for discovery
351
352 // add device in stub DeviceService without suppression configured
353 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
354 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
355
356 // non-suppressed port added to suppressed device
357 final long portno3 = 3L;
358 deviceService.putPorts(DID1, port(DID1, portno3, true));
359 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
360
361 // add device in stub DeviceService with suppression configured
362 deviceService.putDevice(device(DID2, Device.Type.ROADM));
363 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
364
365 // non-suppressed port added to suppressed device
366 final long portno4 = 4L;
367 deviceService.putPorts(DID2, port(DID2, portno4, true));
368 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
369
370 // discovery should succeed for this device
371 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
372 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
373
374 // discovery on device is expected to be stopped for this device
375 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
376 if (linkDiscovery != null) {
377 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
378 }
379 }
380
381 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700382 * Checks that discovery on reconfigured port are properly restarted.
383 */
384 @Test
385 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600386
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700387 // add device in stub DeviceService without suppression configured
388 deviceService.putDevice(device(DID3));
389 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
390
391 // suppressed port added to non-suppressed device
392 final long portno3 = 3L;
393 final Port port3 = port(DID3, portno3, true,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800394 DefaultAnnotations.builder()
395 .set(LldpLinkProvider.NO_LLDP, "true")
396 .build());
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700397 deviceService.putPorts(DID3, port3);
398 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
399
400 // discovery helper should be there turned on
401 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
402 assertFalse("Discoverer should not contain the port there",
403 provider.discoverers.get(DID3).containsPort(portno3));
404 }
405
406 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800407 public void portSuppressedByPortBlacklist() {
408
409 // add device in stub DeviceService without suppression configured
410 deviceService.putDevice(device(DID3));
411 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
412
413 final long portno3 = 3L;
414 final Port port3 = port(DID3, portno3, true);
415
416 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
417 portBlacklist.add(cpDid3no3);
418
419 // suppressed port added to non-suppressed device
420 deviceService.putPorts(DID3, port3);
421 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
422
423 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
424 cpDid3no3,
425 LinkDiscoveryFromPort.class));
426
427 // discovery helper should be there turned on
428 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
429 // but port is not a discovery target
430 assertFalse("Discoverer should not contain the port there",
431 provider.discoverers.get(DID3).containsPort(portno3));
432 }
433
434 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700435 public void portUnknown() {
436 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700437 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
438 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700439
440
alshabibdfc7afb2014-10-21 20:13:27 -0700441 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700442 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700443 }
444
445 @Test
446 public void unknownPktCtx() {
447
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700448 // Note: DID3 hasn't been added to TestDeviceService
449 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700450
451 testProcessor.process(pktCtx);
452 assertFalse("Context should still be free", pktCtx.isHandled());
453 }
454
455 @Test
456 public void knownPktCtx() {
457 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
458 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
459 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
460
461
462 testProcessor.process(pktCtx);
463
464 assertTrue("Link not detected", detectedLink(DID1, DID2));
465
466 }
467
468
469 @After
470 public void tearDown() {
471 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800472 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700473 provider.providerRegistry = null;
474 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800475 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700476 }
477
478 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
479 return new DeviceEvent(type, deviceService.getDevice(did));
480
481 }
482
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700483 private DefaultDevice device(DeviceId did) {
484 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800485 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700486 }
487
Naoki Shiota399a0b32015-11-15 20:36:13 -0600488 private DefaultDevice device(DeviceId did, Device.Type type) {
489 return new DefaultDevice(ProviderId.NONE, did, type,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800490 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
Naoki Shiota399a0b32015-11-15 20:36:13 -0600491 }
492
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700493 private DefaultDevice device(DeviceId did, Annotations annotations) {
494 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800495 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700496 }
497
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800498 @SuppressWarnings(value = {"unused"})
alshabib0ed6a202014-10-19 12:42:57 -0700499 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800500 return new DeviceEvent(type, deviceService.getDevice(did),
501 deviceService.getPort(did, port));
alshabib0ed6a202014-10-19 12:42:57 -0700502 }
503
504 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800505 return new DeviceEvent(type, deviceService.getDevice(did), port);
alshabib0ed6a202014-10-19 12:42:57 -0700506 }
507
508 private Port port(DeviceId did, long port, boolean enabled) {
509 return new DefaultPort(deviceService.getDevice(did),
510 PortNumber.portNumber(port), enabled);
511 }
512
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700513 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
514 return new DefaultPort(deviceService.getDevice(did),
515 PortNumber.portNumber(port), enabled, annotations);
516 }
alshabib0ed6a202014-10-19 12:42:57 -0700517
518 private boolean vanishedDpid(DeviceId... dids) {
519 for (int i = 0; i < dids.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800520 if (!providerService.vanishedDpid().contains(dids[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700521 return false;
522 }
523 }
524 return true;
525 }
526
527 private boolean vanishedPort(Long... ports) {
528 for (int i = 0; i < ports.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800529 if (!providerService.vanishedPort().contains(ports[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700530 return false;
531 }
532 }
533 return true;
534 }
535
536 private boolean detectedLink(DeviceId src, DeviceId dst) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800537 for (DeviceId key : providerService.discoveredLinks().keySet()) {
alshabib0ed6a202014-10-19 12:42:57 -0700538 if (key.equals(src)) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800539 return providerService.discoveredLinks().get(src).equals(dst);
alshabib0ed6a202014-10-19 12:42:57 -0700540 }
541 }
542 return false;
543 }
544
Naoki Shiota399a0b32015-11-15 20:36:13 -0600545 @Test
546 public void addDeviceTypeRule() {
547 Device.Type deviceType1 = Device.Type.ROADM;
548 Device.Type deviceType2 = Device.Type.SWITCH;
549
550 Set<Device.Type> deviceTypes = new HashSet<>();
551 deviceTypes.add(deviceType1);
552
553 cfg.deviceTypes(deviceTypes);
554
555 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
556
557 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
558 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
559 }
560
561 @Test
562 public void updateDeviceTypeRule() {
563 Device.Type deviceType1 = Device.Type.ROADM;
564 Device.Type deviceType2 = Device.Type.SWITCH;
565 Set<Device.Type> deviceTypes = new HashSet<>();
566
567 deviceTypes.add(deviceType1);
568 cfg.deviceTypes(deviceTypes);
569
570 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
571
572 deviceTypes.add(deviceType2);
573 cfg.deviceTypes(deviceTypes);
574
575 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
576
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800577 assertAfter(EVENT_MS, () -> {
578 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
579 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
580 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600581 }
582
583 @Test
584 public void addAnnotationRule() {
585 final String key1 = "key1", key2 = "key2";
586 final String value1 = "value1";
587
588 Map<String, String> annotation = new HashMap<>();
589 annotation.put(key1, value1);
590
591 cfg.annotation(annotation);
592
593 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
594
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800595 assertAfter(EVENT_MS, () -> {
596 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
597 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
598 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
599 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600600 }
601
602 @Test
603 public void updateAnnotationRule() {
604 final String key1 = "key1", key2 = "key2";
605 final String value1 = "value1", value2 = "value2";
606 Map<String, String> annotation = new HashMap<>();
607
608 annotation.put(key1, value1);
609 cfg.annotation(annotation);
610
611 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
612
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800613 assertAfter(EVENT_MS, () -> {
614 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
615 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
616 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
617 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600618
619 annotation.put(key2, value2);
620 cfg.annotation(annotation);
621
622 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
623
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800624 assertAfter(EVENT_MS, () -> {
625 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
626 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
627 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
628 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
629 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600630 }
631
632 private void configEvent(NetworkConfigEvent.Type evType) {
633 configListener.event(new NetworkConfigEvent(evType,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800634 appId,
635 SuppressionConfig.class));
Naoki Shiota399a0b32015-11-15 20:36:13 -0600636 }
637
alshabib0ed6a202014-10-19 12:42:57 -0700638 private class TestPacketContext implements PacketContext {
639
640 protected Device device;
641 protected boolean blocked = false;
642
643 public TestPacketContext(Device dev) {
644 device = dev;
645 }
646
647 @Override
648 public long time() {
649 return 0;
650 }
651
652 @Override
653 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800654 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
655 device.chassisId(),
656 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700657
658 Ethernet ethPacket = new Ethernet();
659 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
Charles Chan928ff8b2017-05-04 12:22:54 -0700660 ethPacket.setDestinationMACAddress(MacAddress.ONOS_LLDP);
alshabib0ed6a202014-10-19 12:42:57 -0700661 ethPacket.setPayload(lldp);
662 ethPacket.setPad(true);
663
alshabib0ed6a202014-10-19 12:42:57 -0700664 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
665
666 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
667
668 return new DefaultInboundPacket(cp, ethPacket,
669 ByteBuffer.wrap(ethPacket.serialize()));
670
671 }
672
673 @Override
674 public OutboundPacket outPacket() {
675 return null;
676 }
677
678 @Override
679 public TrafficTreatment.Builder treatmentBuilder() {
680 return null;
681 }
682
683 @Override
684 public void send() {
685
686 }
687
688 @Override
689 public boolean block() {
690 blocked = true;
691 return blocked;
692 }
693
694 @Override
695 public boolean isHandled() {
696 return blocked;
697 }
698
699 }
700
Thomas Vachuska27bee092015-06-23 19:03:10 -0700701 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700702 @Override
703 public void addProcessor(PacketProcessor processor, int priority) {
704 testProcessor = processor;
705 }
alshabib0ed6a202014-10-19 12:42:57 -0700706 }
707
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800708 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700709
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700710 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700711 private final ArrayListMultimap<DeviceId, Port> ports =
712 ArrayListMultimap.create();
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800713
alshabib0ed6a202014-10-19 12:42:57 -0700714 public TestDeviceService() {
715 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
716 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
717 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
718 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
719 devices.put(DID1, d1);
720 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700721 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
722 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
723 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
724 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
725
726 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
727 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700728 }
729
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700730 private void putDevice(Device device) {
731 DeviceId deviceId = device.id();
732 devices.put(deviceId, device);
733 }
734
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800735 private void putPorts(DeviceId did, Port... ports) {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700736 this.ports.putAll(did, Lists.newArrayList(ports));
737 }
738
alshabib0ed6a202014-10-19 12:42:57 -0700739 @Override
740 public int getDeviceCount() {
741 return devices.values().size();
742 }
743
744 @Override
745 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700746 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700747 }
748
749 @Override
750 public Device getDevice(DeviceId deviceId) {
751 return devices.get(deviceId);
752 }
753
754 @Override
755 public MastershipRole getRole(DeviceId deviceId) {
756 return MastershipRole.MASTER;
757 }
758
759 @Override
760 public List<Port> getPorts(DeviceId deviceId) {
761 return ports.get(deviceId);
762 }
763
764 @Override
765 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
766 for (Port p : ports.get(deviceId)) {
767 if (p.number().equals(portNumber)) {
768 return p;
769 }
770 }
771 return null;
772 }
773
774 @Override
775 public boolean isAvailable(DeviceId deviceId) {
776 return true;
777 }
778
779 @Override
780 public void addListener(DeviceListener listener) {
781 deviceListener = listener;
782
783 }
784
785 @Override
786 public void removeListener(DeviceListener listener) {
787
788 }
789 }
790
Ray Milkeyeb130702018-06-21 15:19:33 -0700791 private final class TestMasterShipService extends MastershipServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700792
793 @Override
794 public MastershipRole getLocalRole(DeviceId deviceId) {
795 return MastershipRole.MASTER;
796 }
797
798 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700799 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
800 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700801 }
802
803 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700804 public RoleInfo getNodesFor(DeviceId deviceId) {
805 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700806 }
alshabib0ed6a202014-10-19 12:42:57 -0700807 }
808
809
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700810 private class TestLinkService extends LinkServiceAdapter {
811 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600812
813 private final class TestNetworkConfigRegistry
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800814 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800815 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600816 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800817 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
818 if (configClass == SuppressionConfig.class) {
819 return (C) cfg;
820 } else if (configClass == LinkDiscoveryFromDevice.class) {
821 return (C) new LinkDiscoveryFromDevice() {
822 @Override
823 public boolean enabled() {
824 return !deviceBlacklist.contains(subj);
825 }
826 };
827 } else if (configClass == LinkDiscoveryFromPort.class) {
828 return (C) new LinkDiscoveryFromPort() {
829 @Override
830 public boolean enabled() {
831 return !portBlacklist.contains(subj);
832 }
833 };
834 } else {
835 return null;
836 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600837 }
838
839 @Override
840 public void addListener(NetworkConfigListener listener) {
841 configListener = listener;
842 }
843 }
844
845 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600846 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
847 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
848
849 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600850 public Set<Device.Type> deviceTypes() {
851 return ImmutableSet.copyOf(deviceTypes);
852 }
853
854 @Override
855 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
856 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
857 return this;
858 }
859
860 @Override
861 public Map<String, String> annotation() {
862 return ImmutableMap.copyOf(annotation);
863 }
864
865 @Override
866 public SuppressionConfig annotation(Map<String, String> annotation) {
867 this.annotation = ImmutableMap.copyOf(annotation);
868 return this;
869 }
870 }
alshabib0ed6a202014-10-19 12:42:57 -0700871}