blob: 6841f4e9cf264d064420119816c6bce7014ab96f [file] [log] [blame]
Michele Santuari208b1672016-08-04 17:33:12 +02001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Michele Santuari208b1672016-08-04 17:33:12 +02003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.provider.linkdiscovery.impl;
17
18import com.google.common.collect.ImmutableSet;
19import org.junit.Before;
Thomas Vachuskae2d80762020-01-21 09:28:07 -080020import org.junit.Ignore;
Michele Santuari208b1672016-08-04 17:33:12 +020021import org.junit.Test;
22import org.onlab.osgi.ComponentContextAdapter;
23import org.onlab.packet.ChassisId;
24import org.onosproject.cfg.ComponentConfigAdapter;
25import org.onosproject.core.ApplicationId;
26import org.onosproject.core.CoreService;
27import org.onosproject.core.DefaultApplicationId;
28import org.onosproject.mastership.MastershipService;
29import org.onosproject.mastership.MastershipServiceAdapter;
30import org.onosproject.net.AbstractProjectableModel;
31import org.onosproject.net.AnnotationKeys;
32import org.onosproject.net.Annotations;
33import org.onosproject.net.ConnectPoint;
34import org.onosproject.net.DefaultAnnotations;
35import org.onosproject.net.DefaultDevice;
36import org.onosproject.net.DefaultLink;
37import org.onosproject.net.Device;
38import org.onosproject.net.DeviceId;
39import org.onosproject.net.Link;
40import org.onosproject.net.LinkKey;
41import org.onosproject.net.PortNumber;
42import org.onosproject.net.behaviour.LinkDiscovery;
43import org.onosproject.net.device.DeviceListener;
44import org.onosproject.net.device.DeviceServiceAdapter;
45import org.onosproject.net.driver.AbstractHandlerBehaviour;
46import org.onosproject.net.driver.Behaviour;
47import org.onosproject.net.driver.Driver;
48import org.onosproject.net.driver.DriverAdapter;
49import org.onosproject.net.driver.DriverHandler;
50import org.onosproject.net.driver.DriverServiceAdapter;
51import org.onosproject.net.link.DefaultLinkDescription;
52import org.onosproject.net.link.LinkDescription;
53import org.onosproject.net.link.LinkProviderRegistryAdapter;
54import org.onosproject.net.link.LinkProviderServiceAdapter;
55import org.onosproject.net.link.LinkServiceAdapter;
56import org.onosproject.net.provider.ProviderId;
57
58import java.util.Dictionary;
59import java.util.HashSet;
60import java.util.Hashtable;
61import java.util.Set;
62
63import static org.easymock.EasyMock.*;
64import static org.junit.Assert.*;
65import static org.onlab.junit.TestTools.assertAfter;
66import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.APP_NAME;
67import static org.onosproject.provider.linkdiscovery.impl.LinkDiscoveryProvider.SCHEME_NAME;
68
69/**
70 * Test for polling mechanism of the NetconfLinkProvider.
71 */
72public class LinkDiscoveryProviderTest {
73
74 private static final ComponentContextAdapter CONTEXT =
75 new ComponentContextAdapter() {
76 @Override
77 public Dictionary getProperties() {
78 Hashtable<String, Integer> props = new Hashtable<>();
79 props.put("linkPollFrequencySeconds", 2);
80 props.put("linkPollDelaySeconds", 1);
DongRyeol Cha3c377802019-11-14 15:40:22 +090081 props.put("linkDiscoveryTimeoutSeconds", 1);
Michele Santuari208b1672016-08-04 17:33:12 +020082 return props;
83 }
84 };
85 // Network Mocks
86 private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId("netconf:1.1.1.1");
87 private static final DeviceId DEVICE_ID_2 = DeviceId.deviceId("netconf:1.1.1.2");
88 private static final ConnectPoint CP11 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(1));
89 private static final ConnectPoint CP12 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(2));
90 private static final ConnectPoint CP13 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(3));
91 private static final ConnectPoint CP14 = new ConnectPoint(DEVICE_ID_1, PortNumber.portNumber(4));
92 private static final ConnectPoint CP21 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(1));
93 private static final ConnectPoint CP22 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(2));
94 private static final ConnectPoint CP23 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(3));
95 private static final ConnectPoint CP24 = new ConnectPoint(DEVICE_ID_2, PortNumber.portNumber(4));
96 private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
97 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
98 private static final DefaultAnnotations LINK_ANNOTATIONS = DefaultAnnotations.builder()
99 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
100 private static final LinkKey LINKKEY1 = LinkKey.linkKey(CP11, CP21);
101 private static final LinkDescription LINK1 = new DefaultLinkDescription(CP11, CP21,
102 Link.Type.DIRECT,
103 LINK_ANNOTATIONS);
104 private static final LinkKey LINKKEY2 = LinkKey.linkKey(CP12, CP22);
105 private static final LinkDescription LINK2 = new DefaultLinkDescription(CP12, CP22,
106 Link.Type.DIRECT,
107 LINK_ANNOTATIONS);
108 private static final LinkKey LINKKEY3 = LinkKey.linkKey(CP13, CP23);
109 private static final LinkDescription LINK3 = new DefaultLinkDescription(CP13, CP23,
110 Link.Type.DIRECT,
111 DefaultAnnotations.builder()
112 .build());
113 private static final LinkKey LINKKEY4 = LinkKey.linkKey(CP14, CP24);
114 private static final LinkDescription LINK4 = new DefaultLinkDescription(CP14, CP24,
115 Link.Type.DIRECT,
116 DefaultAnnotations.builder().build());
117 //Service Mocks
118 private final MockDeviceService deviceService = new MockDeviceService();
119 private final LinkProviderRegistryAdapter linkRegistry = new LinkProviderRegistryAdapter();
120 private final MastershipService mastershipService = new MockMastershipService();
121 private final MockLinkService linkService = new MockLinkService();
122 private final Driver driver = new MockDriver();
123 //Provider related classes
124 private LinkProviderServiceAdapter providerService;
125 private CoreService coreService;
126 private LinkDiscoveryProvider provider = new LinkDiscoveryProvider();
127 private final Device device1 = new MockDevice(provider.id(), DEVICE_ID_1, Device.Type.SWITCH,
128 "foo.inc", "0", "0", "0", new ChassisId(),
129 DEVICE_ANNOTATIONS);
130 private Set<DeviceListener> deviceListeners = new HashSet<>();
131 private ApplicationId appId =
132 new DefaultApplicationId(100, APP_NAME);
133 private TestLink testLink = new TestLink();
134
135 @Before
136 public void setUp() {
137 coreService = createMock(CoreService.class);
138 expect(coreService.registerApplication(appId.name()))
139 .andReturn(appId).anyTimes();
140 replay(coreService);
141 provider.coreService = coreService;
142 provider.providerRegistry = linkRegistry;
143 provider.deviceService = deviceService;
144 provider.mastershipService = mastershipService;
145 provider.linkService = linkService;
146 provider.cfgService = new ComponentConfigAdapter();
147 AbstractProjectableModel.setDriverService(null, new DriverServiceAdapter());
148 provider.activate(null);
149 providerService = linkRegistry.registeredProvider();
150 }
151
152 @Test
153 public void activate() throws Exception {
Yuta HIGUCHIfbd9ae92018-01-24 23:39:06 -0800154 assertTrue("Provider should be registered", linkRegistry.getProviders().contains(provider.id()));
Michele Santuari208b1672016-08-04 17:33:12 +0200155 assertEquals("Device service should be registered", provider.deviceService, deviceService);
156 assertEquals("Device listener should be added", 1, deviceListeners.size());
157 assertNotNull("Registration expected", providerService);
158 assertEquals("Incorrect provider", provider, providerService.provider());
159 assertFalse("Executor should be running", provider.executor.isShutdown());
160 assertFalse("Executor should be running", provider.executor.isTerminated());
161 assertEquals("Incorrect polling frequency, should be default", 10,
162 provider.linkPollFrequencySeconds);
163 assertEquals("Incorrect polling delay , should be default", 20,
164 provider.linkPollDelaySeconds);
DongRyeol Cha3c377802019-11-14 15:40:22 +0900165 assertEquals("Incorrect polling discovery delay , should be default", 300,
166 provider.linkDiscoveryTimeoutSeconds);
Michele Santuari208b1672016-08-04 17:33:12 +0200167 }
168
169 @Test
170 public void modified() throws Exception {
171 provider.modified(CONTEXT);
172 assertEquals("Incorrect polling frequency, should be default", 2,
173 provider.linkPollFrequencySeconds);
174 assertEquals("Incorrect polling delay , should be default", 1,
175 provider.linkPollDelaySeconds);
DongRyeol Cha3c377802019-11-14 15:40:22 +0900176 assertEquals("Incorrect polling discovery delay , should be default", 1,
177 provider.linkDiscoveryTimeoutSeconds);
Michele Santuari208b1672016-08-04 17:33:12 +0200178
179 }
180
181
182 @Test
183 public void deactivate() throws Exception {
184 provider.deactivate();
185 assertEquals("Device listener should be removed", 0, deviceListeners.size());
Yuta HIGUCHIfbd9ae92018-01-24 23:39:06 -0800186 assertFalse("Provider should not be registered", linkRegistry.getProviders().contains(provider.id()));
Michele Santuari208b1672016-08-04 17:33:12 +0200187 assertTrue(provider.executor.isShutdown());
188 assertNull(provider.providerService);
189 }
190
191
192 @Test
Thomas Vachuskae2d80762020-01-21 09:28:07 -0800193 @Ignore("FIXME: fails intermittently; suspecting insufficient time and race condition")
Michele Santuari208b1672016-08-04 17:33:12 +0200194 public void linksTestForStoredDevice() {
195 provider.modified(CONTEXT);
196 providerService.discoveredLinkDescriptions().put(LINKKEY1, LINK1);
197 providerService.discoveredLinkDescriptions().put(LINKKEY2, LINK2);
198 providerService.discoveredLinkDescriptions().put(LINKKEY4, LINK4);
199 testLink.addLinkDesc(LINK2);
200 testLink.addLinkDesc(LINK3);
201 assertAfter(1100, () -> {
202 assertEquals("Total number of link must be 3", 3, providerService.discoveredLinkDescriptions().size());
203 assertFalse("Link1 should be removed",
204 providerService.discoveredLinkDescriptions().containsKey(LINKKEY1));
205 assertTrue("Link2 should be present",
206 providerService.discoveredLinkDescriptions().containsKey(LINKKEY2));
207 assertTrue("Link3 should be added",
208 providerService.discoveredLinkDescriptions().containsKey(LINKKEY3));
209 assertEquals("Link3 should be annotated", SCHEME_NAME.toUpperCase(),
210 providerService.discoveredLinkDescriptions()
211 .get(LINKKEY3).annotations().value(AnnotationKeys.PROTOCOL));
212 assertTrue("Link4 should be present because it is not related to the LinkDiscovery",
213 providerService.discoveredLinkDescriptions().containsKey(LINKKEY4));
214
215 });
216 clear();
217 }
218
219 private void clear() {
220 testLink.clearLinkDesc();
221 providerService.discoveredLinkDescriptions().clear();
222 providerService.discoveredLinks().clear();
223 }
224
225 private class MockDeviceService extends DeviceServiceAdapter {
226
227 @Override
228 public Iterable<Device> getAvailableDevices() {
229 return ImmutableSet.of(device1);
230 }
231
232 @Override
DongRyeol Cha3c377802019-11-14 15:40:22 +0900233 public Device getDevice(DeviceId deviceId) {
234 return device1;
235 }
236
237 @Override
Michele Santuari208b1672016-08-04 17:33:12 +0200238 public void addListener(DeviceListener listener) {
239 deviceListeners.add(listener);
240 }
241
242 @Override
243 public void removeListener(DeviceListener listener) {
244 deviceListeners.remove(listener);
245 }
246 }
247
248 private class MockMastershipService extends MastershipServiceAdapter {
249
250 @Override
251 public boolean isLocalMaster(DeviceId deviceId) {
252 return true;
253 }
254 }
255
256 private class MockLinkService extends LinkServiceAdapter {
257 @Override
DongRyeol Cha9547fc12018-07-24 15:26:16 +0900258 public Set<Link> getDeviceIngressLinks(DeviceId deviceId) {
Michele Santuari208b1672016-08-04 17:33:12 +0200259 Set<Link> links = new HashSet<>();
260 providerService.discoveredLinkDescriptions().values()
261 .forEach(x -> links.add(DefaultLink.builder()
262 .providerId(provider.id())
263 .src(x.src())
264 .dst(x.dst())
265 .type(x.type())
266 .isExpected(x.isExpected())
267 .annotations(x.annotations()).build()));
268 return ImmutableSet.copyOf(links);
269 }
270 }
271
272 private class MockDevice extends DefaultDevice {
273
274 public MockDevice(ProviderId providerId, DeviceId id, Type type,
275 String manufacturer, String hwVersion, String swVersion,
276 String serialNumber, ChassisId chassisId, Annotations... annotations) {
277 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
278 chassisId, annotations);
279 }
280
281 @Override
282 protected Driver locateDriver() {
283 return driver;
284 }
285
286 @Override
287 public Driver driver() {
288 return driver;
289 }
290 }
291
292 private class MockDriver extends DriverAdapter {
293 @Override
294 public <T extends Behaviour> T createBehaviour(DriverHandler handler, Class<T> behaviourClass) {
295
296 return (T) testLink;
297 }
298 }
299
300 private class TestLink extends AbstractHandlerBehaviour implements LinkDiscovery {
301 Set<LinkDescription> linkDescriptions = new HashSet<>();
302
303 @Override
304 public Set<LinkDescription> getLinks() {
305 return ImmutableSet.copyOf(linkDescriptions);
306 }
307
308 private void addLinkDesc(LinkDescription link) {
309 linkDescriptions.add(link);
310 }
311
312 private void clearLinkDesc() {
313 linkDescriptions.clear();
314 }
315
316 }
DongRyeol Cha3c377802019-11-14 15:40:22 +0900317}