/** * Copyright (c) Codice Foundation * <p> * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser * General Public License as published by the Free Software Foundation, either version 3 of the * License, or any later version. * <p> * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.ddf.registry.api.impl; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Dictionary; import java.util.Hashtable; import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.codice.ddf.registry.api.internal.RegistryStore; import org.codice.ddf.registry.common.metacard.RegistryObjectMetacardType; import org.codice.ddf.registry.federationadmin.service.internal.FederationAdminService; import org.codice.ddf.registry.federationadmin.service.internal.RegistryPublicationService; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceReference; import org.osgi.service.event.Event; import org.osgi.service.event.EventConstants; import ddf.catalog.data.Attribute; import ddf.catalog.data.Metacard; import ddf.catalog.data.impl.AttributeImpl; public class TestRegistryStorePublisher extends RegistryStorePublisher { private static final String PUBLISH = "publish"; private static final String UNPUBLISH = "unpublish"; private RegistryStorePublisher registryStorePublisher; private RegistryPublicationService mockRegPubService; private FederationAdminService mockFedAdminService; private ScheduledExecutorService executorService; private ServiceReference serviceReference; private RegistryStore mockRegistryStore; private Optional<Metacard> optMetacard; private ServiceEvent mockServiceEvent; private BundleContext bundleContext; private Metacard mockIdentity; private Attribute registryId; private Event event; @Before public void setup() { registryId = new AttributeImpl(RegistryObjectMetacardType.REGISTRY_ID, "registryId"); mockRegPubService = mock(RegistryPublicationService.class); mockFedAdminService = mock(FederationAdminService.class); executorService = mock(ScheduledExecutorService.class); serviceReference = mock(ServiceReference.class); mockRegistryStore = mock(RegistryStore.class); mockServiceEvent = mock(ServiceEvent.class); bundleContext = mock(BundleContext.class); mockIdentity = mock(Metacard.class); optMetacard = Optional.of(mockIdentity); registryStorePublisher = spy(new RegistryStorePublisher() { @Override BundleContext getBundleContext() { return bundleContext; } }); registryStorePublisher.setExecutor(executorService); registryStorePublisher.setFederationAdminService(mockFedAdminService); registryStorePublisher.setRegistryPublicationService(mockRegPubService); Dictionary<String, Object> eventProperties = new Hashtable<>(); eventProperties.put(EventConstants.EVENT, mockServiceEvent); eventProperties.put(Constants.SERVICE_PID, "servicePid"); event = new Event("org/osgi/framework/ServiceEvent/MODIFIED", eventProperties); } @Test public void testBindRegistryStoreNoContext() { registryStorePublisher = Mockito.spy(new RegistryStorePublisher()); registryStorePublisher.bindRegistryStore(serviceReference); verify(registryStorePublisher, Mockito.times(0)).registryPublish(any(), anyString()); } @Test public void testBindThenUnbindRegistryStoreAutoPush() { when(bundleContext.getService(any())).thenReturn(mockRegistryStore); when(mockRegistryStore.getConfigurationPid()).thenReturn("configPid"); when(mockRegistryStore.isAvailable(any())).thenReturn(true); when(mockRegistryStore.isAutoPush()).thenReturn(true); when(mockRegistryStore.getRegistryId()).thenReturn("registryId"); registryStorePublisher.bindRegistryStore(serviceReference); registryStorePublisher.unbindRegistryStore(serviceReference); verify(registryStorePublisher, Mockito.times(1)).registryPublish(any(), eq(PUBLISH)); } @Test public void testUnbindRegistryStoreNoContext() { registryStorePublisher = Mockito.spy(new RegistryStorePublisher()); registryStorePublisher.unbindRegistryStore(serviceReference); verify(registryStorePublisher, Mockito.times(0)).registryPublish(any(), eq(UNPUBLISH)); } @Test public void testRegistryPublishFailed() throws Exception { RegistryStoreImpl mockRegistryStoreImpl = mock(RegistryStoreImpl.class); when(mockRegistryStoreImpl.getRegistryId()).thenReturn("registryId"); when(mockFedAdminService.getLocalRegistryIdentityMetacard()).thenReturn(optMetacard); registryStorePublisher.registryPublish(mockRegistryStoreImpl, PUBLISH); verify(mockRegPubService, Mockito.times(0)).publish(any(), any()); } @Test public void testRegistryPublish() throws Exception { when(mockRegistryStore.getRegistryId()).thenReturn("registryId"); when(mockFedAdminService.getLocalRegistryIdentityMetacard()).thenReturn(optMetacard); when(mockIdentity.getAttribute(RegistryObjectMetacardType.REGISTRY_ID)).thenReturn( registryId); setupSerialExecutor(); registryStorePublisher.registryPublish(mockRegistryStore, PUBLISH); verify(mockRegPubService, Mockito.times(1)).publish(any(), any()); } @Test public void testRegistryUnpublishFailed() throws Exception { RegistryStoreImpl mockRegistryStoreImpl = mock(RegistryStoreImpl.class); when(mockRegistryStoreImpl.getRegistryId()).thenReturn("registryId"); when(mockFedAdminService.getLocalRegistryIdentityMetacard()).thenReturn(optMetacard); registryStorePublisher.registryPublish(mockRegistryStoreImpl, UNPUBLISH); verify(mockRegPubService, Mockito.times(0)).unpublish(any(), any()); } @Test public void testRegistryUnpublish() throws Exception { when(mockRegistryStore.getRegistryId()).thenReturn("registryId"); when(mockFedAdminService.getLocalRegistryIdentityMetacard()).thenReturn(optMetacard); when(mockIdentity.getAttribute(RegistryObjectMetacardType.REGISTRY_ID)).thenReturn( registryId); setupSerialExecutor(); registryStorePublisher.registryPublish(mockRegistryStore, UNPUBLISH); verify(mockRegPubService, Mockito.times(1)).unpublish(any(), any()); } @Test public void testRegistryUnpublishNoId() throws Exception { when(mockRegistryStore.getRegistryId()).thenReturn(""); registryStorePublisher.registryPublish(mockRegistryStore, UNPUBLISH); verify(mockRegPubService, Mockito.times(0)).unpublish(any(), any()); } @Test public void testHandleFalseEvent() throws Exception { when(mockServiceEvent.getType()).thenReturn(ServiceEvent.UNREGISTERING); registryStorePublisher.handleEvent(event); verify(mockRegPubService, Mockito.times(0)).publish(any(), any()); } @Test public void testHandleEventNoAction() throws Exception { when(mockServiceEvent.getType()).thenReturn(ServiceEvent.MODIFIED); registryStorePublisher.handleEvent(event); verify(mockRegPubService, Mockito.times(0)).publish(any(), any()); verify(mockRegPubService, Mockito.times(0)).unpublish(any(), any()); } @Test public void testHandleEventPublish() throws Exception { when(mockServiceEvent.getType()).thenReturn(ServiceEvent.MODIFIED); when(bundleContext.getService(any())).thenReturn(mockRegistryStore); when(mockRegistryStore.getConfigurationPid()).thenReturn("servicePid"); when(mockRegistryStore.isAvailable(any())).thenReturn(true); when(mockRegistryStore.isAutoPush()).thenReturn(false); when(mockRegistryStore.getRegistryId()).thenReturn("registryId"); registryStorePublisher.bindRegistryStore(serviceReference); when(mockRegistryStore.isAutoPush()).thenReturn(true); registryStorePublisher.handleEvent(event); verify(registryStorePublisher, Mockito.times(1)).registryPublish(any(), eq(PUBLISH)); } @Test public void testHandleEventUnpublish() throws Exception { when(mockServiceEvent.getType()).thenReturn(ServiceEvent.MODIFIED); when(bundleContext.getService(any())).thenReturn(mockRegistryStore); when(mockRegistryStore.getConfigurationPid()).thenReturn("servicePid"); when(mockRegistryStore.isAvailable(any())).thenReturn(true); when(mockRegistryStore.isAutoPush()).thenReturn(true); when(mockRegistryStore.getRegistryId()).thenReturn("registryId"); registryStorePublisher.bindRegistryStore(serviceReference); when(mockRegistryStore.isAutoPush()).thenReturn(false); registryStorePublisher.handleEvent(event); verify(registryStorePublisher, Mockito.times(1)).registryPublish(any(), eq(PUBLISH)); verify(registryStorePublisher, Mockito.times(1)).registryPublish(any(), eq(UNPUBLISH)); } @Test public void testDestroy() throws Exception { when(executorService.awaitTermination(anyLong(), any(TimeUnit.class))).thenReturn(true); registryStorePublisher.destroy(); verify(executorService, times(1)).awaitTermination(anyLong(), any(TimeUnit.class)); verify(executorService, times(0)).shutdownNow(); } @Test public void testDestroyTerminateTasks() throws Exception { when(executorService.awaitTermination(anyLong(), any(TimeUnit.class))).thenReturn(false); registryStorePublisher.destroy(); verify(executorService, times(2)).awaitTermination(anyLong(), any(TimeUnit.class)); verify(executorService, times(1)).shutdownNow(); } @Test public void testDestroyInterupt() throws Exception { when(executorService.awaitTermination(anyLong(), any(TimeUnit.class))).thenThrow(new InterruptedException("interrupt")); registryStorePublisher.destroy(); verify(executorService, times(1)).awaitTermination(anyLong(), any(TimeUnit.class)); verify(executorService, times(1)).shutdownNow(); } private void setupSerialExecutor() { doAnswer((args) -> { ((Runnable) args.getArguments()[0]).run(); return null; }).when(executorService) .schedule(isA(Runnable.class), anyLong(), any()); } }