blob: 28b08eae86d2aee358c89da33948d5c2e6b1b77f [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.ArrayListMultimap;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070019import com.google.common.collect.ImmutableList;
Naoki Shiota399a0b32015-11-15 20:36:13 -060020import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.ImmutableSet;
Thomas Vachuska27bee092015-06-23 19:03:10 -070022import com.google.common.collect.Lists;
23import com.google.common.collect.Maps;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080024import com.google.common.collect.Sets;
25
alshabib0ed6a202014-10-19 12:42:57 -070026import org.junit.After;
27import org.junit.Before;
28import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080029import org.onlab.packet.ChassisId;
30import org.onlab.packet.Ethernet;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080031import org.onlab.packet.IpAddress;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080032import org.onlab.packet.ONOSLLDP;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070033import org.onosproject.cfg.ComponentConfigAdapter;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080034import org.onosproject.cluster.ClusterMetadata;
35import org.onosproject.cluster.ClusterMetadataService;
36import org.onosproject.cluster.ControllerNode;
37import org.onosproject.cluster.DefaultControllerNode;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.cluster.NodeId;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080039import org.onosproject.cluster.Partition;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080041import org.onosproject.core.ApplicationId;
42import org.onosproject.core.CoreService;
43import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080044import org.onosproject.mastership.MastershipListener;
45import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070046import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070048import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080049import org.onosproject.net.DefaultDevice;
50import org.onosproject.net.DefaultPort;
51import org.onosproject.net.Device;
52import org.onosproject.net.DeviceId;
53import org.onosproject.net.MastershipRole;
54import org.onosproject.net.Port;
55import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060056import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060057import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080058import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060059import org.onosproject.net.config.NetworkConfigListener;
60import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080061import org.onosproject.net.device.DeviceEvent;
62import org.onosproject.net.device.DeviceListener;
63import org.onosproject.net.device.DeviceServiceAdapter;
64import org.onosproject.net.flow.TrafficTreatment;
65import org.onosproject.net.link.LinkDescription;
66import org.onosproject.net.link.LinkProvider;
67import org.onosproject.net.link.LinkProviderRegistry;
68import org.onosproject.net.link.LinkProviderService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070069import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080070import org.onosproject.net.packet.DefaultInboundPacket;
71import org.onosproject.net.packet.InboundPacket;
72import org.onosproject.net.packet.OutboundPacket;
73import org.onosproject.net.packet.PacketContext;
74import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070075import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080076import org.onosproject.net.provider.AbstractProviderService;
77import org.onosproject.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070078
Thomas Vachuska27bee092015-06-23 19:03:10 -070079import java.nio.ByteBuffer;
Thomas Vachuska27bee092015-06-23 19:03:10 -070080import java.util.HashMap;
Naoki Shiota399a0b32015-11-15 20:36:13 -060081import java.util.HashSet;
Thomas Vachuska27bee092015-06-23 19:03:10 -070082import java.util.List;
83import java.util.Map;
84import java.util.Set;
Naoki Shiota399a0b32015-11-15 20:36:13 -060085import java.util.Collections;
Thomas Vachuska27bee092015-06-23 19:03:10 -070086import java.util.concurrent.CompletableFuture;
87
Naoki Shiota399a0b32015-11-15 20:36:13 -060088import static org.easymock.EasyMock.createMock;
89import static org.easymock.EasyMock.expect;
90import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060091import static org.junit.Assert.assertNull;
92import static org.junit.Assert.assertNotNull;
93import static org.junit.Assert.assertEquals;
94import static org.junit.Assert.assertTrue;
95import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
96import static org.junit.Assert.assertFalse;
97
alshabib0ed6a202014-10-19 12:42:57 -070098
Jonathan Hartb35540a2015-11-17 09:30:56 -080099public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -0700100
101 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
102 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700103 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
alshabib0ed6a202014-10-19 12:42:57 -0700104
105 private static Port pd1;
106 private static Port pd2;
107 private static Port pd3;
108 private static Port pd4;
109
Jonathan Hartb35540a2015-11-17 09:30:56 -0800110 private final LldpLinkProvider provider = new LldpLinkProvider();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700111 private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
112 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700113 private final TestPacketService packetService = new TestPacketService();
114 private final TestDeviceService deviceService = new TestDeviceService();
115 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600116 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700117
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800118 private CoreService coreService;
alshabib0ed6a202014-10-19 12:42:57 -0700119 private TestLinkProviderService providerService;
120
121 private PacketProcessor testProcessor;
122 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600123 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700124
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800125 private ApplicationId appId =
126 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800127
Naoki Shiota399a0b32015-11-15 20:36:13 -0600128 private TestSuppressionConfig cfg;
129
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800130 private Set<DeviceId> deviceBlacklist;
131
132 private Set<ConnectPoint> portBlacklist;
133
alshabib0ed6a202014-10-19 12:42:57 -0700134 @Before
135 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800136 deviceBlacklist = new HashSet<>();
137 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600138 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800139 coreService = createMock(CoreService.class);
140 expect(coreService.registerApplication(appId.name()))
141 .andReturn(appId).anyTimes();
142 replay(coreService);
143
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700144 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800145 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600146 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800147
alshabib0ed6a202014-10-19 12:42:57 -0700148 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700149 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800150 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700151 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700152 provider.masterService = masterService;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800153 provider.clusterMetadataService = new TestMetadataService();
Saurav Dasc313c402015-02-27 10:09:47 -0800154 provider.activate(null);
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()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800199 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700200 .build()));
201 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
222 // discovery helper for device is expected to be gone or stopped
223 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
224 if (linkDiscovery != null) {
225 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
226 }
227
228 }
229
230 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700231 public void portUp() {
232 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
233 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
234
235 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700236 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700237 }
238
239 @Test
240 public void portDown() {
241
242 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
243 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
244
alshabib0ed6a202014-10-19 12:42:57 -0700245 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700246 provider.discoverers.get(DID1).containsPort(1L));
247 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700248 }
249
250 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700251 public void portRemoved() {
252 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
253 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
254 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
255
256 assertTrue("Port is not gone.", vanishedPort(3L));
257 assertFalse("Port was not removed from discoverer",
258 provider.discoverers.get(DID1).containsPort(3L));
259 }
260
261 /**
262 * Checks that discovery on reconfigured switch are properly restarted.
263 */
264 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600265 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700266
267 /// When Device is configured with suppression:ON, Port also is same
268
269 // add device in stub DeviceService with suppression configured
270 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800271 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700272 .build()));
273 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
274
275 // non-suppressed port added to suppressed device
276 final long portno3 = 3L;
277 deviceService.putPorts(DID3, port(DID3, portno3, true));
278 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
279
280 // discovery on device is expected to be stopped
281 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
282 if (linkDiscovery != null) {
283 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
284 }
285
286 /// When Device is reconfigured without suppression:OFF,
287 /// Port should be included for discovery
288
289 // update device in stub DeviceService without suppression configured
290 deviceService.putDevice(device(DID3));
291 // update the Port in stub DeviceService. (Port has reference to Device)
292 deviceService.putPorts(DID3, port(DID3, portno3, true));
293 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
294
295 // discovery should come back on
296 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
297 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
298 }
299
300 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600301 * Checks that discovery on reconfigured switch are properly restarted.
302 */
303 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800304 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600305
306 /// When Device is configured without suppression:OFF,
307 /// Port should be included for discovery
308
309 // add device in stub DeviceService without suppression configured
310 deviceService.putDevice(device(DID3));
311 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
312
313 // non-suppressed port added to suppressed device
314 final long portno3 = 3L;
315 deviceService.putPorts(DID3, port(DID3, portno3, true));
316 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
317
318 // discovery should succeed
319 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
320 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
321
322 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800323 deviceBlacklist.add(DID3);
324 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
325 DID3,
326 LinkDiscoveryFromDevice.class));
327
Naoki Shiota399a0b32015-11-15 20:36:13 -0600328
329 /// When Device is reconfigured with suppression:ON, Port also is same
330
331 // update device in stub DeviceService with suppression configured
332 deviceService.putDevice(device(DID3));
333 // update the Port in stub DeviceService. (Port has reference to Device)
334 deviceService.putPorts(DID3, port(DID3, portno3, true));
335 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
336
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800337 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600338 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
339 if (linkDiscovery != null) {
340 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
341 }
342 }
343
344 /**
345 * Checks that discovery on reconfigured switch are properly restarted.
346 */
347 @Test
348 public void portSuppressedByDeviceTypeConfig() {
349
350 /// When Device is configured without suppression:OFF,
351 /// Port should be included for discovery
352
353 // add device in stub DeviceService without suppression configured
354 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
355 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
356
357 // non-suppressed port added to suppressed device
358 final long portno3 = 3L;
359 deviceService.putPorts(DID1, port(DID1, portno3, true));
360 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
361
362 // add device in stub DeviceService with suppression configured
363 deviceService.putDevice(device(DID2, Device.Type.ROADM));
364 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
365
366 // non-suppressed port added to suppressed device
367 final long portno4 = 4L;
368 deviceService.putPorts(DID2, port(DID2, portno4, true));
369 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
370
371 // discovery should succeed for this device
372 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
373 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
374
375 // discovery on device is expected to be stopped for this device
376 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
377 if (linkDiscovery != null) {
378 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
379 }
380 }
381
382 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700383 * Checks that discovery on reconfigured port are properly restarted.
384 */
385 @Test
386 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600387
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700388 // add device in stub DeviceService without suppression configured
389 deviceService.putDevice(device(DID3));
390 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
391
392 // suppressed port added to non-suppressed device
393 final long portno3 = 3L;
394 final Port port3 = port(DID3, portno3, true,
395 DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800396 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700397 .build());
398 deviceService.putPorts(DID3, port3);
399 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
400
401 // discovery helper should be there turned on
402 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
403 assertFalse("Discoverer should not contain the port there",
404 provider.discoverers.get(DID3).containsPort(portno3));
405 }
406
407 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800408 public void portSuppressedByPortBlacklist() {
409
410 // add device in stub DeviceService without suppression configured
411 deviceService.putDevice(device(DID3));
412 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
413
414 final long portno3 = 3L;
415 final Port port3 = port(DID3, portno3, true);
416
417 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
418 portBlacklist.add(cpDid3no3);
419
420 // suppressed port added to non-suppressed device
421 deviceService.putPorts(DID3, port3);
422 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
423
424 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
425 cpDid3no3,
426 LinkDiscoveryFromPort.class));
427
428 // discovery helper should be there turned on
429 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
430 // but port is not a discovery target
431 assertFalse("Discoverer should not contain the port there",
432 provider.discoverers.get(DID3).containsPort(portno3));
433 }
434
435 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700436 public void portUnknown() {
437 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700438 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
439 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700440
441
alshabibdfc7afb2014-10-21 20:13:27 -0700442 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700443 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700444 }
445
446 @Test
447 public void unknownPktCtx() {
448
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700449 // Note: DID3 hasn't been added to TestDeviceService
450 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700451
452 testProcessor.process(pktCtx);
453 assertFalse("Context should still be free", pktCtx.isHandled());
454 }
455
456 @Test
457 public void knownPktCtx() {
458 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
459 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
460 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
461
462
463 testProcessor.process(pktCtx);
464
465 assertTrue("Link not detected", detectedLink(DID1, DID2));
466
467 }
468
469
470 @After
471 public void tearDown() {
472 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800473 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700474 provider.providerRegistry = null;
475 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800476 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700477 }
478
479 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
480 return new DeviceEvent(type, deviceService.getDevice(did));
481
482 }
483
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700484 private DefaultDevice device(DeviceId did) {
485 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
486 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
487 }
488
Naoki Shiota399a0b32015-11-15 20:36:13 -0600489 private DefaultDevice device(DeviceId did, Device.Type type) {
490 return new DefaultDevice(ProviderId.NONE, did, type,
491 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
492 }
493
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700494 private DefaultDevice device(DeviceId did, Annotations annotations) {
495 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
496 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
497 }
498
Saurav Dasc313c402015-02-27 10:09:47 -0800499 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700500 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
501 return new DeviceEvent(type, deviceService.getDevice(did),
502 deviceService.getPort(did, port));
503 }
504
505 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
506 return new DeviceEvent(type, deviceService.getDevice(did), port);
507 }
508
509 private Port port(DeviceId did, long port, boolean enabled) {
510 return new DefaultPort(deviceService.getDevice(did),
511 PortNumber.portNumber(port), enabled);
512 }
513
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700514 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
515 return new DefaultPort(deviceService.getDevice(did),
516 PortNumber.portNumber(port), enabled, annotations);
517 }
alshabib0ed6a202014-10-19 12:42:57 -0700518
519 private boolean vanishedDpid(DeviceId... dids) {
520 for (int i = 0; i < dids.length; i++) {
521 if (!providerService.vanishedDpid.contains(dids[i])) {
522 return false;
523 }
524 }
525 return true;
526 }
527
528 private boolean vanishedPort(Long... ports) {
529 for (int i = 0; i < ports.length; i++) {
530 if (!providerService.vanishedPort.contains(ports[i])) {
531 return false;
532 }
533 }
534 return true;
535 }
536
537 private boolean detectedLink(DeviceId src, DeviceId dst) {
538 for (DeviceId key : providerService.discoveredLinks.keySet()) {
539 if (key.equals(src)) {
540 return providerService.discoveredLinks.get(src).equals(dst);
541 }
542 }
543 return false;
544 }
545
Naoki Shiota399a0b32015-11-15 20:36:13 -0600546 @Test
547 public void addDeviceTypeRule() {
548 Device.Type deviceType1 = Device.Type.ROADM;
549 Device.Type deviceType2 = Device.Type.SWITCH;
550
551 Set<Device.Type> deviceTypes = new HashSet<>();
552 deviceTypes.add(deviceType1);
553
554 cfg.deviceTypes(deviceTypes);
555
556 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
557
558 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
559 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
560 }
561
562 @Test
563 public void updateDeviceTypeRule() {
564 Device.Type deviceType1 = Device.Type.ROADM;
565 Device.Type deviceType2 = Device.Type.SWITCH;
566 Set<Device.Type> deviceTypes = new HashSet<>();
567
568 deviceTypes.add(deviceType1);
569 cfg.deviceTypes(deviceTypes);
570
571 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
572
573 deviceTypes.add(deviceType2);
574 cfg.deviceTypes(deviceTypes);
575
576 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
577
578 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
579 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
580 }
581
582 @Test
583 public void addAnnotationRule() {
584 final String key1 = "key1", key2 = "key2";
585 final String value1 = "value1";
586
587 Map<String, String> annotation = new HashMap<>();
588 annotation.put(key1, value1);
589
590 cfg.annotation(annotation);
591
592 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
593
594 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
595 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
596 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
597 }
598
599 @Test
600 public void updateAnnotationRule() {
601 final String key1 = "key1", key2 = "key2";
602 final String value1 = "value1", value2 = "value2";
603 Map<String, String> annotation = new HashMap<>();
604
605 annotation.put(key1, value1);
606 cfg.annotation(annotation);
607
608 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
609
610 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
611 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
612 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
613
614 annotation.put(key2, value2);
615 cfg.annotation(annotation);
616
617 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
618
619 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
620 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
621 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
622 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
623 }
624
625 private void configEvent(NetworkConfigEvent.Type evType) {
626 configListener.event(new NetworkConfigEvent(evType,
627 appId,
628 SuppressionConfig.class));
629 }
630
631
alshabib0ed6a202014-10-19 12:42:57 -0700632 private class TestLinkRegistry implements LinkProviderRegistry {
633
634 @Override
635 public LinkProviderService register(LinkProvider provider) {
636 providerService = new TestLinkProviderService(provider);
637 return providerService;
638 }
639
640 @Override
641 public void unregister(LinkProvider provider) {
642 }
643
644 @Override
645 public Set<ProviderId> getProviders() {
646 return null;
647 }
648
649 }
650
651 private class TestLinkProviderService
652 extends AbstractProviderService<LinkProvider>
653 implements LinkProviderService {
654
655 List<DeviceId> vanishedDpid = Lists.newLinkedList();
656 List<Long> vanishedPort = Lists.newLinkedList();
657 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
658
659 protected TestLinkProviderService(LinkProvider provider) {
660 super(provider);
661 }
662
663 @Override
664 public void linkDetected(LinkDescription linkDescription) {
665 DeviceId sDid = linkDescription.src().deviceId();
666 DeviceId dDid = linkDescription.dst().deviceId();
667 discoveredLinks.put(sDid, dDid);
668 }
669
670 @Override
671 public void linkVanished(LinkDescription linkDescription) {
alshabib0ed6a202014-10-19 12:42:57 -0700672 }
673
674 @Override
675 public void linksVanished(ConnectPoint connectPoint) {
676 vanishedPort.add(connectPoint.port().toLong());
677
678 }
679
680 @Override
681 public void linksVanished(DeviceId deviceId) {
682 vanishedDpid.add(deviceId);
683 }
684
685
686 }
687
688
689
690 private class TestPacketContext implements PacketContext {
691
692 protected Device device;
693 protected boolean blocked = false;
694
695 public TestPacketContext(Device dev) {
696 device = dev;
697 }
698
699 @Override
700 public long time() {
701 return 0;
702 }
703
704 @Override
705 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800706 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
707 device.chassisId(),
708 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700709
710 Ethernet ethPacket = new Ethernet();
711 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
712 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
713 ethPacket.setPayload(lldp);
714 ethPacket.setPad(true);
715
alshabib0ed6a202014-10-19 12:42:57 -0700716 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
717
718 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
719
720 return new DefaultInboundPacket(cp, ethPacket,
721 ByteBuffer.wrap(ethPacket.serialize()));
722
723 }
724
725 @Override
726 public OutboundPacket outPacket() {
727 return null;
728 }
729
730 @Override
731 public TrafficTreatment.Builder treatmentBuilder() {
732 return null;
733 }
734
735 @Override
736 public void send() {
737
738 }
739
740 @Override
741 public boolean block() {
742 blocked = true;
743 return blocked;
744 }
745
746 @Override
747 public boolean isHandled() {
748 return blocked;
749 }
750
751 }
752
Thomas Vachuska27bee092015-06-23 19:03:10 -0700753 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700754 @Override
755 public void addProcessor(PacketProcessor processor, int priority) {
756 testProcessor = processor;
757 }
alshabib0ed6a202014-10-19 12:42:57 -0700758 }
759
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800760 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700761
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700762 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700763 private final ArrayListMultimap<DeviceId, Port> ports =
764 ArrayListMultimap.create();
alshabib0ed6a202014-10-19 12:42:57 -0700765 public TestDeviceService() {
766 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
767 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
768 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
769 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
770 devices.put(DID1, d1);
771 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700772 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
773 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
774 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
775 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
776
777 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
778 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700779 }
780
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700781 private void putDevice(Device device) {
782 DeviceId deviceId = device.id();
783 devices.put(deviceId, device);
784 }
785
786 private void putPorts(DeviceId did, Port...ports) {
787 this.ports.putAll(did, Lists.newArrayList(ports));
788 }
789
alshabib0ed6a202014-10-19 12:42:57 -0700790 @Override
791 public int getDeviceCount() {
792 return devices.values().size();
793 }
794
795 @Override
796 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700797 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700798 }
799
800 @Override
801 public Device getDevice(DeviceId deviceId) {
802 return devices.get(deviceId);
803 }
804
805 @Override
806 public MastershipRole getRole(DeviceId deviceId) {
807 return MastershipRole.MASTER;
808 }
809
810 @Override
811 public List<Port> getPorts(DeviceId deviceId) {
812 return ports.get(deviceId);
813 }
814
815 @Override
816 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
817 for (Port p : ports.get(deviceId)) {
818 if (p.number().equals(portNumber)) {
819 return p;
820 }
821 }
822 return null;
823 }
824
825 @Override
826 public boolean isAvailable(DeviceId deviceId) {
827 return true;
828 }
829
830 @Override
831 public void addListener(DeviceListener listener) {
832 deviceListener = listener;
833
834 }
835
836 @Override
837 public void removeListener(DeviceListener listener) {
838
839 }
840 }
841
842 private final class TestMasterShipService implements MastershipService {
843
844 @Override
845 public MastershipRole getLocalRole(DeviceId deviceId) {
846 return MastershipRole.MASTER;
847 }
848
849 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700850 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
851 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700852 }
853
854 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700855 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
856 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700857 }
858
859 @Override
860 public NodeId getMasterFor(DeviceId deviceId) {
861 return null;
862 }
863
864 @Override
865 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
866 return null;
867 }
868
869 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700870 public void addListener(MastershipListener listener) {
871
872 }
873
874 @Override
875 public void removeListener(MastershipListener listener) {
876
877 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700878
879 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700880 public RoleInfo getNodesFor(DeviceId deviceId) {
881 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700882 }
alshabib0ed6a202014-10-19 12:42:57 -0700883 }
884
885
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700886 private class TestLinkService extends LinkServiceAdapter {
887 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600888
889 private final class TestNetworkConfigRegistry
890 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800891 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600892 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800893 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
894 if (configClass == SuppressionConfig.class) {
895 return (C) cfg;
896 } else if (configClass == LinkDiscoveryFromDevice.class) {
897 return (C) new LinkDiscoveryFromDevice() {
898 @Override
899 public boolean enabled() {
900 return !deviceBlacklist.contains(subj);
901 }
902 };
903 } else if (configClass == LinkDiscoveryFromPort.class) {
904 return (C) new LinkDiscoveryFromPort() {
905 @Override
906 public boolean enabled() {
907 return !portBlacklist.contains(subj);
908 }
909 };
910 } else {
911 return null;
912 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600913 }
914
915 @Override
916 public void addListener(NetworkConfigListener listener) {
917 configListener = listener;
918 }
919 }
920
921 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600922 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
923 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
924
925 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600926 public Set<Device.Type> deviceTypes() {
927 return ImmutableSet.copyOf(deviceTypes);
928 }
929
930 @Override
931 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
932 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
933 return this;
934 }
935
936 @Override
937 public Map<String, String> annotation() {
938 return ImmutableMap.copyOf(annotation);
939 }
940
941 @Override
942 public SuppressionConfig annotation(Map<String, String> annotation) {
943 this.annotation = ImmutableMap.copyOf(annotation);
944 return this;
945 }
946 }
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800947
948 private final class TestMetadataService implements ClusterMetadataService {
949 @Override
950 public ClusterMetadata getClusterMetadata() {
951 final NodeId nid = new NodeId("test-node");
952 final IpAddress addr = IpAddress.valueOf(0);
953 final Partition p = new Partition("test-pt", Sets.newHashSet(nid));
954 return ClusterMetadata.builder()
955 .withName("test-cluster")
956 .withControllerNodes(Sets.newHashSet(new DefaultControllerNode(nid, addr)))
957 .withPartitions(Sets.newHashSet(p)).build();
958 }
959
960 @Override
961 public void setClusterMetadata(ClusterMetadata metadata) {
962 }
963
964 @Override
965 public ControllerNode getLocalNode() {
966 return null;
967 }
968 }
alshabib0ed6a202014-10-19 12:42:57 -0700969}