2 * Copyright © 2021 Orange. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.transportpce.servicehandler.listeners;
11 import static org.junit.Assert.fail;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.never;
15 import static org.mockito.Mockito.times;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
19 import java.util.Collection;
20 import java.util.HashSet;
22 import org.junit.Test;
23 import org.junit.runner.RunWith;
24 import org.mockito.Mock;
25 import org.mockito.junit.MockitoJUnitRunner;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.DataObjectModification;
28 import org.opendaylight.mdsal.binding.api.DataTreeModification;
29 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev210528.NodeIdType;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.ConnectionType;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceAEnd;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceAEndBuilder;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceZEnd;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.ServiceZEndBuilder;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.RxDirection;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.RxDirectionBuilder;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.RxDirectionKey;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.TxDirection;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.TxDirectionBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.endpoint.TxDirectionKey;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.lgx.LgxBuilder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev211210.service.port.PortBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat;
47 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.Services;
48 import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev211210.service.list.ServicesBuilder;
49 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationAlarmService;
50 import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationAlarmServiceBuilder;
51 import org.opendaylight.yangtools.yang.common.Uint32;
52 import org.opendaylight.yangtools.yang.common.Uint8;
54 @RunWith(MockitoJUnitRunner.StrictStubs.class)
55 public class ServiceListenerTest {
58 private DataBroker dataBroker;
60 private NotificationPublishService notificationPublishService;
63 public void testOnDataTreeChangedWhenDeleteService() {
64 @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
65 mock(DataObjectModification.class);
66 final Collection<DataTreeModification<Services>> changes = new HashSet<>();
67 @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
69 when(ch.getRootNode()).thenReturn(service);
71 when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
72 when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
73 ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService);
74 listener.onDataTreeChanged(changes);
75 verify(ch, times(1)).getRootNode();
76 verify(service, times(1)).getModificationType();
77 verify(service, times(2)).getDataBefore();
78 verify(service, never()).getDataAfter();
80 verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class));
81 } catch (InterruptedException e) {
82 fail("Failed publishing notification");
87 public void testOnDataTreeChangedWhenAddService() {
88 @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
89 mock(DataObjectModification.class);
90 final Collection<DataTreeModification<Services>> changes = new HashSet<>();
91 @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
93 when(ch.getRootNode()).thenReturn(service);
95 Services serviceDown = buildService(State.OutOfService, AdminStates.OutOfService);
96 when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
97 when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
98 when(service.getDataAfter()).thenReturn(serviceDown);
99 ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService);
100 listener.onDataTreeChanged(changes);
101 verify(ch, times(1)).getRootNode();
102 verify(service, times(1)).getModificationType();
103 verify(service, times(3)).getDataBefore();
104 verify(service, times(2)).getDataAfter();
105 PublishNotificationAlarmService publishNotificationAlarmService =
106 buildNotificationAlarmService(serviceDown, "The service is now outOfService");
108 verify(notificationPublishService, times(1))
109 .putNotification(publishNotificationAlarmService);
110 } catch (InterruptedException e) {
111 fail("Failed publishing notification");
116 public void testOnDataTreeChangedWhenShouldNeverHappen() {
117 @SuppressWarnings("unchecked") final DataObjectModification<Services> service =
118 mock(DataObjectModification.class);
119 final Collection<DataTreeModification<Services>> changes = new HashSet<>();
120 @SuppressWarnings("unchecked") final DataTreeModification<Services> ch = mock(DataTreeModification.class);
122 when(ch.getRootNode()).thenReturn(service);
124 when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
125 when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService));
126 ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService);
127 listener.onDataTreeChanged(changes);
128 verify(ch, times(1)).getRootNode();
129 verify(service, times(2)).getModificationType();
130 verify(service, times(2)).getDataBefore();
131 verify(service, never()).getDataAfter();
133 verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class));
134 } catch (InterruptedException e) {
135 fail("Failed publishing notification");
139 private Services buildService(State state, AdminStates adminStates) {
140 ServiceAEnd serviceAEnd = getServiceAEndBuild().build();
141 ServiceZEnd serviceZEnd = new ServiceZEndBuilder()
143 .setServiceFormat(ServiceFormat.OC)
144 .setServiceRate(Uint32.valueOf(1))
145 .setNodeId(new NodeIdType("XPONDER-3-2"))
146 .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()),getTxDirection()))
147 .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection()))
149 ServicesBuilder builtInput = new ServicesBuilder()
150 .setCommonId("commonId")
151 .setConnectionType(ConnectionType.Service)
152 .setCustomer("Customer")
153 .setServiceName("service 1")
154 .setServiceAEnd(serviceAEnd)
155 .setServiceZEnd(serviceZEnd)
156 .setOperationalState(state)
157 .setAdministrativeState(adminStates);
159 return builtInput.build();
162 private ServiceAEndBuilder getServiceAEndBuild() {
163 return new ServiceAEndBuilder()
165 .setServiceFormat(ServiceFormat.OC)
166 .setServiceRate(Uint32.valueOf(1))
167 .setNodeId(new NodeIdType("XPONDER-1-2"))
168 .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()),getTxDirection()))
169 .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection()));
172 private TxDirection getTxDirection() {
173 return new TxDirectionBuilder()
174 .setPort(new PortBuilder()
175 .setPortDeviceName("device name")
176 .setPortName("port name")
177 .setPortRack("port rack")
178 .setPortShelf("port shelf")
179 .setPortSlot("port slot")
180 .setPortSubSlot("port subslot")
181 .setPortType("port type")
183 .setLgx(new LgxBuilder()
184 .setLgxDeviceName("lgx device name")
185 .setLgxPortName("lgx port name")
186 .setLgxPortRack("lgx port rack")
187 .setLgxPortShelf("lgx port shelf")
189 .setIndex(Uint8.ZERO)
193 private RxDirection getRxDirection() {
194 return new RxDirectionBuilder()
195 .setPort(new PortBuilder()
196 .setPortDeviceName("device name")
197 .setPortName("port name")
198 .setPortRack("port rack")
199 .setPortShelf("port shelf")
200 .setPortSlot("port slot")
201 .setPortSubSlot("port subslot")
202 .setPortType("port type")
204 .setLgx(new LgxBuilder()
205 .setLgxDeviceName("lgx device name")
206 .setLgxPortName("lgx port name")
207 .setLgxPortRack("lgx port rack")
208 .setLgxPortShelf("lgx port shelf")
210 .setIndex(Uint8.ZERO)
214 private PublishNotificationAlarmService buildNotificationAlarmService(Services services, String message) {
215 return new PublishNotificationAlarmServiceBuilder()
216 .setServiceName("service 1")
217 .setConnectionType(ConnectionType.Service)
219 .setOperationalState(services.getOperationalState())
220 .setPublisherName("ServiceListener")