PerformanceCollectorTest.java revision 1a44d5dcabc18cd5ef111f732ccff91683a1a093
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.os;
18
19import android.os.Bundle;
20import android.os.Parcelable;
21import android.os.PerformanceCollector;
22import android.os.Process;
23import android.os.PerformanceCollector.PerformanceResultsWriter;
24import android.test.suitebuilder.annotation.SmallTest;
25
26import java.lang.reflect.Field;
27import java.util.ArrayList;
28import java.util.Random;
29
30import junit.framework.TestCase;
31
32public class PerformanceCollectorTest extends TestCase {
33
34    private PerformanceCollector mPerfCollector;
35
36    @Override
37    protected void setUp() throws Exception {
38        super.setUp();
39        mPerfCollector = new PerformanceCollector();
40    }
41
42    @Override
43    protected void tearDown() throws Exception {
44        super.tearDown();
45        mPerfCollector = null;
46    }
47
48    @SmallTest
49    public void testBeginSnapshotNoWriter() throws Exception {
50        mPerfCollector.beginSnapshot("testBeginSnapshotNoWriter");
51
52        assertTrue((Long)readPrivateField("mSnapshotCpuTime", mPerfCollector) > 0);
53        assertTrue((Long)readPrivateField("mSnapshotExecTime", mPerfCollector) > 0);
54        Bundle snapshot = (Bundle)readPrivateField("mPerfSnapshot", mPerfCollector);
55        assertNotNull(snapshot);
56        assertEquals(2, snapshot.size());
57    }
58
59    @SmallTest
60    public void testEndSnapshotNoWriter() throws Exception {
61        mPerfCollector.beginSnapshot("testEndSnapshotNoWriter");
62        workForRandomLongPeriod();
63        Bundle snapshot = mPerfCollector.endSnapshot();
64
65        verifySnapshotBundle(snapshot);
66    }
67
68    @SmallTest
69    public void testStartTimingNoWriter() throws Exception {
70        mPerfCollector.startTiming("testStartTimingNoWriter");
71
72        assertTrue((Long)readPrivateField("mCpuTime", mPerfCollector) > 0);
73        assertTrue((Long)readPrivateField("mExecTime", mPerfCollector) > 0);
74        Bundle measurement = (Bundle)readPrivateField("mPerfMeasurement", mPerfCollector);
75        assertNotNull(measurement);
76        verifyTimingBundle(measurement, new ArrayList<String>());
77    }
78
79    @SmallTest
80    public void testAddIterationNoWriter() throws Exception {
81        mPerfCollector.startTiming("testAddIterationNoWriter");
82        workForRandomTinyPeriod();
83        Bundle iteration = mPerfCollector.addIteration("timing1");
84
85        verifyIterationBundle(iteration, "timing1");
86    }
87
88    @SmallTest
89    public void testStopTimingNoWriter() throws Exception {
90        mPerfCollector.startTiming("testStopTimingNoWriter");
91        workForRandomTinyPeriod();
92        mPerfCollector.addIteration("timing2");
93        workForRandomTinyPeriod();
94        mPerfCollector.addIteration("timing3");
95        workForRandomShortPeriod();
96        Bundle timing = mPerfCollector.stopTiming("timing4");
97
98        ArrayList<String> labels = new ArrayList<String>();
99        labels.add("timing2");
100        labels.add("timing3");
101        labels.add("timing4");
102        verifyTimingBundle(timing, labels);
103    }
104
105    @SmallTest
106    public void testBeginSnapshot() throws Exception {
107        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
108        mPerfCollector.setPerformanceResultsWriter(writer);
109        mPerfCollector.beginSnapshot("testBeginSnapshot");
110
111        assertEquals("testBeginSnapshot", writer.snapshotLabel);
112        assertTrue((Long)readPrivateField("mSnapshotCpuTime", mPerfCollector) > 0);
113        assertTrue((Long)readPrivateField("mSnapshotExecTime", mPerfCollector) > 0);
114        Bundle snapshot = (Bundle)readPrivateField("mPerfSnapshot", mPerfCollector);
115        assertNotNull(snapshot);
116        assertEquals(2, snapshot.size());
117    }
118
119    @SmallTest
120    public void testEndSnapshot() throws Exception {
121        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
122        mPerfCollector.setPerformanceResultsWriter(writer);
123        mPerfCollector.beginSnapshot("testEndSnapshot");
124        workForRandomLongPeriod();
125        Bundle snapshot1 = mPerfCollector.endSnapshot();
126        Bundle snapshot2 = writer.snapshotResults;
127
128        assertEqualsBundle(snapshot1, snapshot2);
129        verifySnapshotBundle(snapshot1);
130    }
131
132    @SmallTest
133    public void testStartTiming() throws Exception {
134        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
135        mPerfCollector.setPerformanceResultsWriter(writer);
136        mPerfCollector.startTiming("testStartTiming");
137
138        assertEquals("testStartTiming", writer.timingLabel);
139        assertTrue((Long)readPrivateField("mCpuTime", mPerfCollector) > 0);
140        assertTrue((Long)readPrivateField("mExecTime", mPerfCollector) > 0);
141        Bundle measurement = (Bundle)readPrivateField("mPerfMeasurement", mPerfCollector);
142        assertNotNull(measurement);
143        verifyTimingBundle(measurement, new ArrayList<String>());
144    }
145
146    @SmallTest
147    public void testAddIteration() throws Exception {
148        mPerfCollector.startTiming("testAddIteration");
149        workForRandomTinyPeriod();
150        Bundle iteration = mPerfCollector.addIteration("timing5");
151
152        verifyIterationBundle(iteration, "timing5");
153    }
154
155    @SmallTest
156    public void testStopTiming() throws Exception {
157        mPerfCollector.startTiming("testStopTiming");
158        workForRandomTinyPeriod();
159        mPerfCollector.addIteration("timing6");
160        workForRandomTinyPeriod();
161        mPerfCollector.addIteration("timing7");
162        workForRandomShortPeriod();
163        Bundle timing = mPerfCollector.stopTiming("timing8");
164
165        ArrayList<String> labels = new ArrayList<String>();
166        labels.add("timing6");
167        labels.add("timing7");
168        labels.add("timing8");
169        verifyTimingBundle(timing, labels);
170    }
171
172    @SmallTest
173    public void testAddMeasurementLong() throws Exception {
174        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
175        mPerfCollector.setPerformanceResultsWriter(writer);
176        mPerfCollector.startTiming("testAddMeasurementLong");
177        mPerfCollector.addMeasurement("testAddMeasurementLongZero", 0);
178        mPerfCollector.addMeasurement("testAddMeasurementLongPos", 348573);
179        mPerfCollector.addMeasurement("testAddMeasurementLongNeg", -19354);
180        mPerfCollector.stopTiming("");
181
182        assertEquals("testAddMeasurementLong", writer.timingLabel);
183        Bundle results = writer.timingResults;
184        assertEquals(4, results.size());
185        assertTrue(results.containsKey("testAddMeasurementLongZero"));
186        assertEquals(0, results.getLong("testAddMeasurementLongZero"));
187        assertTrue(results.containsKey("testAddMeasurementLongPos"));
188        assertEquals(348573, results.getLong("testAddMeasurementLongPos"));
189        assertTrue(results.containsKey("testAddMeasurementLongNeg"));
190        assertEquals(-19354, results.getLong("testAddMeasurementLongNeg"));
191    }
192
193    @SmallTest
194    public void testAddMeasurementFloat() throws Exception {
195        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
196        mPerfCollector.setPerformanceResultsWriter(writer);
197        mPerfCollector.startTiming("testAddMeasurementFloat");
198        mPerfCollector.addMeasurement("testAddMeasurementFloatZero", 0.0f);
199        mPerfCollector.addMeasurement("testAddMeasurementFloatPos", 348573.345f);
200        mPerfCollector.addMeasurement("testAddMeasurementFloatNeg", -19354.093f);
201        mPerfCollector.stopTiming("");
202
203        assertEquals("testAddMeasurementFloat", writer.timingLabel);
204        Bundle results = writer.timingResults;
205        assertEquals(4, results.size());
206        assertTrue(results.containsKey("testAddMeasurementFloatZero"));
207        assertEquals(0.0f, results.getFloat("testAddMeasurementFloatZero"));
208        assertTrue(results.containsKey("testAddMeasurementFloatPos"));
209        assertEquals(348573.345f, results.getFloat("testAddMeasurementFloatPos"));
210        assertTrue(results.containsKey("testAddMeasurementFloatNeg"));
211        assertEquals(-19354.093f, results.getFloat("testAddMeasurementFloatNeg"));
212    }
213
214    @SmallTest
215    public void testAddMeasurementString() throws Exception {
216        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
217        mPerfCollector.setPerformanceResultsWriter(writer);
218        mPerfCollector.startTiming("testAddMeasurementString");
219        mPerfCollector.addMeasurement("testAddMeasurementStringNull", null);
220        mPerfCollector.addMeasurement("testAddMeasurementStringEmpty", "");
221        mPerfCollector.addMeasurement("testAddMeasurementStringNonEmpty", "Hello World");
222        mPerfCollector.stopTiming("");
223
224        assertEquals("testAddMeasurementString", writer.timingLabel);
225        Bundle results = writer.timingResults;
226        assertEquals(4, results.size());
227        assertTrue(results.containsKey("testAddMeasurementStringNull"));
228        assertNull(results.getString("testAddMeasurementStringNull"));
229        assertTrue(results.containsKey("testAddMeasurementStringEmpty"));
230        assertEquals("", results.getString("testAddMeasurementStringEmpty"));
231        assertTrue(results.containsKey("testAddMeasurementStringNonEmpty"));
232        assertEquals("Hello World", results.getString("testAddMeasurementStringNonEmpty"));
233    }
234
235    @SmallTest
236    public void testSimpleSequence() throws Exception {
237        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
238        mPerfCollector.setPerformanceResultsWriter(writer);
239        mPerfCollector.beginSnapshot("testSimpleSequence");
240        mPerfCollector.startTiming("testSimpleSequenceTiming");
241        workForRandomTinyPeriod();
242        mPerfCollector.addIteration("iteration1");
243        workForRandomTinyPeriod();
244        mPerfCollector.addIteration("iteration2");
245        workForRandomTinyPeriod();
246        mPerfCollector.addIteration("iteration3");
247        workForRandomTinyPeriod();
248        mPerfCollector.addIteration("iteration4");
249        workForRandomShortPeriod();
250        Bundle timing = mPerfCollector.stopTiming("iteration5");
251        workForRandomLongPeriod();
252        Bundle snapshot1 = mPerfCollector.endSnapshot();
253        Bundle snapshot2 = writer.snapshotResults;
254
255        assertEqualsBundle(snapshot1, snapshot2);
256        verifySnapshotBundle(snapshot1);
257
258        ArrayList<String> labels = new ArrayList<String>();
259        labels.add("iteration1");
260        labels.add("iteration2");
261        labels.add("iteration3");
262        labels.add("iteration4");
263        labels.add("iteration5");
264        verifyTimingBundle(timing, labels);
265    }
266
267    @SmallTest
268    public void testLongSequence() throws Exception {
269        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
270        mPerfCollector.setPerformanceResultsWriter(writer);
271        mPerfCollector.beginSnapshot("testLongSequence");
272        mPerfCollector.startTiming("testLongSequenceTiming1");
273        workForRandomTinyPeriod();
274        mPerfCollector.addIteration("iteration1");
275        workForRandomTinyPeriod();
276        mPerfCollector.addIteration("iteration2");
277        workForRandomShortPeriod();
278        Bundle timing1 = mPerfCollector.stopTiming("iteration3");
279        workForRandomLongPeriod();
280
281        mPerfCollector.startTiming("testLongSequenceTiming2");
282        workForRandomTinyPeriod();
283        mPerfCollector.addIteration("iteration4");
284        workForRandomTinyPeriod();
285        mPerfCollector.addIteration("iteration5");
286        workForRandomShortPeriod();
287        Bundle timing2 = mPerfCollector.stopTiming("iteration6");
288        workForRandomLongPeriod();
289
290        mPerfCollector.startTiming("testLongSequenceTiming3");
291        workForRandomTinyPeriod();
292        mPerfCollector.addIteration("iteration7");
293        workForRandomTinyPeriod();
294        mPerfCollector.addIteration("iteration8");
295        workForRandomShortPeriod();
296        Bundle timing3 = mPerfCollector.stopTiming("iteration9");
297        workForRandomLongPeriod();
298
299        mPerfCollector.startTiming("testLongSequenceTiming4");
300        workForRandomTinyPeriod();
301        mPerfCollector.addIteration("iteration10");
302        workForRandomTinyPeriod();
303        mPerfCollector.addIteration("iteration11");
304        workForRandomShortPeriod();
305        Bundle timing4 = mPerfCollector.stopTiming("iteration12");
306        workForRandomLongPeriod();
307
308        mPerfCollector.startTiming("testLongSequenceTiming5");
309        workForRandomTinyPeriod();
310        mPerfCollector.addIteration("iteration13");
311        workForRandomTinyPeriod();
312        mPerfCollector.addIteration("iteration14");
313        workForRandomShortPeriod();
314        Bundle timing5 = mPerfCollector.stopTiming("iteration15");
315        workForRandomLongPeriod();
316        Bundle snapshot1 = mPerfCollector.endSnapshot();
317        Bundle snapshot2 = writer.snapshotResults;
318
319        assertEqualsBundle(snapshot1, snapshot2);
320        verifySnapshotBundle(snapshot1);
321
322        ArrayList<String> labels1 = new ArrayList<String>();
323        labels1.add("iteration1");
324        labels1.add("iteration2");
325        labels1.add("iteration3");
326        verifyTimingBundle(timing1, labels1);
327        ArrayList<String> labels2 = new ArrayList<String>();
328        labels2.add("iteration4");
329        labels2.add("iteration5");
330        labels2.add("iteration6");
331        verifyTimingBundle(timing2, labels2);
332        ArrayList<String> labels3 = new ArrayList<String>();
333        labels3.add("iteration7");
334        labels3.add("iteration8");
335        labels3.add("iteration9");
336        verifyTimingBundle(timing3, labels3);
337        ArrayList<String> labels4 = new ArrayList<String>();
338        labels4.add("iteration10");
339        labels4.add("iteration11");
340        labels4.add("iteration12");
341        verifyTimingBundle(timing4, labels4);
342        ArrayList<String> labels5 = new ArrayList<String>();
343        labels5.add("iteration13");
344        labels5.add("iteration14");
345        labels5.add("iteration15");
346        verifyTimingBundle(timing5, labels5);
347    }
348
349    /*
350     * Verify that snapshotting and timing do not interfere w/ each other,
351     * by staggering calls to snapshot and timing functions.
352     */
353    @SmallTest
354    public void testOutOfOrderSequence() {
355        MockPerformanceResultsWriter writer = new MockPerformanceResultsWriter();
356        mPerfCollector.setPerformanceResultsWriter(writer);
357        mPerfCollector.startTiming("testOutOfOrderSequenceTiming");
358        workForRandomShortPeriod();
359        mPerfCollector.beginSnapshot("testOutOfOrderSequenceSnapshot");
360        workForRandomShortPeriod();
361        Bundle timing1 = mPerfCollector.stopTiming("timing1");
362        workForRandomShortPeriod();
363        Bundle snapshot1 = mPerfCollector.endSnapshot();
364
365        Bundle timing2 = writer.timingResults;
366        Bundle snapshot2 = writer.snapshotResults;
367
368        assertEqualsBundle(snapshot1, snapshot2);
369        verifySnapshotBundle(snapshot1);
370
371        assertEqualsBundle(timing1, timing2);
372        ArrayList<String> labels = new ArrayList<String>();
373        labels.add("timing1");
374        verifyTimingBundle(timing1, labels);
375    }
376
377    private void workForRandomPeriod(int minDuration, int maxDuration) {
378        Random random = new Random();
379        int period = minDuration + random.nextInt(maxDuration - minDuration);
380        long start = Process.getElapsedCpuTime();
381        // Generate positive amount of work, so cpu time is measurable in
382        // milliseconds
383        while (Process.getElapsedCpuTime() - start < period) {
384            for (int i = 0, temp = 0; i < 50; i++ ) {
385                temp += i;
386            }
387        }
388    }
389
390    private void workForRandomTinyPeriod() {
391        workForRandomPeriod(2, 5);
392    }
393
394    private void workForRandomShortPeriod() {
395        workForRandomPeriod(10, 25);
396    }
397
398    private void workForRandomLongPeriod() {
399        workForRandomPeriod(50, 100);
400    }
401
402    private void verifySnapshotBundle(Bundle snapshot) {
403        assertTrue("At least 26 metrics collected", 26 <= snapshot.size());
404
405        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_CPU_TIME));
406        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_CPU_TIME) > 0);
407        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_EXECUTION_TIME));
408        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_EXECUTION_TIME) > 0);
409
410        assertTrue(snapshot.containsKey(
411                PerformanceCollector.METRIC_KEY_PRE_RECEIVED_TRANSACTIONS));
412        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_PRE_SENT_TRANSACTIONS));
413        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_RECEIVED_TRANSACTIONS));
414        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_SENT_TRANSACTIONS));
415        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_GC_INVOCATION_COUNT));
416
417        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_ALLOCATED));
418        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_ALLOCATED) > 0);
419        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_FREE));
420        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_FREE) > 0);
421        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_PRIVATE_DIRTY));
422        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_PRIVATE_DIRTY) > 0);
423        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_PSS));
424        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_PSS) > 0);
425        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_SHARED_DIRTY));
426        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_SHARED_DIRTY) > 0);
427        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_JAVA_SIZE));
428        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_JAVA_SIZE) > 0);
429        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_ALLOCATED));
430        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_ALLOCATED) > 0);
431        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_FREE));
432        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_FREE) > 0);
433        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_PRIVATE_DIRTY));
434        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_PRIVATE_DIRTY) > 0);
435        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_PSS));
436        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_PSS) > 0);
437        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_SHARED_DIRTY));
438        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_SHARED_DIRTY) > 0);
439        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_NATIVE_SIZE));
440        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_NATIVE_SIZE) > 0);
441        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_GLOBAL_ALLOC_COUNT));
442        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_GLOBAL_ALLOC_COUNT) > 0);
443        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_GLOBAL_ALLOC_SIZE));
444        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_GLOBAL_ALLOC_SIZE) > 0);
445        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_GLOBAL_FREED_COUNT));
446        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_GLOBAL_FREED_COUNT) > 0);
447        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_GLOBAL_FREED_SIZE));
448        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_GLOBAL_FREED_SIZE) > 0);
449        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_OTHER_PRIVATE_DIRTY));
450        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_OTHER_PRIVATE_DIRTY) > 0);
451        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_OTHER_PSS));
452        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_OTHER_PSS) > 0);
453        assertTrue(snapshot.containsKey(PerformanceCollector.METRIC_KEY_OTHER_SHARED_DIRTY));
454        assertTrue(snapshot.getLong(PerformanceCollector.METRIC_KEY_OTHER_SHARED_DIRTY) > 0);
455    }
456
457    private void verifyIterationBundle(Bundle iteration, String label) {
458        assertEquals(3, iteration.size());
459        assertTrue(iteration.containsKey(PerformanceCollector.METRIC_KEY_LABEL));
460        assertEquals(label, iteration.getString(PerformanceCollector.METRIC_KEY_LABEL));
461        assertTrue(iteration.containsKey(PerformanceCollector.METRIC_KEY_CPU_TIME));
462        assertTrue(iteration.getLong(PerformanceCollector.METRIC_KEY_CPU_TIME) > 0);
463        assertTrue(iteration.containsKey(PerformanceCollector.METRIC_KEY_EXECUTION_TIME));
464        assertTrue(iteration.getLong(PerformanceCollector.METRIC_KEY_EXECUTION_TIME) > 0);
465    }
466
467    private void verifyTimingBundle(Bundle timing, ArrayList<String> labels) {
468        assertEquals(1, timing.size());
469        assertTrue(timing.containsKey(PerformanceCollector.METRIC_KEY_ITERATIONS));
470        ArrayList<Parcelable> iterations = timing.getParcelableArrayList(
471                PerformanceCollector.METRIC_KEY_ITERATIONS);
472        assertNotNull(iterations);
473        assertEquals(labels.size(), iterations.size());
474        for (int i = 0; i < labels.size(); i ++) {
475            Bundle iteration = (Bundle)iterations.get(i);
476            verifyIterationBundle(iteration, labels.get(i));
477        }
478    }
479
480    private void assertEqualsBundle(Bundle b1, Bundle b2) {
481        assertEquals(b1.keySet(), b2.keySet());
482        for (String key : b1.keySet()) {
483            assertEquals(b1.get(key), b2.get(key));
484        }
485    }
486
487    private Object readPrivateField(String fieldName, Object object) throws Exception {
488        Field f = object.getClass().getDeclaredField(fieldName);
489        f.setAccessible(true);
490        return f.get(object);
491    }
492
493    private class MockPerformanceResultsWriter implements PerformanceResultsWriter {
494
495        public String snapshotLabel;
496        public Bundle snapshotResults = new Bundle();
497        public String timingLabel;
498        public Bundle timingResults = new Bundle();
499
500        public void writeBeginSnapshot(String label) {
501            snapshotLabel = label;
502        }
503
504        public void writeEndSnapshot(Bundle results) {
505            snapshotResults.putAll(results);
506        }
507
508        public void writeStartTiming(String label) {
509            timingLabel = label;
510        }
511
512        public void writeStopTiming(Bundle results) {
513            timingResults.putAll(results);
514        }
515
516        public void writeMeasurement(String label, long value) {
517            timingResults.putLong(label, value);
518        }
519
520        public void writeMeasurement(String label, float value) {
521            timingResults.putFloat(label, value);
522        }
523
524        public void writeMeasurement(String label, String value) {
525            timingResults.putString(label, value);
526        }
527    }
528}
529