blob: 63cab05cc02e8862b817289826ba7a4ec7ec2c5e [file] [log] [blame]
Matteo Scandolo962a6ad2018-12-11 15:39:42 -08001/*
Joey Armstrong7f6d6d22023-01-09 17:09:50 -05002 * Copyright 2021-2023 Open Networking Foundation (ONF) and the ONF Contributors
Matteo Scandolo962a6ad2018-12-11 15:39:42 -08003 *
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 */
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070016
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080017package org.opencord.olt.impl;
18
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070019import org.junit.After;
20import org.junit.Assert;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080021import org.junit.Before;
22import org.junit.Test;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070023import org.junit.runner.RunWith;
24import org.mockito.Mockito;
25import org.mockito.runners.MockitoJUnitRunner;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080026import org.onlab.packet.ChassisId;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070027import org.onosproject.cfg.ComponentConfigAdapter;
28import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreServiceAdapter;
30import org.onosproject.core.DefaultApplicationId;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080031import org.onosproject.net.AnnotationKeys;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080032import org.onosproject.net.ConnectPoint;
33import org.onosproject.net.DefaultAnnotations;
34import org.onosproject.net.DefaultDevice;
35import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080037import org.onosproject.net.Port;
38import org.onosproject.net.PortNumber;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070039import org.onosproject.net.device.DeviceService;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080040import org.onosproject.net.provider.ProviderId;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070041import org.onosproject.store.service.TestStorageService;
Gustavo Silva29fb20e2022-05-26 09:59:54 -030042import org.opencord.olt.DiscoveredSubscriber;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070043import org.opencord.sadis.SadisService;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080044import org.opencord.sadis.SubscriberAndDeviceInformation;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070045import org.opencord.sadis.UniTagInformation;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080046import org.slf4j.Logger;
47import org.slf4j.LoggerFactory;
48
Andrea Campanella61650a12022-01-24 18:09:44 -080049import java.util.HashMap;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070050import java.util.LinkedList;
51import java.util.List;
52import java.util.concurrent.Executors;
53import java.util.concurrent.LinkedBlockingQueue;
54import java.util.concurrent.TimeUnit;
55
56import static org.mockito.Matchers.any;
57import static org.mockito.Matchers.eq;
58import static org.mockito.Mockito.atLeastOnce;
59import static org.mockito.Mockito.doReturn;
60import static org.mockito.Mockito.never;
61import static org.mockito.Mockito.reset;
62import static org.mockito.Mockito.spy;
63import static org.mockito.Mockito.times;
64import static org.mockito.Mockito.verify;
65import static org.onlab.util.Tools.groupedThreads;
66import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
67
68/**
69 * Set of tests of the ONOS application component.
70 */
71
72@RunWith(MockitoJUnitRunner.class)
73public class OltTest extends OltTestHelpers {
74
75 private Olt component;
76 private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080077 private final Logger log = LoggerFactory.getLogger(getClass());
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080078
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070079 private DeviceId deviceId = DeviceId.deviceId("test-device");
80 private Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
81 "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
82 private Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
83 DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1")
84 .build());
85 private ConnectPoint cp = new ConnectPoint(deviceId, uniUpdateEnabled.number());
86 private DiscoveredSubscriber sub;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080087
88 @Before
89 public void setUp() {
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070090 component = new Olt();
91 component.requeueDelay = 0; // avoid delays in the queue add to make things easier in testing
92 component.cfgService = new ComponentConfigAdapter();
93 component.deviceService = Mockito.mock(DeviceService.class);
94 component.storageService = new TestStorageService();
95 component.coreService = Mockito.spy(new CoreServiceAdapter());
96 component.oltDeviceService = Mockito.mock(OltDeviceService.class);
97
98 doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
99
100 component.discoveredSubscriberExecutor =
101 Executors.newSingleThreadScheduledExecutor(
102 groupedThreads("onos/olt",
103 "discovered-cp-%d", log));
104 component.flowsExecutor =
105 Executors.newFixedThreadPool(component.flowProcessingThreads,
106 groupedThreads("onos/olt-service",
107 "flows-installer-%d"));
108
109 component.subscriberExecutor = Executors.newFixedThreadPool(component.subscriberProcessingThreads,
110 groupedThreads("onos/olt-service",
111 "subscriber-installer-%d"));
112 SadisService sadisService = Mockito.mock(SadisService.class);
113 component.oltFlowService = Mockito.mock(OltFlowService.class);
114 component.sadisService = sadisService;
115
116 // reset the spy on oltFlowService
117 reset(component.oltFlowService);
118
119 component.bindSadisService(sadisService);
Andrea Campanella61650a12022-01-24 18:09:44 -0800120 component.eventsQueues = new HashMap<>();
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700121 component.eventsQueues.put(cp, new LinkedBlockingQueue<>());
122
123 component.discoveredSubscriberExecutor.execute(() -> {
124 component.processDiscoveredSubscribers();
125 });
126 // create empty service for testing
127 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
128 UniTagInformation empty = new UniTagInformation.Builder().build();
129 uniTagInformationList.add(empty);
130 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
131 si.setUniTagList(uniTagInformationList);
132 sub = new DiscoveredSubscriber(testDevice,
133 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
134 false, si);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800135 }
136
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700137 @After
138 public void tearDown() {
139 component.deactivate(null);
140 }
141
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800142 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700143 public void testProcessDiscoveredSubscribersBasicPortSuccess() throws Exception {
144 doReturn(true).when(component.deviceService).isAvailable(any());
145 doReturn(sub.port).when(component.deviceService).getPort(any(), any());
146 doReturn(true).when(component.oltFlowService).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
147 eq(DEFAULT_BP_ID_DEFAULT));
148 doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
149
150 // adding the discovered subscriber to the queue
151 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
152 q.add(sub);
153 component.eventsQueues.put(cp, q);
154
155 // check that we're calling the correct method
156 TimeUnit.MILLISECONDS.sleep(600);
157 verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
158 eq(DEFAULT_BP_ID_DEFAULT));
159
160 // check if the method doesn't throw an exception we're removing the subscriber from the queue
161 LinkedBlockingQueue<DiscoveredSubscriber> updatedQueue = component.eventsQueues.get(cp);
162 assert updatedQueue.isEmpty();
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800163 }
164
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800165 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700166 public void testProcessDiscoveredSubscribersBasicPortException() throws Exception {
167 doReturn(true).when(component.deviceService).isAvailable(any());
168 doReturn(sub.port).when(component.deviceService).getPort(any(), any());
169 doReturn(false).when(component.oltFlowService).handleBasicPortFlows(any(), eq(DEFAULT_BP_ID_DEFAULT),
170 eq(DEFAULT_BP_ID_DEFAULT));
171 doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
172 // replace the queue with a spy
173 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
174 LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
175 // adding the discovered subscriber to the queue
176 spiedQueue.add(sub);
177 component.eventsQueues.put(cp, spiedQueue);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800178
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700179 TimeUnit.MILLISECONDS.sleep(600);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800180
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700181 // check that we're calling the correct method,
182 // since the subscriber is not removed from the queue we're calling the method multiple times
183 verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
184 eq(DEFAULT_BP_ID_DEFAULT));
185
186 // check if the method throws an exception we are not removing the subscriber from the queue
187 verify(spiedQueue, never()).remove(sub);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800188 }
189
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700190 @Test
191 public void testAddSubscriberToQueue() {
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800192
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700193 // replace the queue with a spy
194 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
195 LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
196 component.eventsQueues.put(cp, spiedQueue);
197
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700198 component.addSubscriberToQueue(sub);
199 component.addSubscriberToQueue(sub);
200
Matteo Scandolod7aa89c2021-12-07 10:21:34 -0800201 verify(spiedQueue, times(2)).add(sub);
202 Assert.assertEquals(2, spiedQueue.size());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700203
204
205
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800206 }
207
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700208}