blob: d968c24217a92ba31e6d1d5a4a44a6d62d539d0a [file] [log] [blame]
Matteo Scandolo962a6ad2018-12-11 15:39:42 -08001/*
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07002 * Copyright 2021-present Open Networking Foundation
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;
42import org.opencord.sadis.SadisService;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080043import org.opencord.sadis.SubscriberAndDeviceInformation;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070044import org.opencord.sadis.UniTagInformation;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080045import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47
Andrea Campanella61650a12022-01-24 18:09:44 -080048import java.util.HashMap;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070049import java.util.LinkedList;
50import java.util.List;
51import java.util.concurrent.Executors;
52import java.util.concurrent.LinkedBlockingQueue;
53import java.util.concurrent.TimeUnit;
54
55import static org.mockito.Matchers.any;
56import static org.mockito.Matchers.eq;
57import static org.mockito.Mockito.atLeastOnce;
58import static org.mockito.Mockito.doReturn;
59import static org.mockito.Mockito.never;
60import static org.mockito.Mockito.reset;
61import static org.mockito.Mockito.spy;
62import static org.mockito.Mockito.times;
63import static org.mockito.Mockito.verify;
64import static org.onlab.util.Tools.groupedThreads;
65import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
66
67/**
68 * Set of tests of the ONOS application component.
69 */
70
71@RunWith(MockitoJUnitRunner.class)
72public class OltTest extends OltTestHelpers {
73
74 private Olt component;
75 private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080076 private final Logger log = LoggerFactory.getLogger(getClass());
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080077
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070078 private DeviceId deviceId = DeviceId.deviceId("test-device");
79 private Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
80 "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
81 private Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
82 DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1")
83 .build());
84 private ConnectPoint cp = new ConnectPoint(deviceId, uniUpdateEnabled.number());
85 private DiscoveredSubscriber sub;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080086
87 @Before
88 public void setUp() {
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070089 component = new Olt();
90 component.requeueDelay = 0; // avoid delays in the queue add to make things easier in testing
91 component.cfgService = new ComponentConfigAdapter();
92 component.deviceService = Mockito.mock(DeviceService.class);
93 component.storageService = new TestStorageService();
94 component.coreService = Mockito.spy(new CoreServiceAdapter());
95 component.oltDeviceService = Mockito.mock(OltDeviceService.class);
96
97 doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
98
99 component.discoveredSubscriberExecutor =
100 Executors.newSingleThreadScheduledExecutor(
101 groupedThreads("onos/olt",
102 "discovered-cp-%d", log));
103 component.flowsExecutor =
104 Executors.newFixedThreadPool(component.flowProcessingThreads,
105 groupedThreads("onos/olt-service",
106 "flows-installer-%d"));
107
108 component.subscriberExecutor = Executors.newFixedThreadPool(component.subscriberProcessingThreads,
109 groupedThreads("onos/olt-service",
110 "subscriber-installer-%d"));
111 SadisService sadisService = Mockito.mock(SadisService.class);
112 component.oltFlowService = Mockito.mock(OltFlowService.class);
113 component.sadisService = sadisService;
114
115 // reset the spy on oltFlowService
116 reset(component.oltFlowService);
117
118 component.bindSadisService(sadisService);
Andrea Campanella61650a12022-01-24 18:09:44 -0800119 component.eventsQueues = new HashMap<>();
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700120 component.eventsQueues.put(cp, new LinkedBlockingQueue<>());
121
122 component.discoveredSubscriberExecutor.execute(() -> {
123 component.processDiscoveredSubscribers();
124 });
125 // create empty service for testing
126 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
127 UniTagInformation empty = new UniTagInformation.Builder().build();
128 uniTagInformationList.add(empty);
129 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
130 si.setUniTagList(uniTagInformationList);
131 sub = new DiscoveredSubscriber(testDevice,
132 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
133 false, si);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800134 }
135
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700136 @After
137 public void tearDown() {
138 component.deactivate(null);
139 }
140
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800141 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700142 public void testProcessDiscoveredSubscribersBasicPortSuccess() throws Exception {
143 doReturn(true).when(component.deviceService).isAvailable(any());
144 doReturn(sub.port).when(component.deviceService).getPort(any(), any());
145 doReturn(true).when(component.oltFlowService).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
146 eq(DEFAULT_BP_ID_DEFAULT));
147 doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
148
149 // adding the discovered subscriber to the queue
150 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
151 q.add(sub);
152 component.eventsQueues.put(cp, q);
153
154 // check that we're calling the correct method
155 TimeUnit.MILLISECONDS.sleep(600);
156 verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
157 eq(DEFAULT_BP_ID_DEFAULT));
158
159 // check if the method doesn't throw an exception we're removing the subscriber from the queue
160 LinkedBlockingQueue<DiscoveredSubscriber> updatedQueue = component.eventsQueues.get(cp);
161 assert updatedQueue.isEmpty();
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800162 }
163
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800164 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700165 public void testProcessDiscoveredSubscribersBasicPortException() throws Exception {
166 doReturn(true).when(component.deviceService).isAvailable(any());
167 doReturn(sub.port).when(component.deviceService).getPort(any(), any());
168 doReturn(false).when(component.oltFlowService).handleBasicPortFlows(any(), eq(DEFAULT_BP_ID_DEFAULT),
169 eq(DEFAULT_BP_ID_DEFAULT));
170 doReturn(true).when(component.oltDeviceService).isLocalLeader(cp.deviceId());
171 // replace the queue with a spy
172 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
173 LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
174 // adding the discovered subscriber to the queue
175 spiedQueue.add(sub);
176 component.eventsQueues.put(cp, spiedQueue);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800177
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700178 TimeUnit.MILLISECONDS.sleep(600);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800179
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700180 // check that we're calling the correct method,
181 // since the subscriber is not removed from the queue we're calling the method multiple times
182 verify(component.oltFlowService, atLeastOnce()).handleBasicPortFlows(eq(sub), eq(DEFAULT_BP_ID_DEFAULT),
183 eq(DEFAULT_BP_ID_DEFAULT));
184
185 // check if the method throws an exception we are not removing the subscriber from the queue
186 verify(spiedQueue, never()).remove(sub);
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800187 }
188
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700189 @Test
190 public void testAddSubscriberToQueue() {
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800191
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700192 // replace the queue with a spy
193 LinkedBlockingQueue<DiscoveredSubscriber> q = component.eventsQueues.get(cp);
194 LinkedBlockingQueue<DiscoveredSubscriber> spiedQueue = spy(q);
195 component.eventsQueues.put(cp, spiedQueue);
196
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700197 component.addSubscriberToQueue(sub);
198 component.addSubscriberToQueue(sub);
199
Matteo Scandolod7aa89c2021-12-07 10:21:34 -0800200 verify(spiedQueue, times(2)).add(sub);
201 Assert.assertEquals(2, spiedQueue.size());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700202
203
204
Matteo Scandolo962a6ad2018-12-11 15:39:42 -0800205 }
206
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700207}