package de.is24.util.monitoring;
import de.is24.util.monitoring.jmx.JmxAppMon4JNamingStrategy;
import de.is24.util.monitoring.keyhandler.DefaultKeyEscaper;
import org.fest.assertions.Assertions;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import static de.is24.util.monitoring.TestHelper.initializeWithJMXNaming;
import static org.fest.assertions.Assertions.assertThat;
public class InApplicationMonitorTest {
private static final String INITIALIZED_COUNTER_1 = "initialized.counter.1";
@Before
public void setupClass() {
TestingInApplicationMonitor.resetInstanceForTesting();
}
@Test
public void explicitInitializationShouldKeepInApplicationMonitorInstance() {
// given a default configured InApplication Monitor
InApplicationMonitor defaultInstance = InApplicationMonitor.getInstance();
// when explicitly initializing InApplicationMonitor
initializeWithJMXNaming();
// then the new CorePlugin Instance is used
Assertions.assertThat(InApplicationMonitor.getInstance()).isSameAs(defaultInstance);
}
@Test
public void explicitInitializationShouldSetCorePlugin() {
// given a default configured InApplication Monitor with a counter added
InApplicationMonitor.getInstance().initializeCounter(INITIALIZED_COUNTER_1);
// when explicitly initializing InApplicationMonitor
DefaultKeyEscaper keyEscaper = new DefaultKeyEscaper();
CorePlugin corePlugin = new CorePlugin(new JmxAppMon4JNamingStrategy() {
@Override
public String getJmxPrefix() {
return "lala";
}
}, keyEscaper);
InApplicationMonitor explicitInitializedInApplicationMonitor = InApplicationMonitor.initInstance(
corePlugin, keyEscaper);
// then the new CorePlugin Instance is used
Assertions.assertThat(explicitInitializedInApplicationMonitor.getCorePlugin()).isSameAs(corePlugin);
}
@Test
public void explicitInitializationShouldTakeOverInitializedCountersAndTimersIntoCorePlugin() {
// given a default configured InApplication Monitor with a counter added
InApplicationMonitor.getInstance().initializeCounter(INITIALIZED_COUNTER_1);
// when explicitly initializing InApplicationMonitor
CorePlugin corePlugin = initializeWithJMXNaming();
// then
CheckCounterVisitor reportVisitor = new CheckCounterVisitor(
INITIALIZED_COUNTER_1);
corePlugin.reportInto(reportVisitor);
assertThat(reportVisitor.isFound()).isTrue();
}
@Test
public void explicitInitializationShouldTakeOverInitializedCountersAndTimersIntoJMX() {
// given a default configured InApplication Monitor with a counter added
InApplicationMonitor.getInstance().initializeCounter(INITIALIZED_COUNTER_1);
// when explicitly initializing InApplicationMonitor
initializeWithJMXNaming();
// then
Assertions.assertThat(JMXTestHelper.getCounterValue("lala", INITIALIZED_COUNTER_1)).isEqualTo(0);
}
@Test
public void explicitInitializationWithJMXNamingStrategyShouldInitializeJMX() {
// given a default configured InApplication Monitor
InApplicationMonitor.getInstance();
// when explicitly initializing InApplicationMonitor
initializeWithJMXNaming();
// then
Assertions.assertThat(JMXTestHelper.checkInApplicationMonitorJMXBeanRegistered("lala")).isEqualTo(true);
}
@Test
public void allowThreadLocalStateValuesForTesting() throws Exception {
final String threadTestGlobalValue = "threadTestGlobalValue";
ExecutorService executorService = new ScheduledThreadPoolExecutor(1);
try {
// This future represents another thread registering a State Value after the parent thread
// set itself to use the thread local state, and check that it all the time sees the right
// state value while the parent thread does his testing.
Future<Boolean> task = executorService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
boolean result;
try {
//wait until parent thread has set up thread local State
Thread.sleep(10);
// than register stateValue with same name
InApplicationMonitor.getInstance()
.registerStateValue(new SimpleStateValueProvider(threadTestGlobalValue, 11L));
result = InApplicationMonitor.getInstance()
.getCorePlugin()
.getStateValue(threadTestGlobalValue)
.getValue() == 11L;
Thread.sleep(20);
} catch (InterruptedException e) {
result = false;
}
// and check again after reset
result = result &&
(InApplicationMonitor.getInstance().getCorePlugin().getStateValue(threadTestGlobalValue).getValue() ==
11L);
return result;
}
});
// switch this thread to local State, and register the same state value as the future Task thread will do
InApplicationMonitor.getInstance().setThreadLocalState();
InApplicationMonitor.getInstance().registerStateValue(new SimpleStateValueProvider(threadTestGlobalValue, 110L));
// wait until future thread (hopefully) has registered his state value
Thread.sleep(15);
// check that we see our local state value
Assertions.assertThat(InApplicationMonitor.getInstance()
.getCorePlugin()
.getStateValue(threadTestGlobalValue)
.getValue())
.isEqualTo(110L);
InApplicationMonitor.getInstance().resetThreadLocalState();
assertThat(task.get()).isTrue();
} finally {
InApplicationMonitor.getInstance().resetThreadLocalState();
}
}
@Test
public void resetInstanceInOtherThreadShouldNotAffectThreadLocalStateValues() throws Exception {
final String threadTestGlobalValue = "threadTestGlobalValue";
String threadTestLocalValue = "threadTestLocalValue";
try {
InApplicationMonitor.getInstance().setThreadLocalState();
InApplicationMonitor.getInstance().registerStateValue(new SimpleStateValueProvider(threadTestGlobalValue, 110L));
InApplicationMonitor.getInstance().registerStateValue(new SimpleStateValueProvider(threadTestLocalValue, 1100L));
Thread thread = new Thread() {
@Override
public void run() {
TestingInApplicationMonitor.resetInstanceForTesting();
}
};
thread.start();
Thread.sleep(10);
Assertions.assertThat(InApplicationMonitor.getInstance()
.getCorePlugin()
.getStateValue(threadTestGlobalValue)
.getValue())
.isEqualTo(110L);
} finally {
InApplicationMonitor.getInstance().resetThreadLocalState();
}
}
}