Added:
/parfait-core/src/test/java/com/custardsource/parfait/timing/EventMetricCollectorTest.java
Modified:
/parfait-core/src/main/java/com/custardsource/parfait/timing/EventMetricCollector.java
=======================================
--- /dev/null
+++
/parfait-core/src/test/java/com/custardsource/parfait/timing/EventMetricCollectorTest.java
Tue May 31 17:57:32 2011
@@ -0,0 +1,82 @@
+package com.custardsource.parfait.timing;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class EventMetricCollectorTest {
+
+ private static final String TOP_LEVEL_GROUP = "eventGroup1";
+ private static final String NESTED_GROUP = "eventGroup2";
+
+ private EventMetricCollector collector;
+ @Mock
+ private StepMeasurementSink stepMeasurementSink;
+ @Mock
+ private EventCounters topLevelCounter;
+ @Mock
+ private EventCounters nestedCounter;
+ @Mock
+ private EventMetricCounters topLevelMetricCounters;
+
+ @Before
+ public void givenAnEventMetricCollector() {
+ MockitoAnnotations.initMocks(this);
+
+ Map<Object, EventCounters> perEventCounters = Maps.newHashMap();
+ perEventCounters.put(TOP_LEVEL_GROUP, topLevelCounter);
+ perEventCounters.put(NESTED_GROUP, nestedCounter);
+ collector = new EventMetricCollector(perEventCounters,
newArrayList(stepMeasurementSink));
+
+
when(topLevelCounter.getEventGroupName()).thenReturn(TOP_LEVEL_GROUP);
+ when(nestedCounter.getEventGroupName()).thenReturn(NESTED_GROUP);
+ EventMetricCounters invocationCounter =
mock(EventMetricCounters.class);
+
when(topLevelCounter.getInvocationCounter()).thenReturn(invocationCounter);
+ ThreadMetric threadMetric = mock(ThreadMetric.class);
+
when(topLevelCounter.getMetricSources()).thenReturn(newArrayList(threadMetric));
+
when(topLevelCounter.getCounterForMetric(threadMetric)).thenReturn(topLevelMetricCounters);
+ }
+
+ @Test
+ public void itShouldIncrementCountersForSingleCollectors() {
+ collector.startTiming(TOP_LEVEL_GROUP, "topLevelEvent");
+ collector.stopTiming();
+
+
verify(topLevelCounter).getCounterForMetric(any(ThreadMetric.class));
+ verify(topLevelMetricCounters).incrementCounters(anyLong());
+ }
+
+ @Test
+ public void itShouldIncrementTopLevelCountersForNestedCollectors() {
+ collector.startTiming(TOP_LEVEL_GROUP, "topLevelEvent");
+ collector.startTiming(NESTED_GROUP, "nestedEvent");
+ collector.stopTiming();
+ collector.stopTiming();
+
+
verify(topLevelCounter).getCounterForMetric(any(ThreadMetric.class));
+ verify(topLevelMetricCounters).incrementCounters(anyLong());
+ }
+
+ @Test
+ public void itShouldNotIncrementNestedCountersForNestedCollectors() {
+ collector.startTiming(TOP_LEVEL_GROUP, "topLevelEvent");
+ collector.startTiming(NESTED_GROUP, "nestedEvent");
+ collector.stopTiming();
+ collector.stopTiming();
+
+ verify(nestedCounter,
never()).getCounterForMetric(any(ThreadMetric.class));
+ }
+
+}
=======================================
---
/parfait-core/src/main/java/com/custardsource/parfait/timing/EventMetricCollector.java
Thu Dec 16 00:06:37 2010
+++
/parfait-core/src/main/java/com/custardsource/parfait/timing/EventMetricCollector.java
Tue May 31 17:57:32 2011
@@ -1,5 +1,7 @@
package com.custardsource.parfait.timing;
+import java.util.ArrayDeque;
+import java.util.Deque;
import java.util.List;
import java.util.Map;
@@ -22,7 +24,7 @@
* the top-level event requested by the user.
*/
private int depth = 0;
- private Object topLevelEvent;
+ private Deque<Object> topLevelEvent = new ArrayDeque<Object>();
private final Map<Object, EventCounters> perEventCounters;
private final List<StepMeasurementSink> sinks;
@@ -41,7 +43,7 @@
newTiming.addMetricInstance(new MetricMeasurement(metric,
Thread.currentThread()));
}
current = newTiming;
- topLevelEvent = eventGroup;
+ topLevelEvent.addFirst(eventGroup);
depth++;
if (top == null) {
top = newTiming;
@@ -52,14 +54,15 @@
public void stopTiming() {
current.stopAll();
depth--;
+ Object event = topLevelEvent.removeFirst();
for (StepMeasurementSink sink : sinks) {
sink.handle(current, depth);
}
- if (depth == 0 && perEventCounters.containsKey(topLevelEvent)) {
+ if (depth == 0 && perEventCounters.containsKey(event)) {
// We're at the top level, increment our event counters too
- EventCounters counters = perEventCounters.get(topLevelEvent);
+ EventCounters counters = perEventCounters.get(event);
for (MetricMeasurement metric : current.getMetricInstances()) {
EventMetricCounters counter =
counters.getCounterForMetric(metric
.getMetricSource());