blob: c6f0b3d0105e9660b36ac6a222b844dc3b50e702 [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;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080035import org.onosproject.cluster.ClusterMetadataEventListener;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080036import org.onosproject.cluster.ClusterMetadataService;
37import org.onosproject.cluster.ControllerNode;
38import org.onosproject.cluster.DefaultControllerNode;
Madan Jampani8474fdd2016-01-19 09:56:28 -080039import org.onosproject.cluster.DefaultPartition;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.cluster.NodeId;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -080041import org.onosproject.cluster.Partition;
Madan Jampaniab7e7cd2016-01-14 14:02:32 -080042import org.onosproject.cluster.PartitionId;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.cluster.RoleInfo;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080044import org.onosproject.core.ApplicationId;
45import org.onosproject.core.CoreService;
46import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.mastership.MastershipListener;
48import org.onosproject.mastership.MastershipService;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070049import org.onosproject.net.Annotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import org.onosproject.net.ConnectPoint;
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -070051import org.onosproject.net.DefaultAnnotations;
Brian O'Connorabafb502014-12-02 22:26:20 -080052import org.onosproject.net.DefaultDevice;
53import org.onosproject.net.DefaultPort;
54import org.onosproject.net.Device;
55import org.onosproject.net.DeviceId;
56import org.onosproject.net.MastershipRole;
57import org.onosproject.net.Port;
58import org.onosproject.net.PortNumber;
Naoki Shiota399a0b32015-11-15 20:36:13 -060059import org.onosproject.net.config.Config;
Naoki Shiota399a0b32015-11-15 20:36:13 -060060import org.onosproject.net.config.NetworkConfigEvent;
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -080061import org.onosproject.net.config.NetworkConfigEvent.Type;
Naoki Shiota399a0b32015-11-15 20:36:13 -060062import org.onosproject.net.config.NetworkConfigListener;
63import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080064import org.onosproject.net.device.DeviceEvent;
65import org.onosproject.net.device.DeviceListener;
66import org.onosproject.net.device.DeviceServiceAdapter;
67import org.onosproject.net.flow.TrafficTreatment;
68import org.onosproject.net.link.LinkDescription;
69import org.onosproject.net.link.LinkProvider;
70import org.onosproject.net.link.LinkProviderRegistry;
71import org.onosproject.net.link.LinkProviderService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -070072import org.onosproject.net.link.LinkServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080073import org.onosproject.net.packet.DefaultInboundPacket;
74import org.onosproject.net.packet.InboundPacket;
75import org.onosproject.net.packet.OutboundPacket;
76import org.onosproject.net.packet.PacketContext;
77import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070078import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080079import org.onosproject.net.provider.AbstractProviderService;
80import org.onosproject.net.provider.ProviderId;
alshabib0ed6a202014-10-19 12:42:57 -070081
Thomas Vachuska27bee092015-06-23 19:03:10 -070082import java.nio.ByteBuffer;
Thomas Vachuska27bee092015-06-23 19:03:10 -070083import java.util.HashMap;
Naoki Shiota399a0b32015-11-15 20:36:13 -060084import java.util.HashSet;
Thomas Vachuska27bee092015-06-23 19:03:10 -070085import java.util.List;
86import java.util.Map;
87import java.util.Set;
Naoki Shiota399a0b32015-11-15 20:36:13 -060088import java.util.Collections;
Thomas Vachuska27bee092015-06-23 19:03:10 -070089import java.util.concurrent.CompletableFuture;
90
Naoki Shiota399a0b32015-11-15 20:36:13 -060091import static org.easymock.EasyMock.createMock;
92import static org.easymock.EasyMock.expect;
93import static org.easymock.EasyMock.replay;
Naoki Shiota399a0b32015-11-15 20:36:13 -060094import static org.junit.Assert.assertNull;
95import static org.junit.Assert.assertNotNull;
96import static org.junit.Assert.assertEquals;
97import static org.junit.Assert.assertTrue;
98import static org.onosproject.provider.lldp.impl.LldpLinkProvider.DEFAULT_RULES;
99import static org.junit.Assert.assertFalse;
100
alshabib0ed6a202014-10-19 12:42:57 -0700101
Jonathan Hartb35540a2015-11-17 09:30:56 -0800102public class LldpLinkProviderTest {
alshabib0ed6a202014-10-19 12:42:57 -0700103
104 private static final DeviceId DID1 = DeviceId.deviceId("of:0000000000000001");
105 private static final DeviceId DID2 = DeviceId.deviceId("of:0000000000000002");
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700106 private static final DeviceId DID3 = DeviceId.deviceId("of:0000000000000003");
alshabib0ed6a202014-10-19 12:42:57 -0700107
108 private static Port pd1;
109 private static Port pd2;
110 private static Port pd3;
111 private static Port pd4;
112
Jonathan Hartb35540a2015-11-17 09:30:56 -0800113 private final LldpLinkProvider provider = new LldpLinkProvider();
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700114 private final TestLinkRegistry linkRegistry = new TestLinkRegistry();
115 private final TestLinkService linkService = new TestLinkService();
alshabib0ed6a202014-10-19 12:42:57 -0700116 private final TestPacketService packetService = new TestPacketService();
117 private final TestDeviceService deviceService = new TestDeviceService();
118 private final TestMasterShipService masterService = new TestMasterShipService();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600119 private final TestNetworkConfigRegistry configRegistry = new TestNetworkConfigRegistry();
alshabib0ed6a202014-10-19 12:42:57 -0700120
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800121 private CoreService coreService;
alshabib0ed6a202014-10-19 12:42:57 -0700122 private TestLinkProviderService providerService;
123
124 private PacketProcessor testProcessor;
125 private DeviceListener deviceListener;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600126 private NetworkConfigListener configListener;
alshabib0ed6a202014-10-19 12:42:57 -0700127
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800128 private ApplicationId appId =
129 new DefaultApplicationId(100, "org.onosproject.provider.lldp");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800130
Naoki Shiota399a0b32015-11-15 20:36:13 -0600131 private TestSuppressionConfig cfg;
132
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800133 private Set<DeviceId> deviceBlacklist;
134
135 private Set<ConnectPoint> portBlacklist;
136
alshabib0ed6a202014-10-19 12:42:57 -0700137 @Before
138 public void setUp() {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800139 deviceBlacklist = new HashSet<>();
140 portBlacklist = new HashSet<>();
Naoki Shiota399a0b32015-11-15 20:36:13 -0600141 cfg = new TestSuppressionConfig();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800142 coreService = createMock(CoreService.class);
143 expect(coreService.registerApplication(appId.name()))
144 .andReturn(appId).anyTimes();
145 replay(coreService);
146
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700147 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800148 provider.coreService = coreService;
Naoki Shiota399a0b32015-11-15 20:36:13 -0600149 provider.cfgRegistry = configRegistry;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800150
alshabib0ed6a202014-10-19 12:42:57 -0700151 provider.deviceService = deviceService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700152 provider.linkService = linkService;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800153 provider.packetService = packetService;
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700154 provider.providerRegistry = linkRegistry;
alshabib0ed6a202014-10-19 12:42:57 -0700155 provider.masterService = masterService;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800156 provider.clusterMetadataService = new TestMetadataService();
Saurav Dasc313c402015-02-27 10:09:47 -0800157 provider.activate(null);
alshabib0ed6a202014-10-19 12:42:57 -0700158 }
159
160 @Test
161 public void basics() {
162 assertNotNull("registration expected", providerService);
163 assertEquals("incorrect provider", provider, providerService.provider());
164 }
165
166 @Test
167 public void switchAdd() {
168 DeviceEvent de = deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1);
169 deviceListener.event(de);
170
171 assertFalse("Device not added", provider.discoverers.isEmpty());
172 }
173
174 @Test
175 public void switchRemove() {
176 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
177 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_REMOVED, DID1));
178
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700179 final LinkDiscovery linkDiscovery = provider.discoverers.get(DID1);
180 if (linkDiscovery != null) {
181 // If LinkDiscovery helper is there after DEVICE_REMOVED,
182 // it should be stopped
183 assertTrue("Discoverer is not stopped", linkDiscovery.isStopped());
184 }
alshabib0ed6a202014-10-19 12:42:57 -0700185 assertTrue("Device is not gone.", vanishedDpid(DID1));
186 }
187
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700188 /**
189 * Checks that links on a reconfigured switch are properly removed.
190 */
191 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800192 public void switchSuppressedByAnnotation() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600193
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700194 // add device to stub DeviceService
195 deviceService.putDevice(device(DID3));
196 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
197
198 assertFalse("Device not added", provider.discoverers.isEmpty());
199
200 // update device in stub DeviceService with suppression config
201 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800202 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700203 .build()));
204 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
205
Naoki Shiota399a0b32015-11-15 20:36:13 -0600206 // discovery on device is expected to be gone or stopped
207 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
208 if (linkDiscovery != null) {
209 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
210 }
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700211 }
212
alshabib0ed6a202014-10-19 12:42:57 -0700213 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800214 public void switchSuppressByBlacklist() {
215 // add device in stub DeviceService
216 deviceService.putDevice(device(DID3));
217 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
218
219 // add deviveId to device blacklist
220 deviceBlacklist.add(DID3);
221 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
222 DID3,
223 LinkDiscoveryFromDevice.class));
224
225 // discovery helper for device is expected to be gone or stopped
226 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
227 if (linkDiscovery != null) {
228 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
229 }
230
231 }
232
233 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700234 public void portUp() {
235 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
236 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
237
238 assertTrue("Port not added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700239 provider.discoverers.get(DID1).containsPort(3L));
alshabib0ed6a202014-10-19 12:42:57 -0700240 }
241
242 @Test
243 public void portDown() {
244
245 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
246 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 1, false)));
247
alshabib0ed6a202014-10-19 12:42:57 -0700248 assertFalse("Port added to discoverer",
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700249 provider.discoverers.get(DID1).containsPort(1L));
250 assertTrue("Port is not gone.", vanishedPort(1L));
alshabib0ed6a202014-10-19 12:42:57 -0700251 }
252
253 @Test
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700254 public void portRemoved() {
255 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
256 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, 3, true)));
257 deviceListener.event(portEvent(DeviceEvent.Type.PORT_REMOVED, DID1, port(DID1, 3, true)));
258
259 assertTrue("Port is not gone.", vanishedPort(3L));
260 assertFalse("Port was not removed from discoverer",
261 provider.discoverers.get(DID1).containsPort(3L));
262 }
263
264 /**
265 * Checks that discovery on reconfigured switch are properly restarted.
266 */
267 @Test
Naoki Shiota399a0b32015-11-15 20:36:13 -0600268 public void portSuppressedByDeviceAnnotationConfig() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700269
270 /// When Device is configured with suppression:ON, Port also is same
271
272 // add device in stub DeviceService with suppression configured
273 deviceService.putDevice(device(DID3, DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800274 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700275 .build()));
276 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
277
278 // non-suppressed port added to suppressed device
279 final long portno3 = 3L;
280 deviceService.putPorts(DID3, port(DID3, portno3, true));
281 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
282
283 // discovery on device is expected to be stopped
284 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
285 if (linkDiscovery != null) {
286 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
287 }
288
289 /// When Device is reconfigured without suppression:OFF,
290 /// Port should be included for discovery
291
292 // update device in stub DeviceService without suppression configured
293 deviceService.putDevice(device(DID3));
294 // update the Port in stub DeviceService. (Port has reference to Device)
295 deviceService.putPorts(DID3, port(DID3, portno3, true));
296 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
297
298 // discovery should come back on
299 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
300 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
301 }
302
303 /**
Naoki Shiota399a0b32015-11-15 20:36:13 -0600304 * Checks that discovery on reconfigured switch are properly restarted.
305 */
306 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800307 public void portSuppressedByParentDeviceIdBlacklist() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600308
309 /// When Device is configured without suppression:OFF,
310 /// Port should be included for discovery
311
312 // add device in stub DeviceService without suppression configured
313 deviceService.putDevice(device(DID3));
314 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
315
316 // non-suppressed port added to suppressed device
317 final long portno3 = 3L;
318 deviceService.putPorts(DID3, port(DID3, portno3, true));
319 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, portno3, true)));
320
321 // discovery should succeed
322 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
323 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID3).containsPort(portno3));
324
325 // add suppression rule for "deviceId: "of:0000000000000003""
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800326 deviceBlacklist.add(DID3);
327 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
328 DID3,
329 LinkDiscoveryFromDevice.class));
330
Naoki Shiota399a0b32015-11-15 20:36:13 -0600331
332 /// When Device is reconfigured with suppression:ON, Port also is same
333
334 // update device in stub DeviceService with suppression configured
335 deviceService.putDevice(device(DID3));
336 // update the Port in stub DeviceService. (Port has reference to Device)
337 deviceService.putPorts(DID3, port(DID3, portno3, true));
338 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_UPDATED, DID3));
339
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800340 // discovery helper for device is expected to be gone or stopped
Naoki Shiota399a0b32015-11-15 20:36:13 -0600341 LinkDiscovery linkDiscovery = provider.discoverers.get(DID3);
342 if (linkDiscovery != null) {
343 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
344 }
345 }
346
347 /**
348 * Checks that discovery on reconfigured switch are properly restarted.
349 */
350 @Test
351 public void portSuppressedByDeviceTypeConfig() {
352
353 /// When Device is configured without suppression:OFF,
354 /// Port should be included for discovery
355
356 // add device in stub DeviceService without suppression configured
357 deviceService.putDevice(device(DID1, Device.Type.SWITCH));
358 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
359
360 // non-suppressed port added to suppressed device
361 final long portno3 = 3L;
362 deviceService.putPorts(DID1, port(DID1, portno3, true));
363 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID1, port(DID1, portno3, true)));
364
365 // add device in stub DeviceService with suppression configured
366 deviceService.putDevice(device(DID2, Device.Type.ROADM));
367 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
368
369 // non-suppressed port added to suppressed device
370 final long portno4 = 4L;
371 deviceService.putPorts(DID2, port(DID2, portno4, true));
372 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID2, port(DID2, portno4, true)));
373
374 // discovery should succeed for this device
375 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID1).isStopped());
376 assertTrue("Discoverer should contain the port there", provider.discoverers.get(DID1).containsPort(portno3));
377
378 // discovery on device is expected to be stopped for this device
379 LinkDiscovery linkDiscovery = provider.discoverers.get(DID2);
380 if (linkDiscovery != null) {
381 assertTrue("Discovery expected to be stopped", linkDiscovery.isStopped());
382 }
383 }
384
385 /**
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700386 * Checks that discovery on reconfigured port are properly restarted.
387 */
388 @Test
389 public void portSuppressedByPortConfig() {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600390
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700391 // add device in stub DeviceService without suppression configured
392 deviceService.putDevice(device(DID3));
393 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
394
395 // suppressed port added to non-suppressed device
396 final long portno3 = 3L;
397 final Port port3 = port(DID3, portno3, true,
398 DefaultAnnotations.builder()
Jonathan Hartb35540a2015-11-17 09:30:56 -0800399 .set(LldpLinkProvider.NO_LLDP, "true")
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700400 .build());
401 deviceService.putPorts(DID3, port3);
402 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
403
404 // discovery helper should be there turned on
405 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
406 assertFalse("Discoverer should not contain the port there",
407 provider.discoverers.get(DID3).containsPort(portno3));
408 }
409
410 @Test
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800411 public void portSuppressedByPortBlacklist() {
412
413 // add device in stub DeviceService without suppression configured
414 deviceService.putDevice(device(DID3));
415 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID3));
416
417 final long portno3 = 3L;
418 final Port port3 = port(DID3, portno3, true);
419
420 final ConnectPoint cpDid3no3 = new ConnectPoint(DID3, PortNumber.portNumber(portno3));
421 portBlacklist.add(cpDid3no3);
422
423 // suppressed port added to non-suppressed device
424 deviceService.putPorts(DID3, port3);
425 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port3));
426
427 configListener.event(new NetworkConfigEvent(Type.CONFIG_ADDED,
428 cpDid3no3,
429 LinkDiscoveryFromPort.class));
430
431 // discovery helper should be there turned on
432 assertFalse("Discoverer is expected to start", provider.discoverers.get(DID3).isStopped());
433 // but port is not a discovery target
434 assertFalse("Discoverer should not contain the port there",
435 provider.discoverers.get(DID3).containsPort(portno3));
436 }
437
438 @Test
alshabib0ed6a202014-10-19 12:42:57 -0700439 public void portUnknown() {
440 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700441 // Note: DID3 hasn't been added to TestDeviceService, but only port is added
442 deviceListener.event(portEvent(DeviceEvent.Type.PORT_ADDED, DID3, port(DID3, 1, false)));
alshabib0ed6a202014-10-19 12:42:57 -0700443
444
alshabibdfc7afb2014-10-21 20:13:27 -0700445 assertNull("DeviceId exists",
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700446 provider.discoverers.get(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700447 }
448
449 @Test
450 public void unknownPktCtx() {
451
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700452 // Note: DID3 hasn't been added to TestDeviceService
453 PacketContext pktCtx = new TestPacketContext(device(DID3));
alshabib0ed6a202014-10-19 12:42:57 -0700454
455 testProcessor.process(pktCtx);
456 assertFalse("Context should still be free", pktCtx.isHandled());
457 }
458
459 @Test
460 public void knownPktCtx() {
461 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID1));
462 deviceListener.event(deviceEvent(DeviceEvent.Type.DEVICE_ADDED, DID2));
463 PacketContext pktCtx = new TestPacketContext(deviceService.getDevice(DID2));
464
465
466 testProcessor.process(pktCtx);
467
468 assertTrue("Link not detected", detectedLink(DID1, DID2));
469
470 }
471
472
473 @After
474 public void tearDown() {
475 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800476 provider.coreService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700477 provider.providerRegistry = null;
478 provider.deviceService = null;
Marc De Leenheer8b3e80b2015-03-06 14:27:03 -0800479 provider.packetService = null;
alshabib0ed6a202014-10-19 12:42:57 -0700480 }
481
482 private DeviceEvent deviceEvent(DeviceEvent.Type type, DeviceId did) {
483 return new DeviceEvent(type, deviceService.getDevice(did));
484
485 }
486
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700487 private DefaultDevice device(DeviceId did) {
488 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
489 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
490 }
491
Naoki Shiota399a0b32015-11-15 20:36:13 -0600492 private DefaultDevice device(DeviceId did, Device.Type type) {
493 return new DefaultDevice(ProviderId.NONE, did, type,
494 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
495 }
496
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700497 private DefaultDevice device(DeviceId did, Annotations annotations) {
498 return new DefaultDevice(ProviderId.NONE, did, Device.Type.SWITCH,
499 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId(), annotations);
500 }
501
Saurav Dasc313c402015-02-27 10:09:47 -0800502 @SuppressWarnings(value = { "unused" })
alshabib0ed6a202014-10-19 12:42:57 -0700503 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
504 return new DeviceEvent(type, deviceService.getDevice(did),
505 deviceService.getPort(did, port));
506 }
507
508 private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, Port port) {
509 return new DeviceEvent(type, deviceService.getDevice(did), port);
510 }
511
512 private Port port(DeviceId did, long port, boolean enabled) {
513 return new DefaultPort(deviceService.getDevice(did),
514 PortNumber.portNumber(port), enabled);
515 }
516
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700517 private Port port(DeviceId did, long port, boolean enabled, Annotations annotations) {
518 return new DefaultPort(deviceService.getDevice(did),
519 PortNumber.portNumber(port), enabled, annotations);
520 }
alshabib0ed6a202014-10-19 12:42:57 -0700521
522 private boolean vanishedDpid(DeviceId... dids) {
523 for (int i = 0; i < dids.length; i++) {
524 if (!providerService.vanishedDpid.contains(dids[i])) {
525 return false;
526 }
527 }
528 return true;
529 }
530
531 private boolean vanishedPort(Long... ports) {
532 for (int i = 0; i < ports.length; i++) {
533 if (!providerService.vanishedPort.contains(ports[i])) {
534 return false;
535 }
536 }
537 return true;
538 }
539
540 private boolean detectedLink(DeviceId src, DeviceId dst) {
541 for (DeviceId key : providerService.discoveredLinks.keySet()) {
542 if (key.equals(src)) {
543 return providerService.discoveredLinks.get(src).equals(dst);
544 }
545 }
546 return false;
547 }
548
Naoki Shiota399a0b32015-11-15 20:36:13 -0600549 @Test
550 public void addDeviceTypeRule() {
551 Device.Type deviceType1 = Device.Type.ROADM;
552 Device.Type deviceType2 = Device.Type.SWITCH;
553
554 Set<Device.Type> deviceTypes = new HashSet<>();
555 deviceTypes.add(deviceType1);
556
557 cfg.deviceTypes(deviceTypes);
558
559 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
560
561 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
562 assertFalse(provider.rules().getSuppressedDeviceType().contains(deviceType2));
563 }
564
565 @Test
566 public void updateDeviceTypeRule() {
567 Device.Type deviceType1 = Device.Type.ROADM;
568 Device.Type deviceType2 = Device.Type.SWITCH;
569 Set<Device.Type> deviceTypes = new HashSet<>();
570
571 deviceTypes.add(deviceType1);
572 cfg.deviceTypes(deviceTypes);
573
574 configEvent(NetworkConfigEvent.Type.CONFIG_ADDED);
575
576 deviceTypes.add(deviceType2);
577 cfg.deviceTypes(deviceTypes);
578
579 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
580
581 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType1));
582 assertTrue(provider.rules().getSuppressedDeviceType().contains(deviceType2));
583 }
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
597 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
598 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
599 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
600 }
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
613 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
614 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
615 assertFalse(provider.rules().getSuppressedAnnotation().containsKey(key2));
616
617 annotation.put(key2, value2);
618 cfg.annotation(annotation);
619
620 configEvent(NetworkConfigEvent.Type.CONFIG_UPDATED);
621
622 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key1));
623 assertEquals(value1, provider.rules().getSuppressedAnnotation().get(key1));
624 assertTrue(provider.rules().getSuppressedAnnotation().containsKey(key2));
625 assertEquals(value2, provider.rules().getSuppressedAnnotation().get(key2));
626 }
627
628 private void configEvent(NetworkConfigEvent.Type evType) {
629 configListener.event(new NetworkConfigEvent(evType,
630 appId,
631 SuppressionConfig.class));
632 }
633
634
alshabib0ed6a202014-10-19 12:42:57 -0700635 private class TestLinkRegistry implements LinkProviderRegistry {
636
637 @Override
638 public LinkProviderService register(LinkProvider provider) {
639 providerService = new TestLinkProviderService(provider);
640 return providerService;
641 }
642
643 @Override
644 public void unregister(LinkProvider provider) {
645 }
646
647 @Override
648 public Set<ProviderId> getProviders() {
649 return null;
650 }
651
652 }
653
654 private class TestLinkProviderService
655 extends AbstractProviderService<LinkProvider>
656 implements LinkProviderService {
657
658 List<DeviceId> vanishedDpid = Lists.newLinkedList();
659 List<Long> vanishedPort = Lists.newLinkedList();
660 Map<DeviceId, DeviceId> discoveredLinks = Maps.newHashMap();
661
662 protected TestLinkProviderService(LinkProvider provider) {
663 super(provider);
664 }
665
666 @Override
667 public void linkDetected(LinkDescription linkDescription) {
668 DeviceId sDid = linkDescription.src().deviceId();
669 DeviceId dDid = linkDescription.dst().deviceId();
670 discoveredLinks.put(sDid, dDid);
671 }
672
673 @Override
674 public void linkVanished(LinkDescription linkDescription) {
alshabib0ed6a202014-10-19 12:42:57 -0700675 }
676
677 @Override
678 public void linksVanished(ConnectPoint connectPoint) {
679 vanishedPort.add(connectPoint.port().toLong());
680
681 }
682
683 @Override
684 public void linksVanished(DeviceId deviceId) {
685 vanishedDpid.add(deviceId);
686 }
687
688
689 }
690
691
692
693 private class TestPacketContext implements PacketContext {
694
695 protected Device device;
696 protected boolean blocked = false;
697
698 public TestPacketContext(Device dev) {
699 device = dev;
700 }
701
702 @Override
703 public long time() {
704 return 0;
705 }
706
707 @Override
708 public InboundPacket inPacket() {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800709 ONOSLLDP lldp = ONOSLLDP.onosLLDP(deviceService.getDevice(DID1).id().toString(),
710 device.chassisId(),
711 (int) pd1.number().toLong());
alshabib0ed6a202014-10-19 12:42:57 -0700712
713 Ethernet ethPacket = new Ethernet();
714 ethPacket.setEtherType(Ethernet.TYPE_LLDP);
715 ethPacket.setDestinationMACAddress(ONOSLLDP.LLDP_NICIRA);
716 ethPacket.setPayload(lldp);
717 ethPacket.setPad(true);
718
alshabib0ed6a202014-10-19 12:42:57 -0700719 ethPacket.setSourceMACAddress("DE:AD:BE:EF:BA:11");
720
721 ConnectPoint cp = new ConnectPoint(device.id(), pd3.number());
722
723 return new DefaultInboundPacket(cp, ethPacket,
724 ByteBuffer.wrap(ethPacket.serialize()));
725
726 }
727
728 @Override
729 public OutboundPacket outPacket() {
730 return null;
731 }
732
733 @Override
734 public TrafficTreatment.Builder treatmentBuilder() {
735 return null;
736 }
737
738 @Override
739 public void send() {
740
741 }
742
743 @Override
744 public boolean block() {
745 blocked = true;
746 return blocked;
747 }
748
749 @Override
750 public boolean isHandled() {
751 return blocked;
752 }
753
754 }
755
Thomas Vachuska27bee092015-06-23 19:03:10 -0700756 private class TestPacketService extends PacketServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700757 @Override
758 public void addProcessor(PacketProcessor processor, int priority) {
759 testProcessor = processor;
760 }
alshabib0ed6a202014-10-19 12:42:57 -0700761 }
762
Yuta HIGUCHIf1f2ac02014-11-26 14:02:22 -0800763 private class TestDeviceService extends DeviceServiceAdapter {
alshabib0ed6a202014-10-19 12:42:57 -0700764
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700765 private final Map<DeviceId, Device> devices = new HashMap<>();
alshabib0ed6a202014-10-19 12:42:57 -0700766 private final ArrayListMultimap<DeviceId, Port> ports =
767 ArrayListMultimap.create();
alshabib0ed6a202014-10-19 12:42:57 -0700768 public TestDeviceService() {
769 Device d1 = new DefaultDevice(ProviderId.NONE, DID1, Device.Type.SWITCH,
770 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
771 Device d2 = new DefaultDevice(ProviderId.NONE, DID2, Device.Type.SWITCH,
772 "TESTMF", "TESTHW", "TESTSW", "TESTSN", new ChassisId());
773 devices.put(DID1, d1);
774 devices.put(DID2, d2);
alshabib0ed6a202014-10-19 12:42:57 -0700775 pd1 = new DefaultPort(d1, PortNumber.portNumber(1), true);
776 pd2 = new DefaultPort(d1, PortNumber.portNumber(2), true);
777 pd3 = new DefaultPort(d2, PortNumber.portNumber(1), true);
778 pd4 = new DefaultPort(d2, PortNumber.portNumber(2), true);
779
780 ports.putAll(DID1, Lists.newArrayList(pd1, pd2));
781 ports.putAll(DID2, Lists.newArrayList(pd3, pd4));
alshabib0ed6a202014-10-19 12:42:57 -0700782 }
783
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700784 private void putDevice(Device device) {
785 DeviceId deviceId = device.id();
786 devices.put(deviceId, device);
787 }
788
789 private void putPorts(DeviceId did, Port...ports) {
790 this.ports.putAll(did, Lists.newArrayList(ports));
791 }
792
alshabib0ed6a202014-10-19 12:42:57 -0700793 @Override
794 public int getDeviceCount() {
795 return devices.values().size();
796 }
797
798 @Override
799 public Iterable<Device> getDevices() {
HIGUCHI Yuta9a9edf82015-10-21 11:23:20 -0700800 return ImmutableList.copyOf(devices.values());
alshabib0ed6a202014-10-19 12:42:57 -0700801 }
802
803 @Override
804 public Device getDevice(DeviceId deviceId) {
805 return devices.get(deviceId);
806 }
807
808 @Override
809 public MastershipRole getRole(DeviceId deviceId) {
810 return MastershipRole.MASTER;
811 }
812
813 @Override
814 public List<Port> getPorts(DeviceId deviceId) {
815 return ports.get(deviceId);
816 }
817
818 @Override
819 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
820 for (Port p : ports.get(deviceId)) {
821 if (p.number().equals(portNumber)) {
822 return p;
823 }
824 }
825 return null;
826 }
827
828 @Override
829 public boolean isAvailable(DeviceId deviceId) {
830 return true;
831 }
832
833 @Override
834 public void addListener(DeviceListener listener) {
835 deviceListener = listener;
836
837 }
838
839 @Override
840 public void removeListener(DeviceListener listener) {
841
842 }
843 }
844
845 private final class TestMasterShipService implements MastershipService {
846
847 @Override
848 public MastershipRole getLocalRole(DeviceId deviceId) {
849 return MastershipRole.MASTER;
850 }
851
852 @Override
Madan Jampanide003d92015-05-11 17:14:20 -0700853 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
854 return CompletableFuture.completedFuture(null);
alshabib0ed6a202014-10-19 12:42:57 -0700855 }
856
857 @Override
Madan Jampanic6e574f2015-05-29 13:41:52 -0700858 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
859 return null;
alshabib0ed6a202014-10-19 12:42:57 -0700860 }
861
862 @Override
863 public NodeId getMasterFor(DeviceId deviceId) {
864 return null;
865 }
866
867 @Override
868 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
869 return null;
870 }
871
872 @Override
alshabib0ed6a202014-10-19 12:42:57 -0700873 public void addListener(MastershipListener listener) {
874
875 }
876
877 @Override
878 public void removeListener(MastershipListener listener) {
879
880 }
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700881
882 @Override
Ayaka Koshibeabedb092014-10-20 17:01:31 -0700883 public RoleInfo getNodesFor(DeviceId deviceId) {
884 return new RoleInfo(new NodeId("foo"), Collections.<NodeId>emptyList());
Yuta HIGUCHI376d7502014-10-19 15:57:52 -0700885 }
alshabib0ed6a202014-10-19 12:42:57 -0700886 }
887
888
Thomas Vachuskae4ebac92015-09-10 11:39:05 -0700889 private class TestLinkService extends LinkServiceAdapter {
890 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600891
892 private final class TestNetworkConfigRegistry
893 extends NetworkConfigRegistryAdapter {
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800894 @SuppressWarnings("unchecked")
Naoki Shiota399a0b32015-11-15 20:36:13 -0600895 @Override
HIGUCHI Yutad9fe3a32015-11-24 18:52:25 -0800896 public <S, C extends Config<S>> C getConfig(S subj, Class<C> configClass) {
897 if (configClass == SuppressionConfig.class) {
898 return (C) cfg;
899 } else if (configClass == LinkDiscoveryFromDevice.class) {
900 return (C) new LinkDiscoveryFromDevice() {
901 @Override
902 public boolean enabled() {
903 return !deviceBlacklist.contains(subj);
904 }
905 };
906 } else if (configClass == LinkDiscoveryFromPort.class) {
907 return (C) new LinkDiscoveryFromPort() {
908 @Override
909 public boolean enabled() {
910 return !portBlacklist.contains(subj);
911 }
912 };
913 } else {
914 return null;
915 }
Naoki Shiota399a0b32015-11-15 20:36:13 -0600916 }
917
918 @Override
919 public void addListener(NetworkConfigListener listener) {
920 configListener = listener;
921 }
922 }
923
924 private final class TestSuppressionConfig extends SuppressionConfig {
Naoki Shiota399a0b32015-11-15 20:36:13 -0600925 private Set<Device.Type> deviceTypes = new HashSet<>(DEFAULT_RULES.getSuppressedDeviceType());
926 private Map<String, String> annotation = new HashMap<>(DEFAULT_RULES.getSuppressedAnnotation());
927
928 @Override
Naoki Shiota399a0b32015-11-15 20:36:13 -0600929 public Set<Device.Type> deviceTypes() {
930 return ImmutableSet.copyOf(deviceTypes);
931 }
932
933 @Override
934 public SuppressionConfig deviceTypes(Set<Device.Type> deviceTypes) {
935 this.deviceTypes = ImmutableSet.copyOf(deviceTypes);
936 return this;
937 }
938
939 @Override
940 public Map<String, String> annotation() {
941 return ImmutableMap.copyOf(annotation);
942 }
943
944 @Override
945 public SuppressionConfig annotation(Map<String, String> annotation) {
946 this.annotation = ImmutableMap.copyOf(annotation);
947 return this;
948 }
949 }
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800950
951 private final class TestMetadataService implements ClusterMetadataService {
952 @Override
953 public ClusterMetadata getClusterMetadata() {
954 final NodeId nid = new NodeId("test-node");
955 final IpAddress addr = IpAddress.valueOf(0);
Madan Jampani8474fdd2016-01-19 09:56:28 -0800956 final Partition p = new DefaultPartition(PartitionId.from(1), Sets.newHashSet(nid));
Madan Jampaniad3c5262016-01-20 00:50:17 -0800957 return new ClusterMetadata("test-cluster",
958 Sets.newHashSet(new DefaultControllerNode(nid, addr)),
959 Sets.newHashSet(p));
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800960 }
961
962 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800963 public ControllerNode getLocalNode() {
964 return null;
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800965 }
966
967 @Override
Madan Jampaniab7e7cd2016-01-14 14:02:32 -0800968 public void addListener(ClusterMetadataEventListener listener) {
969 }
970
971 @Override
972 public void removeListener(ClusterMetadataEventListener listener) {
Ayaka Koshibe12c8c082015-12-08 12:48:46 -0800973 }
974 }
alshabib0ed6a202014-10-19 12:42:57 -0700975}