1package org.robolectric.util;
2
3import static org.assertj.core.api.Assertions.assertThat;
4import static org.junit.Assert.fail;
5
6import java.io.IOException;
7import java.util.Collection;
8import org.junit.Before;
9import org.junit.Test;
10import org.junit.runner.RunWith;
11import org.junit.runners.JUnit4;
12import org.robolectric.util.PerfStatsCollector.Event;
13import org.robolectric.util.PerfStatsCollector.Metric;
14
15@RunWith(JUnit4.class)
16public class PerfStatsCollectorTest {
17
18  private FakeClock fakeClock;
19  private PerfStatsCollector collector;
20
21  @Before
22  public void setUp() throws Exception {
23    fakeClock = new FakeClock();
24    collector = new PerfStatsCollector(fakeClock);
25  }
26
27  @Test
28  public void shouldMeasureElapsedTimeForEvents() throws Exception {
29    Event firstEvent = collector.startEvent("first event");
30    fakeClock.delay(20);
31    firstEvent.finished();
32
33    Collection<Metric> metrics = collector.getMetrics();
34    assertThat(metrics).containsExactly(
35        new Metric("first event", 1, 20, true)
36    );
37  }
38
39  @Test
40  public void shouldMeasureElapsedTimeForRepeatedEvents() throws Exception {
41    Event firstEvent = collector.startEvent("repeatable event");
42    fakeClock.delay(20);
43    firstEvent.finished();
44
45    Event secondEvent = collector.startEvent("repeatable event");
46    fakeClock.delay(20);
47    secondEvent.finished();
48
49    Event thirdEvent = collector.startEvent("repeatable event");
50    fakeClock.delay(20);
51    thirdEvent.finished();
52
53    Collection<Metric> metrics = collector.getMetrics();
54    assertThat(metrics).containsExactly(
55        new Metric("repeatable event", 3, 60, true)
56    );
57  }
58
59  @Test
60  public void shouldRunAndMeasureSuccessfulCallable() throws Exception {
61    assertThat(collector.measure("event", () -> {
62      fakeClock.delay(10);
63      return "return value";
64    })).isEqualTo("return value");
65
66    Collection<Metric> metrics = collector.getMetrics();
67    assertThat(metrics).containsExactly(new Metric("event", 1, 10, true));
68  }
69
70  @Test
71  public void shouldRunAndMeasureExceptionThrowingCallable() throws Exception {
72    collector.measure("event", () -> {
73      fakeClock.delay(10);
74      return "return value";
75    });
76
77    try {
78      collector.measure("event", () -> {
79        fakeClock.delay(5);
80        throw new RuntimeException("fake");
81      });
82      fail("should have thrown");
83    } catch (RuntimeException e) {
84      assertThat(e.getMessage()).isEqualTo("fake");
85    }
86
87    Collection<Metric> metrics = collector.getMetrics();
88    assertThat(metrics).containsExactlyInAnyOrder(
89        new Metric("event", 1, 10, true),
90        new Metric("event", 1, 5, false));
91  }
92
93  @Test
94  public void shouldRunAndMeasureCheckedException() throws Exception {
95    try {
96      collector.measure("event", () -> {
97        fakeClock.delay(5);
98        throw new IOException("fake");
99      });
100      fail("should have thrown");
101    } catch (IOException e) {
102      assertThat(e.getMessage()).isEqualTo("fake");
103    }
104
105    Collection<Metric> metrics = collector.getMetrics();
106    assertThat(metrics).containsExactlyInAnyOrder(
107        new Metric("event", 1, 5, false));
108  }
109
110  @Test
111  public void reset_shouldClearAllMetadataAndMetrics() throws Exception {
112    collector.putMetadata(String.class, "metadata");
113    collector.startEvent("event").finished();
114    collector.reset();
115    assertThat(collector.getMetadata().get(String.class)).isNull();
116    assertThat(collector.getMetrics()).isEmpty();
117  }
118
119  private static class FakeClock implements Clock {
120
121    private int timeNs = 0;
122
123    @Override
124    public long nanoTime() {
125      return timeNs;
126    }
127
128    public void delay(int ms) {
129      timeNs += ms;
130    }
131  }
132}
133