package com.google.sitebricks.stat;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.sitebricks.stat.testservices.ChildDummyService;
import com.google.sitebricks.stat.testservices.DummyService;
import com.google.sitebricks.stat.testservices.StatExposerTestingService;
import com.google.sitebricks.stat.testservices.StaticDummyService;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import static org.testng.Assert.assertEquals;
/**
* @author dhanji@gmail.com (Dhanji R. Prasanna)
*/
public class StatsIntegrationTest {
Injector injector;
@BeforeMethod
public final void before() {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
install(new StatModule("/stat"));
bind(DummyService.class);
bind(ChildDummyService.class);
bind(StatExposerTestingService.class);
}
});
}
@Test
public final void testPublishingStatsInDummyService() {
DummyService service = injector.getInstance(DummyService.class);
service.call();
service.call();
service.call();
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
assertEquals(snapshot.size(), 2);
// Here we check the value of the field, NUMBER_OF_CALLS
StatDescriptor numberOfCallsDescriptor =
getByName(DummyService.NUMBER_OF_CALLS, snapshot);
String numberOfCallsValue = (String) snapshot.get(numberOfCallsDescriptor);
assertEquals(String.valueOf(service.getCalls()), numberOfCallsValue);
// Here we check the value of the method, CALL_LATENCY_NS
StatDescriptor callLatencyNsDescriptor =
getByName(DummyService.CALL_LATENCY_NS, snapshot);
String callLatencyValue = (String) snapshot.get(callLatencyNsDescriptor);
assertEquals(service.getCallLatencyMs().toString(), callLatencyValue);
}
/**
* This test illustrates how stats are published from parent classes when
* a child class is published.
*/
@Test public void testPublishingStatsInChildService() {
ChildDummyService service = injector.getInstance(ChildDummyService.class);
service.call();
service.call();
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
// We expect 1 stat from the child class and 2 from its parent
assertEquals(snapshot.size(), 3);
StatDescriptor numberOfChildCallsDescriptor =
getByName(ChildDummyService.NUMBER_OF_CHILD_CALLS, snapshot);
String numberOfChildCallsValue =
(String) snapshot.get(numberOfChildCallsDescriptor);
assertEquals(
String.valueOf(service.getChildCalls()), numberOfChildCallsValue);
// Below we check the value of the stats on the parent class
StatDescriptor numberOfCallsDescriptor =
getByName(DummyService.NUMBER_OF_CALLS, snapshot);
String numberOfCallsValue = (String) snapshot.get(numberOfCallsDescriptor);
assertEquals(String.valueOf(service.getCalls()), numberOfCallsValue);
StatDescriptor callLatencyNsDescriptor =
getByName(DummyService.CALL_LATENCY_NS, snapshot);
String callLatencyValue = (String) snapshot.get(callLatencyNsDescriptor);
assertEquals(service.getCallLatencyMs().toString(), callLatencyValue);
}
@Test
public void testPublishingStatsAsStaticMember() {
StaticDummyService.reset();
StaticDummyService service1 = injector.getInstance(StaticDummyService.class);
StaticDummyService service2 = injector.getInstance(StaticDummyService.class);
service1.call();
service2.call();
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
assertEquals(snapshot.size(), 1);
StatDescriptor staticCallsDescriptor =
getByName(StaticDummyService.STATIC_CALLS, snapshot);
String numberOfStaticCallsValue =
(String) snapshot.get(staticCallsDescriptor);
assertEquals(
String.valueOf(StaticDummyService.getNumberOfStaticCalls()),
numberOfStaticCallsValue);
}
@Test
public final void testPublishingDuplicatedStat() {
DummyService service1 = injector.getInstance(DummyService.class);
DummyService service2 = injector.getInstance(DummyService.class);
service1.call();
service2.call();
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
assertEquals(2, snapshot.size(), snapshot.toString());
for (Entry<StatDescriptor, Object> entry : snapshot.entrySet()) {
assertEquals(Stats.DUPLICATED_STAT_VALUE, entry.getValue(),
"Unexpected value for " + entry.getKey());
}
}
@SuppressWarnings("unchecked")
@Test
public final void testPublishingUsingDifferentExposers() {
StatExposerTestingService service =
injector.getInstance(StatExposerTestingService.class);
service.call();
service.call();
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
assertEquals(snapshot.size(), 8, "Snapshot has unexpected size: " + snapshot);
AtomicInteger atomicIntegerCallCount = service.getCallCount();
String stringCallCount = String.valueOf(atomicIntegerCallCount);
StatDescriptor callsDefaultExposerDescriptor = getByName(
StatExposerTestingService.CALLS_WITH_DEFAULT_EXPOSER, snapshot);
String callsDefaultExposerValue =
(String) snapshot.get(callsDefaultExposerDescriptor);
assertEquals(stringCallCount, callsDefaultExposerValue);
StatDescriptor callsIdentityExposerDescriptor = getByName(
StatExposerTestingService.CALLS_WITH_IDENTITY_EXPOSER, snapshot);
AtomicInteger callsIdentityExposerValue =
(AtomicInteger) snapshot.get(callsIdentityExposerDescriptor);
assertEquals(atomicIntegerCallCount.get(), callsIdentityExposerValue.get());
StatDescriptor callsInferenceExposerDescriptor = getByName(
StatExposerTestingService.CALLS_WITH_INFERENCE_EXPOSER, snapshot);
String callsInferenceExposerValue =
(String) snapshot.get(callsInferenceExposerDescriptor);
assertEquals(stringCallCount, callsInferenceExposerValue);
StatDescriptor callsToStringExposerDescriptor = getByName(
StatExposerTestingService.CALLS_WITH_TO_STRING_EXPOSER, snapshot);
String callsToStringExposerValue =
(String) snapshot.get(callsToStringExposerDescriptor);
assertEquals(stringCallCount, callsToStringExposerValue);
List<Integer> callsList = service.getCallsList();
String callsListAsString = String.valueOf(callsList);
StatDescriptor listDefaultExposerDescriptor = getByName(
StatExposerTestingService.LIST_WITH_DEFAULT_EXPOSER, snapshot);
List<Integer> listDefaultExposerValue =
(List<Integer>) snapshot.get(listDefaultExposerDescriptor);
assertEquals(callsList, listDefaultExposerValue);
StatDescriptor listIdentityExposerDescriptor = getByName(
StatExposerTestingService.LIST_WITH_IDENTITY_EXPOSER, snapshot);
List<Integer> listIdentityExposerValue =
(List<Integer>) snapshot.get(listIdentityExposerDescriptor);
assertEquals(callsList, listIdentityExposerValue);
StatDescriptor listInferenceExposerDescriptor = getByName(
StatExposerTestingService.LIST_WITH_INFERENCE_EXPOSER, snapshot);
List<Integer> listInferenceExposerValue =
(List<Integer>) snapshot.get(listInferenceExposerDescriptor);
assertEquals(callsList, listInferenceExposerValue);
StatDescriptor listToStringExposerDescriptor = getByName(
StatExposerTestingService.LIST_WITH_TO_STRING_EXPOSER, snapshot);
String listToStringExposerValue =
(String) snapshot.get(listToStringExposerDescriptor);
assertEquals(callsListAsString, listToStringExposerValue);
}
@Test
public final void testPublishingStandaloneStat() {
StatRegistrar statRegistrar = injector.getInstance(StatRegistrar.class);
AtomicInteger statValue = new AtomicInteger(0);
statRegistrar.registerSingleStat("single-stat", "", statValue);
Stats stats = injector.getInstance(Stats.class);
ImmutableMap<StatDescriptor, Object> snapshot = stats.snapshot();
StatDescriptor numberOfChildCallsDescriptor =
getByName("single-stat", snapshot);
String snapshottedValue =
(String) snapshot.get(numberOfChildCallsDescriptor);
assertEquals(String.valueOf(statValue.intValue()), snapshottedValue);
}
StatDescriptor getByName(
String name, ImmutableMap<StatDescriptor, Object> snapshot) {
for (StatDescriptor key : snapshot.keySet()) {
if (key.getName().equals(name)) {
return key;
}
}
throw new RuntimeException(
"No entry found for " + name + " within " + snapshot);
}
}