/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.workbench.common.screens.datasource.management.backend;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.enterprise.inject.spi.BeanManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceDefDeployer;
import org.kie.workbench.common.screens.datasource.management.backend.core.DataSourceRuntimeManager;
import org.kie.workbench.common.screens.datasource.management.backend.core.DefaultDriverInitializer;
import org.kie.workbench.common.screens.datasource.management.backend.core.DriverDefDeployer;
import org.kie.workbench.common.screens.datasource.management.backend.core.impl.DataSourceRuntimeManagerImpl;
import org.kie.workbench.common.screens.datasource.management.backend.service.DefChangeHandler;
import org.kie.workbench.common.screens.datasource.management.backend.service.DefResourceChangeObserver;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith(MockitoJUnitRunner.class)
public class DataSourceManagementBootstrapTest {
private static final long RETRIES = 15;
private static final long DELAY = 1000;
private static final String DEF_CHANGE_HANDLER_BEAN_NAME = "DEF_CHANGE_HANDLER_BEAN_NAME";
@Mock
private DataSourceRuntimeManager dataSourceRuntimeManager;
@Mock
private DataSourceDefDeployer dataSourceDefDeployer;
@Mock
private DriverDefDeployer driverDefDeployer;
@Mock
private DefaultDriverInitializer driverInitializer;
@Mock
private DefResourceChangeObserver defResourceChangeObserver;
@Mock
private BeanManager beanManager;
private DataSourceManagementBootstrap dataSourceManagementBootstrap;
@Mock
private DefChangeHandler defChangeHandler;
@Mock
private ScheduledExecutorService scheduler;
private long dataSourceRuntimeMangerHasStartedFailures = -1;
@Before
public void setUp() throws Exception {
System.getProperties().setProperty(DataSourceManagementBootstrap.DEPLOYMENTS_INITIALIZATION_DELAY,
Long.toString(DELAY));
System.getProperties().setProperty(DataSourceManagementBootstrap.DEPLOYMENTS_INITIALIZATION_RETRIES,
Long.toString(RETRIES));
System.getProperties().setProperty(DataSourceManagementBootstrap.DEF_CHANGE_HANDLER_BEAN,
DEF_CHANGE_HANDLER_BEAN_NAME);
dataSourceRuntimeMangerHasStartedFailures = -1;
dataSourceRuntimeManager = spy(new DataSourceRuntimeManagerImpl() {
int failures = 0;
@Override
public void hasStarted() throws Exception {
if (failures++ < dataSourceRuntimeMangerHasStartedFailures) {
//make the initialization check fail the desired number of times.
throw new RuntimeException("Data source runtime manager has not started yet.");
}
}
});
dataSourceManagementBootstrap = new DataSourceManagementBootstrap(dataSourceRuntimeManager,
dataSourceDefDeployer,
driverDefDeployer,
driverInitializer,
defResourceChangeObserver,
beanManager) {
{
super.scheduler.shutdown();
super.scheduler = DataSourceManagementBootstrapTest.this.scheduler;
}
@Override
protected DefChangeHandler getDefChangeHandler(String defChangeHandlerName) {
return DEF_CHANGE_HANDLER_BEAN_NAME.equals(defChangeHandlerName) ? defChangeHandler : null;
}
};
}
@Test
public void testInitializeConfigParams() throws Exception {
dataSourceManagementBootstrap.init();
assertEquals(DELAY,
dataSourceManagementBootstrap.deploymentsInitializationDelay);
assertEquals(RETRIES,
dataSourceManagementBootstrap.deploymentsInitializationRetries);
}
@Test
public void testInitializeDefChangeHandler() {
dataSourceManagementBootstrap.init();
verify(defResourceChangeObserver,
times(1)).setDefChangeHandler(defChangeHandler);
}
@Test
public void testInitializeDefaultDrivers() {
dataSourceManagementBootstrap.init();
verify(driverInitializer,
times(1)).initializeDefaultDrivers();
}
@Test
public void testInitializeDeploymentsOKWithNoRetries() throws Exception {
//initialization works well at the first try.
prepareExecutor();
dataSourceManagementBootstrap.init();
verify(scheduler,
times(1)).schedule(any(Runnable.class),
eq(DELAY),
eq(TimeUnit.MILLISECONDS));
verify(dataSourceRuntimeManager,
times(1)).hasStarted();
verify(driverDefDeployer,
times(1)).deployGlobalDefs();
verify(dataSourceDefDeployer,
times(1)).deployGlobalDefs();
verify(scheduler,
times(1)).shutdown();
}
@Test
public void testInitializeDeploymentsOKWithRetries() throws Exception {
prepareExecutor();
//let the hasStarted check fail a desired number of times.
dataSourceRuntimeMangerHasStartedFailures = 4;
dataSourceManagementBootstrap.init();
verify(scheduler,
times(1 + (int) dataSourceRuntimeMangerHasStartedFailures))
.schedule(any(Runnable.class),
eq(DELAY),
eq(TimeUnit.MILLISECONDS));
verify(dataSourceRuntimeManager,
times(1 + (int) dataSourceRuntimeMangerHasStartedFailures)).hasStarted();
//after the programmed number of failures the initialization works well.
verify(driverDefDeployer,
times(1)).deployGlobalDefs();
verify(dataSourceDefDeployer,
times(1)).deployGlobalDefs();
verify(scheduler,
times(1)).shutdown();
}
@Test
public void testInitializeDeploymentsExceededTheRetries() throws Exception {
//initialization works well at the first M retry.
prepareExecutor();
//let the hasStarted check fail for all the retries.
dataSourceRuntimeMangerHasStartedFailures = RETRIES;
dataSourceManagementBootstrap.init();
verify(scheduler,
times((int) RETRIES))
.schedule(any(Runnable.class),
eq(DELAY),
eq(TimeUnit.MILLISECONDS));
verify(dataSourceRuntimeManager,
times((int) RETRIES)).hasStarted();
//all the retries were consumed, and the deployments where never invoked.
verify(driverDefDeployer,
never()).deployGlobalDefs();
verify(dataSourceDefDeployer,
never()).deployGlobalDefs();
verify(scheduler,
times(1)).shutdown();
}
@Test
public void testDestroyWhenTasksRunning() {
dataSourceManagementBootstrap.init();
when(scheduler.isShutdown()).thenReturn(false);
dataSourceManagementBootstrap.destroy();
verify(scheduler,
times(1)).shutdownNow();
}
@Test
public void testDestroyWhenNoTasksRunning() {
dataSourceManagementBootstrap.init();
when(scheduler.isShutdown()).thenReturn(true);
dataSourceManagementBootstrap.destroy();
verify(scheduler,
never()).shutdownNow();
}
private void prepareExecutor() {
doAnswer(new Answer< Void >() {
public Void answer(InvocationOnMock invocation) {
Runnable runnable = (Runnable) invocation.getArguments()[0];
runnable.run();
return null;
}
}).when(scheduler).schedule(any(Runnable.class),
eq(DELAY),
eq(TimeUnit.MILLISECONDS));
}
}