package rocks.inspectit.agent.java.analyzer.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.mockito.InjectMocks;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.slf4j.Logger;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.esotericsoftware.kryo.io.Input;
import rocks.inspectit.agent.java.config.IConfigurationStorage;
import rocks.inspectit.agent.java.io.FileResolver;
import rocks.inspectit.agent.java.spring.PrototypesProvider;
import rocks.inspectit.shared.all.instrumentation.config.impl.InstrumentationDefinition;
import rocks.inspectit.shared.all.serializer.SerializationException;
import rocks.inspectit.shared.all.serializer.impl.SerializationManager;
import rocks.inspectit.shared.all.testbase.TestBase;
@SuppressWarnings("PMD")
public class ClassHashHelperTest extends TestBase {
protected static final String TEST_CACHE_FILE = "test.cache";
@InjectMocks
ClassHashHelper helper;
@Mock
Logger log;
@Mock
IConfigurationStorage configurationStorage;
@Mock
PrototypesProvider prototypesProvider;
@Mock
SerializationManager serializationManager;
@Mock
ScheduledExecutorService executorService;
@Mock
FileResolver fileResolver;
@BeforeMethod
public void setup() {
doReturn(new File(TEST_CACHE_FILE)).when(fileResolver).getClassHashCacheFile();
when(prototypesProvider.createSerializer()).thenReturn(serializationManager);
}
@AfterMethod
public void delete() {
File file = new File(TEST_CACHE_FILE);
if (file.exists()) {
assertThat(file.delete(), is(true));
}
}
public class AfterPropertiesSet extends ClassHashHelperTest {
@Test
public void noCacheFileExists() throws Exception {
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(true);
helper.afterPropertiesSet();
verify(prototypesProvider, times(1)).createSerializer();
verify(executorService, times(1)).scheduleAtFixedRate(Matchers.<Runnable> any(), anyLong(), anyLong(), Matchers.<TimeUnit> any());
verifyZeroInteractions(serializationManager);
assertThat(helper.isEmpty(), is(true));
}
@Test
public void cacheFileExists() throws Exception {
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(true);
new File(TEST_CACHE_FILE).createNewFile();
Object hashes = Collections.singletonMap("fqn", Collections.singleton("hash"));
when(serializationManager.deserialize(Matchers.<Input> any())).thenReturn(hashes);
helper.afterPropertiesSet();
verify(prototypesProvider, times(1)).createSerializer();
verify(serializationManager, times(1)).deserialize(Matchers.<Input> any());
verify(executorService, times(1)).scheduleAtFixedRate(Matchers.<Runnable> any(), anyLong(), anyLong(), Matchers.<TimeUnit> any());
assertThat(helper.isEmpty(), is(false));
}
@Test
public void cacheFileExistsException() throws Exception {
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(true);
new File(TEST_CACHE_FILE).createNewFile();
when(serializationManager.deserialize(Matchers.<Input> any())).thenThrow(new SerializationException());
helper.afterPropertiesSet();
verify(prototypesProvider, times(1)).createSerializer();
verify(executorService, times(1)).scheduleAtFixedRate(Matchers.<Runnable> any(), anyLong(), anyLong(), Matchers.<TimeUnit> any());
assertThat(helper.isEmpty(), is(true));
}
@Test
public void cacheFileExistsCacheOnCmrNot() throws Exception {
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(false);
new File(TEST_CACHE_FILE).createNewFile();
Object hashes = Collections.singleton("hash");
when(serializationManager.deserialize(Matchers.<Input> any())).thenReturn(hashes);
helper.afterPropertiesSet();
verify(executorService, times(1)).scheduleAtFixedRate(Matchers.<Runnable> any(), anyLong(), anyLong(), Matchers.<TimeUnit> any());
assertThat(helper.isEmpty(), is(true));
assertThat(new File(TEST_CACHE_FILE).exists(), is(false));
verifyZeroInteractions(serializationManager);
}
@Test
public void initialInstrumentationPoints() throws Exception {
String fqn = "fqn";
String hash = "hash";
InstrumentationDefinition instrumentationResult = mock(InstrumentationDefinition.class);
Map<Collection<String>, InstrumentationDefinition> initInstrumentations = Collections.<Collection<String>, InstrumentationDefinition> singletonMap(Collections.singleton(hash),
instrumentationResult);
when(instrumentationResult.getClassName()).thenReturn(fqn);
when(configurationStorage.getInitialInstrumentationResults()).thenReturn(initInstrumentations);
helper.afterPropertiesSet();
assertThat(helper.isEmpty(), is(false));
assertThat(helper.isSent(fqn, hash), is(true));
assertThat(helper.getInstrumentationDefinition(fqn), is(instrumentationResult));
}
@Test
public void noInitialInstrumentationPoints() throws Exception {
when(configurationStorage.getInitialInstrumentationResults()).thenReturn(Collections.<Collection<String>, InstrumentationDefinition> emptyMap());
helper.afterPropertiesSet();
assertThat(helper.isEmpty(), is(true));
}
}
public class RegisterAnalyzed extends ClassHashHelperTest {
@Test
public void register() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
helper.registerAnalyzed(fqn);
boolean analyzed = helper.isAnalyzed(fqn);
assertThat(analyzed, is(true));
}
}
public class IsAnalyzed extends ClassHashHelperTest {
@Test
public void notAnalzyed() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
boolean analyzed = helper.isAnalyzed(fqn);
assertThat(analyzed, is(false));
}
@Test
public void load() throws Exception {
String fqn = "fqn";
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(true);
new File(TEST_CACHE_FILE).createNewFile();
Object hashes = Collections.singletonMap(fqn, Collections.emptyList());
when(serializationManager.deserialize(Matchers.<Input> any())).thenReturn(hashes);
helper.afterPropertiesSet();
boolean analyzed = helper.isAnalyzed(fqn);
assertThat(analyzed, is(true));
}
}
public class RegisterInstrumentationDefinition extends ClassHashHelperTest {
@Test
public void register() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
InstrumentationDefinition definition = mock(InstrumentationDefinition.class);
helper.registerInstrumentationDefinition(fqn, definition);
InstrumentationDefinition fromCache = helper.getInstrumentationDefinition(fqn);
assertThat(fromCache, is(definition));
}
}
public class GetInstrumentationDefinition extends ClassHashHelperTest {
@Test
public void notRegistered() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
InstrumentationDefinition definition = helper.getInstrumentationDefinition(fqn);
assertThat(definition, is(nullValue()));
}
@Test
public void saveAndLoad() throws Exception {
String fqn = "fqn";
InstrumentationDefinition definition = mock(InstrumentationDefinition.class);
helper.registerInstrumentationDefinition(fqn, definition);
helper.destroy();
helper.afterPropertiesSet();
InstrumentationDefinition fromCache = helper.getInstrumentationDefinition(fqn);
assertThat(fromCache, is(nullValue()));
}
}
public class RegisterSent extends ClassHashHelperTest {
@Test
public void register() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
String hash = "hash";
helper.registerSent(fqn, hash);
boolean sent = helper.isSent(fqn, hash);
assertThat(sent, is(true));
}
}
public class IsSent extends ClassHashHelperTest {
@Test
public void notSent() throws Exception {
helper.afterPropertiesSet();
String fqn = "fqn";
String hash = "hash";
boolean sent = helper.isSent(fqn, hash);
assertThat(sent, is(false));
}
@Test
public void load() throws Exception {
String fqn = "fqn";
String hash = "hash";
when(configurationStorage.isClassCacheExistsOnCmr()).thenReturn(true);
new File(TEST_CACHE_FILE).createNewFile();
Object hashes = Collections.singletonMap(fqn, Collections.singleton(hash));
when(serializationManager.deserialize(Matchers.<Input> any())).thenReturn(hashes);
helper.afterPropertiesSet();
boolean sent = helper.isSent(fqn, hash);
assertThat(sent, is(true));
}
}
}