X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=servicehandler%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fservicehandler%2Flisteners%2FServiceListenerTest.java;h=442189164fcc09cbaa31796529f2750178cdf588;hb=b1b3bafd549bb501937cea5c976d5344608b6ed3;hp=cf85247a5fcfe124b139c7c7a52f9560fb3eafa9;hpb=274148a8d813140f86e1f9770ba992b072c1a5cd;p=transportpce.git diff --git a/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListenerTest.java b/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListenerTest.java index cf85247a5..442189164 100755 --- a/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListenerTest.java +++ b/servicehandler/src/test/java/org/opendaylight/transportpce/servicehandler/listeners/ServiceListenerTest.java @@ -5,73 +5,102 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.transportpce.servicehandler.listeners; -import static org.junit.Assert.fail; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.Collection; -import java.util.HashSet; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; -import org.opendaylight.mdsal.binding.api.DataBroker; +import org.mockito.junit.jupiter.MockitoExtension; import org.opendaylight.mdsal.binding.api.DataObjectModification; import org.opendaylight.mdsal.binding.api.DataTreeModification; import org.opendaylight.mdsal.binding.api.NotificationPublishService; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev181130.NodeIdType; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.ConnectionType; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceAEnd; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceAEndBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceZEnd; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceZEndBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.RxDirection; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.RxDirectionBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.TxDirection; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.endpoint.TxDirectionBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.lgx.LgxBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.port.PortBuilder; -import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev181130.State; -import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev181130.AdminStates; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev190531.ServiceFormat; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.Services; -import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev190531.service.list.ServicesBuilder; -import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationAlarmService; -import org.opendaylight.yang.gen.v1.nbi.notifications.rev210813.PublishNotificationAlarmServiceBuilder; +import org.opendaylight.mdsal.binding.api.RpcService; +import org.opendaylight.transportpce.common.ResponseCodes; +import org.opendaylight.transportpce.pce.service.PathComputationService; +import org.opendaylight.transportpce.servicehandler.service.ServiceDataStoreOperations; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.node.types.rev210528.NodeIdType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.ConnectionType; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.Restorable; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.configuration.response.common.ConfigurationResponseCommonBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.sdnc.request.header.SdncRequestHeaderBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceAEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.ServiceZEndBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.RxDirectionKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirection; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.endpoint.TxDirectionKey; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.lgx.LgxBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.port.PortBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliency; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev230526.service.resiliency.ServiceResiliencyBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.common.state.types.rev191129.State; +import org.opendaylight.yang.gen.v1.http.org.openroadm.equipment.states.types.rev191129.AdminStates; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.format.rev191129.ServiceFormat; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreate; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceCreateOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDelete; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceReroute; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceRerouteOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.Services; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.service.list.ServicesBuilder; +import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmService; +import org.opendaylight.yang.gen.v1.nbi.notifications.rev230728.PublishNotificationAlarmServiceBuilder; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.opendaylight.yangtools.yang.common.Uint32; +import org.opendaylight.yangtools.yang.common.Uint8; -@RunWith(MockitoJUnitRunner.StrictStubs.class) +@ExtendWith(MockitoExtension.class) public class ServiceListenerTest { @Mock - private DataBroker dataBroker; + private RpcService rpcService; + @Mock + private ServiceDataStoreOperations serviceDataStoreOperations; @Mock private NotificationPublishService notificationPublishService; + @Mock + private PathComputationService pathComputationService; + @Mock + private ServiceDelete serviceDelete; + @Mock + private ServiceReroute serviceReroute; + @Mock + private ServiceCreate serviceCreate; @Test - public void testOnDataTreeChangedWhenDeleteService() { + void testOnDataTreeChangedWhenDeleteService() { @SuppressWarnings("unchecked") final DataObjectModification service = mock(DataObjectModification.class); - final Collection> changes = new HashSet<>(); + final List> changes = new ArrayList<>(); @SuppressWarnings("unchecked") final DataTreeModification ch = mock(DataTreeModification.class); changes.add(ch); when(ch.getRootNode()).thenReturn(service); - when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); - when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); - ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService); + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); + when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); + ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations, + notificationPublishService); listener.onDataTreeChanged(changes); verify(ch, times(1)).getRootNode(); - verify(service, times(1)).getModificationType(); - verify(service, times(2)).getDataBefore(); - verify(service, never()).getDataAfter(); + verify(service, times(1)).modificationType(); + verify(service, times(2)).dataBefore(); + verify(service, never()).dataAfter(); try { verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class)); } catch (InterruptedException e) { @@ -80,51 +109,51 @@ public class ServiceListenerTest { } @Test - public void testOnDataTreeChangedWhenAddService() { + void testOnDataTreeChangedWhenServiceBecomesOutOfService() { @SuppressWarnings("unchecked") final DataObjectModification service = mock(DataObjectModification.class); - final Collection> changes = new HashSet<>(); + final List> changes = new ArrayList<>(); @SuppressWarnings("unchecked") final DataTreeModification ch = mock(DataTreeModification.class); changes.add(ch); when(ch.getRootNode()).thenReturn(service); - Services serviceDown = buildService(State.OutOfService, AdminStates.OutOfService); - when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); - when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); - when(service.getDataAfter()).thenReturn(serviceDown); - ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService); + Services serviceDown = buildService(State.OutOfService, AdminStates.InService); + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); + when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); + when(service.dataAfter()).thenReturn(serviceDown); + ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations, + notificationPublishService); listener.onDataTreeChanged(changes); verify(ch, times(1)).getRootNode(); - verify(service, times(1)).getModificationType(); - verify(service, times(3)).getDataBefore(); - verify(service, times(2)).getDataAfter(); - PublishNotificationAlarmService publishNotificationAlarmService = - buildNotificationAlarmService(serviceDown, "The service is now outOfService"); + verify(service, times(1)).modificationType(); + verify(service, times(3)).dataBefore(); + verify(service, times(1)).dataAfter(); try { verify(notificationPublishService, times(1)) - .putNotification(publishNotificationAlarmService); + .putNotification(buildNotificationAlarmService(serviceDown, "The service is now outOfService")); } catch (InterruptedException e) { fail("Failed publishing notification"); } } @Test - public void testOnDataTreeChangedWhenShouldNeverHappen() { + void testOnDataTreeChangedWhenShouldNeverHappen() { @SuppressWarnings("unchecked") final DataObjectModification service = mock(DataObjectModification.class); - final Collection> changes = new HashSet<>(); + final List> changes = new ArrayList<>(); @SuppressWarnings("unchecked") final DataTreeModification ch = mock(DataTreeModification.class); changes.add(ch); when(ch.getRootNode()).thenReturn(service); - when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED); - when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); - ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService); + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED); + when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); + ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations, + notificationPublishService); listener.onDataTreeChanged(changes); verify(ch, times(1)).getRootNode(); - verify(service, times(2)).getModificationType(); - verify(service, times(2)).getDataBefore(); - verify(service, never()).getDataAfter(); + verify(service, times(2)).modificationType(); + verify(service, times(2)).dataBefore(); + verify(service, never()).dataAfter(); try { verify(notificationPublishService, never()).putNotification(any(PublishNotificationAlarmService.class)); } catch (InterruptedException e) { @@ -132,37 +161,120 @@ public class ServiceListenerTest { } } + @Test + void testOnDataTreeChangedWhenServiceDegradedShouldBeRerouted() { + @SuppressWarnings("unchecked") final DataObjectModification service = + mock(DataObjectModification.class); + final List> changes = new ArrayList<>(); + @SuppressWarnings("unchecked") final DataTreeModification ch = mock(DataTreeModification.class); + changes.add(ch); + when(ch.getRootNode()).thenReturn(service); + + ServiceResiliency serviceResiliency = new ServiceResiliencyBuilder().setResiliency(Restorable.VALUE).build(); + Services serviceAfter = new ServicesBuilder(buildService(State.OutOfService, AdminStates.InService)) + .setServiceResiliency(serviceResiliency) + .build(); + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); + when(service.dataBefore()) + .thenReturn(new ServicesBuilder(buildService(State.InService, AdminStates.InService)) + .setServiceResiliency(serviceResiliency) + .build()); + when(service.dataAfter()).thenReturn(serviceAfter); + when(serviceDataStoreOperations.getService(anyString())).thenReturn(Optional.of(serviceAfter)); + when(rpcService.getRpc(ServiceDelete.class)).thenReturn(serviceDelete); + when(serviceDelete.invoke(any())) + .thenReturn(RpcResultBuilder.success(new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + when(rpcService.getRpc(ServiceReroute.class)).thenReturn(serviceReroute); + when(serviceReroute.invoke(any())) + .thenReturn(RpcResultBuilder.success(new ServiceRerouteOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + when(rpcService.getRpc(ServiceCreate.class)).thenReturn(serviceCreate); + when(serviceCreate.invoke(any())) + .thenReturn(RpcResultBuilder.success(new ServiceCreateOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations, + notificationPublishService); + listener.onDataTreeChanged(changes); + verify(ch, times(1)).getRootNode(); + verify(service, times(1)).modificationType(); + verify(service, times(3)).dataBefore(); + verify(service, times(1)).dataAfter(); +// verify(servicehandler, times(1)).serviceDelete(any()); + + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); + listener.onDataTreeChanged(changes); +// verify(servicehandler, times(1)).serviceCreate(any()); + } + + @Test + void testOnDataTreeChangedWhenServiceDegradedShouldNotBeRerouted() { + @SuppressWarnings("unchecked") final DataObjectModification service = + mock(DataObjectModification.class); + final List> changes = new ArrayList<>(); + @SuppressWarnings("unchecked") final DataTreeModification ch = mock(DataTreeModification.class); + changes.add(ch); + when(ch.getRootNode()).thenReturn(service); + + Services serviceAfter = buildService(State.OutOfService, AdminStates.InService); + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); + when(service.dataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); + when(service.dataAfter()).thenReturn(serviceAfter); + ServiceListener listener = new ServiceListener(rpcService, serviceDataStoreOperations, + notificationPublishService); + listener.onDataTreeChanged(changes); + verify(ch, times(1)).getRootNode(); + verify(service, times(1)).modificationType(); + verify(service, times(3)).dataBefore(); + verify(service, times(1)).dataAfter(); +// verify(servicehandler, times(0)).serviceDelete(any()); + + when(service.modificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); + listener.onDataTreeChanged(changes); +// verify(servicehandler, times(0)).serviceCreate(any()); + } + private Services buildService(State state, AdminStates adminStates) { - ServiceAEnd serviceAEnd = getServiceAEndBuild().build(); - ServiceZEnd serviceZEnd = new ServiceZEndBuilder() - .setClli("clli") - .setServiceFormat(ServiceFormat.OC) - .setServiceRate(Uint32.valueOf(1)) - .setNodeId(new NodeIdType("XPONDER-3-2")) - .setTxDirection(getTxDirection()) - .setRxDirection(getRxDirection()) - .build(); - ServicesBuilder builtInput = new ServicesBuilder() + return new ServicesBuilder() + .setSdncRequestHeader(new SdncRequestHeaderBuilder().build()) .setCommonId("commonId") .setConnectionType(ConnectionType.Service) .setCustomer("Customer") .setServiceName("service 1") - .setServiceAEnd(serviceAEnd) - .setServiceZEnd(serviceZEnd) + .setServiceAEnd(getServiceAEndBuild().build()) + .setServiceZEnd(new ServiceZEndBuilder() + .setClli("clli") + .setServiceFormat(ServiceFormat.Ethernet) + .setServiceRate(Uint32.valueOf(1)) + .setNodeId(new NodeIdType("XPONDER-3-2")) + .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()), getTxDirection())) + .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection())) + .build()) .setOperationalState(state) - .setAdministrativeState(adminStates); - - return builtInput.build(); + .setAdministrativeState(adminStates) + .build(); } private ServiceAEndBuilder getServiceAEndBuild() { return new ServiceAEndBuilder() .setClli("clli") - .setServiceFormat(ServiceFormat.OC) + .setServiceFormat(ServiceFormat.Ethernet) .setServiceRate(Uint32.valueOf(1)) .setNodeId(new NodeIdType("XPONDER-1-2")) - .setTxDirection(getTxDirection()) - .setRxDirection(getRxDirection()); + .setTxDirection(Map.of(new TxDirectionKey(getTxDirection().key()), getTxDirection())) + .setRxDirection(Map.of(new RxDirectionKey(getRxDirection().key()), getRxDirection())); } private TxDirection getTxDirection() { @@ -182,6 +294,7 @@ public class ServiceListenerTest { .setLgxPortRack("lgx port rack") .setLgxPortShelf("lgx port shelf") .build()) + .setIndex(Uint8.ZERO) .build(); } @@ -202,6 +315,7 @@ public class ServiceListenerTest { .setLgxPortRack("lgx port rack") .setLgxPortShelf("lgx port shelf") .build()) + .setIndex(Uint8.ZERO) .build(); } @@ -214,4 +328,4 @@ public class ServiceListenerTest { .setPublisherName("ServiceListener") .build(); } -} +} \ No newline at end of file