blob: 0448f9d1067908664f9b1f5b969f80791c692d4a [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
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070048import java.util.LinkedList;
49import java.util.List;
50import java.util.concurrent.Executors;
51import java.util.concurrent.LinkedBlockingQueue;
52import java.util.concurrent.TimeUnit;
53
54import static org.mockito.Matchers.any;
55import static org.mockito.Matchers.eq;
56import static org.mockito.Mockito.atLeastOnce;
57import static org.mockito.Mockito.doReturn;
58import static org.mockito.Mockito.never;
59import static org.mockito.Mockito.reset;
60import static org.mockito.Mockito.spy;
61import static org.mockito.Mockito.times;
62import static org.mockito.Mockito.verify;
63import static org.onlab.util.Tools.groupedThreads;
64import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
65
66/**
67 * Set of tests of the ONOS application component.
68 */
69
70@RunWith(MockitoJUnitRunner.class)
71public class OltTest extends OltTestHelpers {
72
73 private Olt component;
74 private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080075 private final Logger log = LoggerFactory.getLogger(getClass());
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080076
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070077 private DeviceId deviceId = DeviceId.deviceId("test-device");
78 private Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
79 "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
80 private Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
81 DefaultAnnotations.builder().set(AnnotationKeys.PORT_NAME, "uni-1")
82 .build());
83 private ConnectPoint cp = new ConnectPoint(deviceId, uniUpdateEnabled.number());
84 private DiscoveredSubscriber sub;
Matteo Scandolo962a6ad2018-12-11 15:39:42 -080085
86 @Before
87 public void setUp() {
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070088 component = new Olt();
89 component.requeueDelay = 0; // avoid delays in the queue add to make things easier in testing
90 component.cfgService = new ComponentConfigAdapter();
91 component.deviceService = Mockito.mock(DeviceService.class);
92 component.storageService = new TestStorageService();
93 component.coreService = Mockito.spy(new CoreServiceAdapter());
94 component.oltDeviceService = Mockito.mock(OltDeviceService.class);
95
96 doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
97
98 component.discoveredSubscriberExecutor =
99 Executors.newSingleThreadScheduledExecutor(
100 groupedThreads("onos/olt",
101 "discovered-cp-%d", log));
102 component.flowsExecutor =
103 Executors.newFixedThreadPool(component.flowProcessingThreads,
104 groupedThreads("onos/olt-service",
105 "flows-installer-%d"));
106
107 component.subscriberExecutor = Executors.newFixedThreadPool(component.subscriberProcessingThreads,
108 groupedThreads("onos/olt-service",
109 "subscriber-installer-%d"));
110 SadisService sadisService = Mockito.mock(SadisService.class);
111 component.oltFlowService = Mockito.mock(OltFlowService.class);
112 component.sadisService = sadisService;
113
114 // reset the spy on oltFlowService
115 reset(component.oltFlowService);
116
117 component.bindSadisService(sadisService);
118 component.eventsQueues = component.storageService.
119 <ConnectPoint, LinkedBlockingQueue<DiscoveredSubscriber>>consistentMapBuilder().build().asJavaMap();
120 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}