X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=servicehandler%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Ftransportpce%2Fservicehandler%2Flisteners%2FServiceListenerTest.java;h=08a1edb27e64cf5e378c97ef5789198c72c3364a;hb=f327d205217ec8eefa4326881f8d06f1378db37a;hp=f02dec19f433880189878ea8a470968c0238a55b;hpb=7f29ca37c9697d3adda029f649fd84d094885354;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 f02dec19f..08a1edb27 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 @@ -8,8 +8,9 @@ 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; @@ -18,39 +19,64 @@ 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.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.endpoint.RxDirection; -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.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.rev210628.PublishNotificationAlarmService; -import org.opendaylight.yang.gen.v1.nbi.notifications.rev210628.PublishNotificationAlarmServiceBuilder; +import org.opendaylight.transportpce.common.ResponseCodes; +import org.opendaylight.transportpce.pce.service.PathComputationService; +import org.opendaylight.transportpce.servicehandler.impl.ServicehandlerImpl; +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.ServiceCreateOutputBuilder; +import org.opendaylight.yang.gen.v1.http.org.openroadm.service.rev230526.ServiceDeleteOutputBuilder; +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.rev211013.PublishNotificationAlarmService; +import org.opendaylight.yang.gen.v1.nbi.notifications.rev211013.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 ServicehandlerImpl servicehandler; + @Mock + private ServiceDataStoreOperations serviceDataStoreOperations; @Mock private NotificationPublishService notificationPublishService; + @Mock + private PathComputationService pathComputationService; @Test - public void testOnDataTreeChangedWhenDeleteService() { + void testOnDataTreeChangedWhenDeleteService() { @SuppressWarnings("unchecked") final DataObjectModification service = mock(DataObjectModification.class); final Collection> changes = new HashSet<>(); @@ -60,7 +86,8 @@ public class ServiceListenerTest { when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); - ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService); + ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations, + notificationPublishService); listener.onDataTreeChanged(changes); verify(ch, times(1)).getRootNode(); verify(service, times(1)).getModificationType(); @@ -74,7 +101,7 @@ public class ServiceListenerTest { } @Test - public void testOnDataTreeChangedWhenAddService() { + void testOnDataTreeChangedWhenServiceBecomesOutOfService() { @SuppressWarnings("unchecked") final DataObjectModification service = mock(DataObjectModification.class); final Collection> changes = new HashSet<>(); @@ -82,28 +109,27 @@ public class ServiceListenerTest { changes.add(ch); when(ch.getRootNode()).thenReturn(service); - Services serviceDown = buildService(State.OutOfService, AdminStates.OutOfService); + Services serviceDown = buildService(State.OutOfService, AdminStates.InService); 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); + ServiceListener listener = new ServiceListener(servicehandler, 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)).getDataAfter(); 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<>(); @@ -113,7 +139,8 @@ public class ServiceListenerTest { when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED); when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); - ServiceListener listener = new ServiceListener(dataBroker, notificationPublishService); + ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations, + notificationPublishService); listener.onDataTreeChanged(changes); verify(ch, times(1)).getRootNode(); verify(service, times(2)).getModificationType(); @@ -126,61 +153,158 @@ public class ServiceListenerTest { } } - private Services buildService(State state, AdminStates adminStates) { - org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service.ServiceAEnd - serviceAEnd = getServiceAEndBuild() - .build(); - org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service - .ServiceZEnd serviceZEnd = new org.opendaylight.yang.gen.v1 - .http.org.openroadm.common.service.types.rev190531.service.ServiceZEndBuilder() - .setClli("clli").setServiceFormat(ServiceFormat.OC).setServiceRate(Uint32.valueOf(1)) - .setNodeId(new NodeIdType("XPONDER-3-2")) - .setTxDirection(getTxDirection()) - .setRxDirection(getRxDirection()) + @Test + void testOnDataTreeChangedWhenServiceDegradedShouldBeRerouted() { + @SuppressWarnings("unchecked") final DataObjectModification service = + mock(DataObjectModification.class); + final Collection> changes = new HashSet<>(); + @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.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); + when(service.getDataBefore()) + .thenReturn(new ServicesBuilder(buildService(State.InService, AdminStates.InService)) + .setServiceResiliency(serviceResiliency) + .build()); + when(service.getDataAfter()).thenReturn(serviceAfter); + when(serviceDataStoreOperations.getService(anyString())).thenReturn(Optional.of(serviceAfter)); + when(servicehandler.serviceDelete(any())) + .thenReturn(RpcResultBuilder.success(new ServiceDeleteOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + when(servicehandler.serviceReroute(any())) + .thenReturn(RpcResultBuilder.success(new ServiceRerouteOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + when(servicehandler.serviceCreate(any())) + .thenReturn(RpcResultBuilder.success(new ServiceCreateOutputBuilder() + .setConfigurationResponseCommon(new ConfigurationResponseCommonBuilder() + .setResponseCode(ResponseCodes.RESPONSE_OK) + .build()) + .build()) + .buildFuture()); + ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations, + notificationPublishService); + listener.onDataTreeChanged(changes); + verify(ch, times(1)).getRootNode(); + verify(service, times(1)).getModificationType(); + verify(service, times(3)).getDataBefore(); + verify(service, times(1)).getDataAfter(); + verify(servicehandler, times(1)).serviceDelete(any()); - ServicesBuilder builtInput = new ServicesBuilder() + when(service.getModificationType()).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 Collection> changes = new HashSet<>(); + @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.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE); + when(service.getDataBefore()).thenReturn(buildService(State.InService, AdminStates.InService)); + when(service.getDataAfter()).thenReturn(serviceAfter); + ServiceListener listener = new ServiceListener(servicehandler, serviceDataStoreOperations, + notificationPublishService); + listener.onDataTreeChanged(changes); + verify(ch, times(1)).getRootNode(); + verify(service, times(1)).getModificationType(); + verify(service, times(3)).getDataBefore(); + verify(service, times(1)).getDataAfter(); + verify(servicehandler, times(0)).serviceDelete(any()); + + when(service.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE); + listener.onDataTreeChanged(changes); + verify(servicehandler, times(0)).serviceCreate(any()); + } + + private Services buildService(State state, AdminStates adminStates) { + 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 org.opendaylight.yang.gen.v1 - .http.org.openroadm.common.service.types.rev190531.service.ServiceAEndBuilder getServiceAEndBuild() { - return new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service - .ServiceAEndBuilder() - .setClli("clli").setServiceFormat(ServiceFormat.OC).setServiceRate(Uint32.valueOf(1)) + private ServiceAEndBuilder getServiceAEndBuild() { + return new ServiceAEndBuilder() + .setClli("clli") + .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() { - return new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service - .endpoint.TxDirectionBuilder().setPort(new PortBuilder().setPortDeviceName("device name") - .setPortName("port name").setPortRack("port rack").setPortShelf("port shelf") - .setPortSlot("port slot").setPortSubSlot("port subslot").setPortType("port type").build()) - .setLgx(new LgxBuilder().setLgxDeviceName("lgx device name").setLgxPortName("lgx port name") - .setLgxPortRack("lgx port rack").setLgxPortShelf("lgx port shelf").build()) + return new TxDirectionBuilder() + .setPort(new PortBuilder() + .setPortDeviceName("device name") + .setPortName("port name") + .setPortRack("port rack") + .setPortShelf("port shelf") + .setPortSlot("port slot") + .setPortSubSlot("port subslot") + .setPortType("port type") + .build()) + .setLgx(new LgxBuilder() + .setLgxDeviceName("lgx device name") + .setLgxPortName("lgx port name") + .setLgxPortRack("lgx port rack") + .setLgxPortShelf("lgx port shelf") + .build()) + .setIndex(Uint8.ZERO) .build(); } private RxDirection getRxDirection() { - return new org.opendaylight.yang.gen.v1.http.org.openroadm.common.service.types.rev190531.service - .endpoint.RxDirectionBuilder() - .setPort(new PortBuilder().setPortDeviceName("device name").setPortName("port name") - .setPortRack("port rack").setPortShelf("port shelf").setPortSlot("port slot") - .setPortSubSlot("port subslot").setPortType("port type").build()) - .setLgx(new LgxBuilder().setLgxDeviceName("lgx device name") - .setLgxPortName("lgx port name").setLgxPortRack("lgx port rack") - .setLgxPortShelf("lgx port shelf").build()) + return new RxDirectionBuilder() + .setPort(new PortBuilder() + .setPortDeviceName("device name") + .setPortName("port name") + .setPortRack("port rack") + .setPortShelf("port shelf") + .setPortSlot("port slot") + .setPortSubSlot("port subslot") + .setPortType("port type") + .build()) + .setLgx(new LgxBuilder() + .setLgxDeviceName("lgx device name") + .setLgxPortName("lgx port name") + .setLgxPortRack("lgx port rack") + .setLgxPortShelf("lgx port shelf") + .build()) + .setIndex(Uint8.ZERO) .build(); } @@ -190,7 +314,7 @@ public class ServiceListenerTest { .setConnectionType(ConnectionType.Service) .setMessage(message) .setOperationalState(services.getOperationalState()) - .setTopic("ServiceListener") + .setPublisherName("ServiceListener") .build(); } -} +} \ No newline at end of file