blob: 9cdf90e0542b76d85f5fa689ba6684b9161a9f65 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
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 Milkeyd9bbde82016-06-09 11:35:00 -070018import java.nio.ByteBuffer;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25import java.util.concurrent.CompletableFuture;
26
alshabib0ed6a202014-10-19 12:42:57 -070027import org.junit.After;
28import org.junit.Before;
29import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onlab.packet.ChassisId;
31import org.onlab.packet.Ethernet;
Charles Chan928ff8b2017-05-04 12:22:54 -070032import org.onlab.packet.MacAddress;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080033import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070034import org.onosproject.cfg.ComponentConfigAdapter;
Ayaka Koshibe07e9d412016-05-20 13:37:16 -070035import org.onosproject.cluster.ClusterMetadataServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080036import org.onosproject.cluster.NodeId;
37import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080038import org.onosproject.core.ApplicationId;
39import org.onosproject.core.CoreService;
40import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.mastership.MastershipListener;
42import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070043import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070045import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.DefaultDevice;
47import org.onosproject.net.DefaultPort;
48import org.onosproject.net.Device;
49import org.onosproject.net.DeviceId;
50import org.onosproject.net.MastershipRole;
51import org.onosproject.net.Port;
52import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060053import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060054import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080055import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060056import org.onosproject.net.config.NetworkConfigListener;
57import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080058import org.onosproject.net.device.DeviceEvent;
59import org.onosproject.net.device.DeviceListener;
60import org.onosproject.net.device.DeviceServiceAdapter;
61import org.onosproject.net.flow.TrafficTreatment;
Ray Milkeycd6ab182016-02-03 11:13:09 -080062import org.onosproject.net.link.LinkProviderRegistryAdapter;
63import org.onosproject.net.link.LinkProviderServiceAdapter;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070064import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080065import org.onosproject.net.packet.DefaultInboundPacket;
66import org.onosproject.net.packet.InboundPacket;
67import org.onosproject.net.packet.OutboundPacket;
68import org.onosproject.net.packet.PacketContext;
69import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070070import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080071import org.onosproject.net.provider.ProviderId;
Ray Milkey957390e2016-02-09 10:02:46 -080072import org.onosproject.provider.lldpcommon.LinkDiscovery;
alshabib0ed6a202014-10-19 12:42:57 -070073
Ray Milkeyd9bbde82016-06-09 11:35:00 -070074import com.google.common.collect.ArrayListMultimap;
75import com.google.common.collect.ImmutableList;
76import com.google.common.collect.ImmutableMap;
77import com.google.common.collect.ImmutableSet;
78import com.google.common.collect.Lists;
79import com.google.common.util.concurrent.MoreExecutors;
Thomas Vachuska27bee092015-06-23 19:03:10 -070080
Naoki Shiota399a0b32015-11-15 20:36:13 -060081import static org.easymock.EasyMock.createMock;
82import static org.easymock.EasyMock.expect;
83import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060084import static org.junit.Assert.assertEquals;
Ray Milkeycd6ab182016-02-03 11:13:09 -080085import static org.junit.Assert.assertFalse;
86import static org.junit.Assert.assertNotNull;
87import static org.junit.Assert.assertNull;
Naoki Shiota399a0b32015-11-15 20:36:13 -060088import static org.junit.Assert.assertTrue;
Thomas Vachuskab5f6f522016-03-01 13:52:10 -080089import static org.onlab.junit.TestTools.assertAfter;
Naoki Shiota399a0b32015-11-15 20:36:13 -060090import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
Naoki Shiota399a0b32015-11-15 20:36:13 -060091
alshabib0ed6a202014-10-19 12:42:57 -070092
Jonathan Hartb35540a2015-11-17 09:30:56 -080093public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -070094
95 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
96 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070097 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
Thomas Vachuskab5f6f522016-03-01 13:52:10 -080098 private static final int EVENT_MS = 500;
alshabib0ed6a202014-10-19 12:42:57 -070099
100 private static Port pd1;
101 private static Port pd2;
102 private static Port pd3;
103 private static Port pd4;
104
Jonathan Hartb35540a2015-11-17 09:30:56 -0800105 private final LldpLinkProvider provider = new LldpLinkProvider();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800106 private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700107 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700108 private final TestPacketService packetService = new TestPacketService();
109 private final TestDeviceService deviceService = new TestDeviceService();
110 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600111 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700112
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800113 private CoreService coreService;
Ray Milkeycd6ab182016-02-03 11:13:09 -0800114 private LinkProviderServiceAdapter providerService;
alshabib0ed6a202014-10-19 12:42:57 -0700115
116 private PacketProcessor testProcessor;
117 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600118 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700119
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800120 private ApplicationId appId =
121 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800122
Naoki Shiota399a0b32015-11-15 20:36:13 -0600123 private TestSuppressionConfig cfg;
124
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800125 private Set<DeviceId> deviceBlacklist;
126
127 private Set<ConnectPoint> portBlacklist;
128
alshabib0ed6a202014-10-19 12:42:57 -0700129 @Before
130 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800131 deviceBlacklist = new HashSet<>();
132 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600133 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800134 coreService = createMock(CoreService.class);
135 expect(coreService.registerApplication(appId.name()))
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800136 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800137 replay(coreService);
138
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700139 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800140 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600141 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800142
alshabib0ed6a202014-10-19 12:42:57 -0700143 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700144 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800145 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700146 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700147 provider.masterService = masterService;
Ayaka Koshibe07e9d412016-05-20 13:37:16 -0700148 provider.clusterMetadataService = new ClusterMetadataServiceAdapter();
Ray Milkeycd6ab182016-02-03 11:13:09 -0800149
Saurav Dasc313c402015-02-27 10:09:47 -0800150 provider.activate(null);
Ray Milkeycd6ab182016-02-03 11:13:09 -0800151
Ray Milkeyd9bbde82016-06-09 11:35:00 -0700152 provider.eventExecutor = MoreExecutors.newDirectExecutorService();
153
Ray Milkeycd6ab182016-02-03 11:13:09 -0800154 providerService = linkRegistry.registeredProvider();
alshabib0ed6a202014-10-19 12:42:57 -0700155 }
156
157 @Test
158 public void basics() {
159 assertNotNull("registration expected", providerService);
160 assertEquals("incorrect provider", provider, providerService.provider());
161 }
162
163 @Test
164 public void switchAdd() {
165 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
166 deviceListener.event(de);
167
168 assertFalse("Device not added", provider.discoverers.isEmpty());
169 }
170
171 @Test
172 public void switchRemove() {
173 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
174 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
175
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700176 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
177 if (linkDiscovery != null) {
178 // If LinkDiscovery helper is there after DEVICE_REMOVED,
179 // it should be stopped
180 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
181 }
alshabib0ed6a202014-10-19 12:42:57 -0700182 assertTrue("Device is not gone.", vanishedDpid(DID1));
183 }
184
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700185 /**
186 * Checks that links on a reconfigured switch are properly removed.
187 */
188 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800189 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600190
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700191 // add device to stub DeviceService
192 deviceService.putDevice(device(DID3));
193 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
194
195 assertFalse("Device not added", provider.discoverers.isEmpty());
196
197 // update device in stub DeviceService with suppression config
198 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800199 .set(LldpLinkProvider.NO_LLDP, "true")
200 .build()));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700201 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
202
Naoki Shiota399a0b32015-11-15 20:36:13 -0600203 // discovery on device is expected to be gone or stopped
204 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
205 if (linkDiscovery != null) {
206 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
207 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700208 }
209
alshabib0ed6a202014-10-19 12:42:57 -0700210 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800211 public void switchSuppressByBlacklist() {
212 // add device in stub DeviceService
213 deviceService.putDevice(device(DID3));
214 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
215
216 // add deviveId to device blacklist
217 deviceBlacklist.add(DID3);
218 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
219 DID3,
220 LinkDiscoveryFromDevice.class));
221
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800222 assertAfter(EVENT_MS, () -> {
223 // discovery helper for device is expected to be gone or stopped
224 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
225 if (linkDiscovery != null) {
226 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
227 }
228 });
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800229 }
230
231 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700232 public void portUp() {
233 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
234 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
235
236 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700237 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700238 }
239
240 @Test
241 public void portDown() {
242
243 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
244 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
245
alshabib0ed6a202014-10-19 12:42:57 -0700246 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700247 provider.discoverers.get(DID1).containsPort(1L));
248 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700249 }
250
251 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700252 public void portRemoved() {
253 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
254 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
255 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
256
257 assertTrue("Port is not gone.", vanishedPort(3L));
258 assertFalse("Port was not removed from discoverer",
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800259 provider.discoverers.get(DID1).containsPort(3L));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700260 }
261
262 /**
263 * Checks that discovery on reconfigured switch are properly restarted.
264 */
265 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600266 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700267
268 /// When Device is configured with suppression:ON, Port also is same
269
270 // add device in stub DeviceService with suppression configured
271 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800272 .set(LldpLinkProvider.NO_LLDP, "true")
273 .build()));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700274 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
275
276 // non-suppressed port added to suppressed device
277 final long portno3 = 3L;
278 deviceService.putPorts(DID3, port(DID3, portno3, true));
279 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
280
281 // discovery on device is expected to be stopped
282 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
283 if (linkDiscovery != null) {
284 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
285 }
286
287 /// When Device is reconfigured without suppression:OFF,
288 /// Port should be included for discovery
289
290 // update device in stub DeviceService without suppression configured
291 deviceService.putDevice(device(DID3));
292 // update the Port in stub DeviceService. (Port has reference to Device)
293 deviceService.putPorts(DID3, port(DID3, portno3, true));
294 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
295
296 // discovery should come back on
297 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
298 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
299 }
300
301 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600302 * Checks that discovery on reconfigured switch are properly restarted.
303 */
304 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800305 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600306
307 /// When Device is configured without suppression:OFF,
308 /// Port should be included for discovery
309
310 // add device in stub DeviceService without suppression configured
311 deviceService.putDevice(device(DID3));
312 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
313
314 // non-suppressed port added to suppressed device
315 final long portno3 = 3L;
316 deviceService.putPorts(DID3, port(DID3, portno3, true));
317 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
318
319 // discovery should succeed
320 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
321 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
322
323 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800324 deviceBlacklist.add(DID3);
325 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
326 DID3,
327 LinkDiscoveryFromDevice.class));
328
Naoki Shiota399a0b32015-11-15 20:36:13 -0600329
330 /// When Device is reconfigured with suppression:ON, Port also is same
331
332 // update device in stub DeviceService with suppression configured
333 deviceService.putDevice(device(DID3));
334 // update the Port in stub DeviceService. (Port has reference to Device)
335 deviceService.putPorts(DID3, port(DID3, portno3, true));
336 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
337
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800338 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600339 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
340 if (linkDiscovery != null) {
341 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
342 }
343 }
344
345 /**
346 * Checks that discovery on reconfigured switch are properly restarted.
347 */
348 @Test
349 public void portSuppressedByDeviceTypeConfig() {
350
351 /// When Device is configured without suppression:OFF,
352 /// Port should be included for discovery
353
354 // add device in stub DeviceService without suppression configured
355 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
356 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
357
358 // non-suppressed port added to suppressed device
359 final long portno3 = 3L;
360 deviceService.putPorts(DID1, port(DID1, portno3, true));
361 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
362
363 // add device in stub DeviceService with suppression configured
364 deviceService.putDevice(device(DID2, Device.Type.ROADM));
365 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
366
367 // non-suppressed port added to suppressed device
368 final long portno4 = 4L;
369 deviceService.putPorts(DID2, port(DID2, portno4, true));
370 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
371
372 // discovery should succeed for this device
373 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
374 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
375
376 // discovery on device is expected to be stopped for this device
377 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
378 if (linkDiscovery != null) {
379 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
380 }
381 }
382
383 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700384 * Checks that discovery on reconfigured port are properly restarted.
385 */
386 @Test
387 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600388
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700389 // add device in stub DeviceService without suppression configured
390 deviceService.putDevice(device(DID3));
391 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
392
393 // suppressed port added to non-suppressed device
394 final long portno3 = 3L;
395 final Port port3 = port(DID3, portno3, true,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800396 DefaultAnnotations.builder()
397 .set(LldpLinkProvider.NO_LLDP, "true")
398 .build());
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700399 deviceService.putPorts(DID3, port3);
400 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
401
402 // discovery helper should be there turned on
403 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
404 assertFalse("Discoverer should not contain the port there",
405 provider.discoverers.get(DID3).containsPort(portno3));
406 }
407
408 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800409 public void portSuppressedByPortBlacklist() {
410
411 // add device in stub DeviceService without suppression configured
412 deviceService.putDevice(device(DID3));
413 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
414
415 final long portno3 = 3L;
416 final Port port3 = port(DID3, portno3, true);
417
418 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
419 portBlacklist.add(cpDid3no3);
420
421 // suppressed port added to non-suppressed device
422 deviceService.putPorts(DID3, port3);
423 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
424
425 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
426 cpDid3no3,
427 LinkDiscoveryFromPort.class));
428
429 // discovery helper should be there turned on
430 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
431 // but port is not a discovery target
432 assertFalse("Discoverer should not contain the port there",
433 provider.discoverers.get(DID3).containsPort(portno3));
434 }
435
436 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700437 public void portUnknown() {
438 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700439 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
440 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700441
442
alshabibdfc7afb2014-10-21 20:13:27 -0700443 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700444 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700445 }
446
447 @Test
448 public void unknownPktCtx() {
449
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700450 // Note: DID3 hasn't been added to TestDeviceService
451 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700452
453 testProcessor.process(pktCtx);
454 assertFalse("Context should still be free", pktCtx.isHandled());
455 }
456
457 @Test
458 public void knownPktCtx() {
459 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
460 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
461 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
462
463
464 testProcessor.process(pktCtx);
465
466 assertTrue("Link not detected", detectedLink(DID1, DID2));
467
468 }
469
470
471 @After
472 public void tearDown() {
473 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800474 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700475 provider.providerRegistry = null;
476 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800477 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700478 }
479
480 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
481 return new DeviceEvent(type, deviceService.getDevice(did));
482
483 }
484
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700485 private DefaultDevice device(DeviceId did) {
486 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800487 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700488 }
489
Naoki Shiota399a0b32015-11-15 20:36:13 -0600490 private DefaultDevice device(DeviceId did, Device.Type type) {
491 return new DefaultDevice(ProviderId.NONE, did, type,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800492 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
Naoki Shiota399a0b32015-11-15 20:36:13 -0600493 }
494
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700495 private DefaultDevice device(DeviceId did, Annotations annotations) {
496 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800497 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700498 }
499
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800500 @SuppressWarnings(value = {"unused"})
alshabib0ed6a202014-10-19 12:42:57 -0700501 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800502 return new DeviceEvent(type, deviceService.getDevice(did),
503 deviceService.getPort(did, port));
alshabib0ed6a202014-10-19 12:42:57 -0700504 }
505
506 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800507 return new DeviceEvent(type, deviceService.getDevice(did), port);
alshabib0ed6a202014-10-19 12:42:57 -0700508 }
509
510 private Port port(DeviceId did, long port, boolean enabled) {
511 return new DefaultPort(deviceService.getDevice(did),
512 PortNumber.portNumber(port), enabled);
513 }
514
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700515 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
516 return new DefaultPort(deviceService.getDevice(did),
517 PortNumber.portNumber(port), enabled, annotations);
518 }
alshabib0ed6a202014-10-19 12:42:57 -0700519
520 private boolean vanishedDpid(DeviceId... dids) {
521 for (int i = 0; i < dids.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800522 if (!providerService.vanishedDpid().contains(dids[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700523 return false;
524 }
525 }
526 return true;
527 }
528
529 private boolean vanishedPort(Long... ports) {
530 for (int i = 0; i < ports.length; i++) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800531 if (!providerService.vanishedPort().contains(ports[i])) {
alshabib0ed6a202014-10-19 12:42:57 -0700532 return false;
533 }
534 }
535 return true;
536 }
537
538 private boolean detectedLink(DeviceId src, DeviceId dst) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800539 for (DeviceId key : providerService.discoveredLinks().keySet()) {
alshabib0ed6a202014-10-19 12:42:57 -0700540 if (key.equals(src)) {
Ray Milkeycd6ab182016-02-03 11:13:09 -0800541 return providerService.discoveredLinks().get(src).equals(dst);
alshabib0ed6a202014-10-19 12:42:57 -0700542 }
543 }
544 return false;
545 }
546
Naoki Shiota399a0b32015-11-15 20:36:13 -0600547 @Test
548 public void addDeviceTypeRule() {
549 Device.Type deviceType1 = Device.Type.ROADM;
550 Device.Type deviceType2 = Device.Type.SWITCH;
551
552 Set<Device.Type> deviceTypes = new HashSet<>();
553 deviceTypes.add(deviceType1);
554
555 cfg.deviceTypes(deviceTypes);
556
557 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
558
559 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
560 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
561 }
562
563 @Test
564 public void updateDeviceTypeRule() {
565 Device.Type deviceType1 = Device.Type.ROADM;
566 Device.Type deviceType2 = Device.Type.SWITCH;
567 Set<Device.Type> deviceTypes = new HashSet<>();
568
569 deviceTypes.add(deviceType1);
570 cfg.deviceTypes(deviceTypes);
571
572 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
573
574 deviceTypes.add(deviceType2);
575 cfg.deviceTypes(deviceTypes);
576
577 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
578
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800579 assertAfter(EVENT_MS, () -> {
580 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
581 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
582 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600583 }
584
585 @Test
586 public void addAnnotationRule() {
587 final String key1 = "key1", key2 = "key2";
588 final String value1 = "value1";
589
590 Map<String, String> annotation = new HashMap<>();
591 annotation.put(key1, value1);
592
593 cfg.annotation(annotation);
594
595 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
596
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800597 assertAfter(EVENT_MS, () -> {
598 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
599 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
600 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
601 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600602 }
603
604 @Test
605 public void updateAnnotationRule() {
606 final String key1 = "key1", key2 = "key2";
607 final String value1 = "value1", value2 = "value2";
608 Map<String, String> annotation = new HashMap<>();
609
610 annotation.put(key1, value1);
611 cfg.annotation(annotation);
612
613 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
614
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800615 assertAfter(EVENT_MS, () -> {
616 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
617 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
618 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
619 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600620
621 annotation.put(key2, value2);
622 cfg.annotation(annotation);
623
624 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
625
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800626 assertAfter(EVENT_MS, () -> {
627 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
628 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
629 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
630 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
631 });
Naoki Shiota399a0b32015-11-15 20:36:13 -0600632 }
633
634 private void configEvent(NetworkConfigEvent.Type evType) {
635 configListener.event(new NetworkConfigEvent(evType,
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800636 appId,
637 SuppressionConfig.class));
Naoki Shiota399a0b32015-11-15 20:36:13 -0600638 }
639
alshabib0ed6a202014-10-19 12:42:57 -0700640 private class TestPacketContext implements PacketContext {
641
642 protected Device device;
643 protected boolean blocked = false;
644
645 public TestPacketContext(Device dev) {
646 device = dev;
647 }
648
649 @Override
650 public long time() {
651 return 0;
652 }
653
654 @Override
655 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800656 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
657 device.chassisId(),
658 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700659
660 Ethernet ethPacket = new Ethernet();
661 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
Charles Chan928ff8b2017-05-04 12:22:54 -0700662 ethPacket.setDestinationMACAddress(MacAddress.ONOS_LLDP);
alshabib0ed6a202014-10-19 12:42:57 -0700663 ethPacket.setPayload(lldp);
664 ethPacket.setPad(true);
665
alshabib0ed6a202014-10-19 12:42:57 -0700666 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
667
668 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
669
670 return new DefaultInboundPacket(cp, ethPacket,
671 ByteBuffer.wrap(ethPacket.serialize()));
672
673 }
674
675 @Override
676 public OutboundPacket outPacket() {
677 return null;
678 }
679
680 @Override
681 public TrafficTreatment.Builder treatmentBuilder() {
682 return null;
683 }
684
685 @Override
686 public void send() {
687
688 }
689
690 @Override
691 public boolean block() {
692 blocked = true;
693 return blocked;
694 }
695
696 @Override
697 public boolean isHandled() {
698 return blocked;
699 }
700
701 }
702
Thomas Vachuska27bee092015-06-23 19:03:10 -0700703 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700704 @Override
705 public void addProcessor(PacketProcessor processor, int priority) {
706 testProcessor = processor;
707 }
alshabib0ed6a202014-10-19 12:42:57 -0700708 }
709
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800710 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700711
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700712 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700713 private final ArrayListMultimap<DeviceId, Port> ports =
714 ArrayListMultimap.create();
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800715
alshabib0ed6a202014-10-19 12:42:57 -0700716 public TestDeviceService() {
717 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
718 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
719 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
720 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
721 devices.put(DID1, d1);
722 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700723 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
724 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
725 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
726 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
727
728 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
729 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700730 }
731
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700732 private void putDevice(Device device) {
733 DeviceId deviceId = device.id();
734 devices.put(deviceId, device);
735 }
736
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800737 private void putPorts(DeviceId did, Port... ports) {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700738 this.ports.putAll(did, Lists.newArrayList(ports));
739 }
740
alshabib0ed6a202014-10-19 12:42:57 -0700741 @Override
742 public int getDeviceCount() {
743 return devices.values().size();
744 }
745
746 @Override
747 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700748 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700749 }
750
751 @Override
752 public Device getDevice(DeviceId deviceId) {
753 return devices.get(deviceId);
754 }
755
756 @Override
757 public MastershipRole getRole(DeviceId deviceId) {
758 return MastershipRole.MASTER;
759 }
760
761 @Override
762 public List<Port> getPorts(DeviceId deviceId) {
763 return ports.get(deviceId);
764 }
765
766 @Override
767 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
768 for (Port p : ports.get(deviceId)) {
769 if (p.number().equals(portNumber)) {
770 return p;
771 }
772 }
773 return null;
774 }
775
776 @Override
777 public boolean isAvailable(DeviceId deviceId) {
778 return true;
779 }
780
781 @Override
782 public void addListener(DeviceListener listener) {
783 deviceListener = listener;
784
785 }
786
787 @Override
788 public void removeListener(DeviceListener listener) {
789
790 }
791 }
792
793 private final class TestMasterShipService implements MastershipService {
794
795 @Override
796 public MastershipRole getLocalRole(DeviceId deviceId) {
797 return MastershipRole.MASTER;
798 }
799
800 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700801 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
802 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700803 }
804
805 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700806 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
807 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700808 }
809
810 @Override
811 public NodeId getMasterFor(DeviceId deviceId) {
812 return null;
813 }
814
815 @Override
816 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
817 return null;
818 }
819
820 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700821 public void addListener(MastershipListener listener) {
822
823 }
824
825 @Override
826 public void removeListener(MastershipListener listener) {
827
828 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700829
830 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700831 public RoleInfo getNodesFor(DeviceId deviceId) {
832 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700833 }
alshabib0ed6a202014-10-19 12:42:57 -0700834 }
835
836
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700837 private class TestLinkService extends LinkServiceAdapter {
838 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600839
840 private final class TestNetworkConfigRegistry
Thomas Vachuskab5f6f522016-03-01 13:52:10 -0800841 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800842 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600843 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800844 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
845 if (configClass == SuppressionConfig.class) {
846 return (C) cfg;
847 } else if (configClass == LinkDiscoveryFromDevice.class) {
848 return (C) new LinkDiscoveryFromDevice() {
849 @Override
850 public boolean enabled() {
851 return !deviceBlacklist.contains(subj);
852 }
853 };
854 } else if (configClass == LinkDiscoveryFromPort.class) {
855 return (C) new LinkDiscoveryFromPort() {
856 @Override
857 public boolean enabled() {
858 return !portBlacklist.contains(subj);
859 }
860 };
861 } else {
862 return null;
863 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600864 }
865
866 @Override
867 public void addListener(NetworkConfigListener listener) {
868 configListener = listener;
869 }
870 }
871
872 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600873 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
874 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
875
876 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600877 public Set<Device.Type> deviceTypes() {
878 return ImmutableSet.copyOf(deviceTypes);
879 }
880
881 @Override
882 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
883 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
884 return this;
885 }
886
887 @Override
888 public Map<String, String> annotation() {
889 return ImmutableMap.copyOf(annotation);
890 }
891
892 @Override
893 public SuppressionConfig annotation(Map<String, String> annotation) {
894 this.annotation = ImmutableMap.copyOf(annotation);
895 return this;
896 }
897 }
alshabib0ed6a202014-10-19 12:42:57 -0700898}