151ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom/* 251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project 351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * 451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * you may not use this file except in compliance with the License. 651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * You may obtain a copy of the License at 751ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * 851ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 951ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * 1051ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 1151ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 1251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * See the License for the specific language governing permissions and 1451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom * limitations under the License. 1551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom */ 1651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 17cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrompackage dalvik.system.profiler; 18cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom 19cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.AsciiHprofWriter; 20cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.BinaryHprofReader; 21cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.BinaryHprofWriter; 22cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.HprofData.Sample; 23cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.HprofData.StackTrace; 24cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.HprofData.ThreadEvent; 25cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.HprofData; 26cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport dalvik.system.profiler.SamplingProfiler.ThreadSet; 27d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.ByteArrayInputStream; 28d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.ByteArrayOutputStream; 29d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.File; 30d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.FileOutputStream; 31d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.InputStream; 32d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.io.OutputStream; 3351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstromimport java.math.BigInteger; 3451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstromimport java.security.KeyPairGenerator; 3551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstromimport java.security.SecureRandom; 36d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.Arrays; 37d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.HashMap; 38d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.HashSet; 39d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.List; 40d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.Map; 41d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstromimport java.util.Set; 4251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstromimport javax.crypto.spec.DHParameterSpec; 4351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstromimport junit.framework.TestCase; 4451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 4551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrompublic class SamplingProfilerTest extends TestCase { 4651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 47d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom /** 48d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * Run the SamplingProfiler to gather some data on an actual 49d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * computation, then assert that it looks correct with test_HprofData. 50d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom */ 51d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_SamplingProfiler() throws Exception { 5251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom ThreadSet threadSet = SamplingProfiler.newArrayThreadSet(Thread.currentThread()); 5351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom SamplingProfiler profiler = new SamplingProfiler(12, threadSet); 54d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom profiler.start(100); 5551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom toBeMeasured(); 5651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom profiler.stop(); 5751ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom profiler.shutdown(); 58d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(profiler.getHprofData(), true); 5951ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom } 6051ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 6151ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom private static final String P_STR = 62d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom "9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e3" 6351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom + "1db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b"; 6451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom private static final String G_STR = 6551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom "98ab7c5c431479d8645e33aa09758e0907c78747798d0968576f9877421a9089" 6651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom + "756f7876e76590b76765645c987976d764dd4564698a87585e64554984bb4445" 6751ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom + "76e5764786f875b4456c"; 6851ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 6951ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom private static final byte[] P = new BigInteger(P_STR,16).toByteArray(); 7051ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom private static final byte[] G = new BigInteger(G_STR,16).toByteArray(); 7151ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 7251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom private static void toBeMeasured () throws Exception { 7351ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom long start = System.currentTimeMillis(); 7451ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom for (int i = 0; i < 10000; i++) { 7551ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom BigInteger p = new BigInteger(P); 7651ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom BigInteger g = new BigInteger(G); 7751ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom KeyPairGenerator gen = KeyPairGenerator.getInstance("DH"); 7851ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom gen.initialize(new DHParameterSpec(p, g), new SecureRandom()); 7951ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom } 8051ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom long end = System.currentTimeMillis(); 8151ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom } 8251ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom 83d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_null() throws Exception { 84d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom try { 85d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom new HprofData(null); 86d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom fail(); 87d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } catch (NullPointerException expected) { 88d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 89d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 90d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 91d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_empty() throws Exception { 92d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Map<StackTrace, int[]> stackTraces = new HashMap<StackTrace, int[]>(); 93d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData hprofData = new HprofData(stackTraces); 94d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 95d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 96d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 97d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_timeMillis() throws Exception { 98d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Map<StackTrace, int[]> stackTraces = new HashMap<StackTrace, int[]>(); 99d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData hprofData = new HprofData(stackTraces); 100d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom long now = System.currentTimeMillis(); 101d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.setStartMillis(now); 102d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(now, hprofData.getStartMillis()); 103d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 104d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 105d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 106d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_addThreadEvent_null() throws Exception { 107d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Map<StackTrace, int[]> stackTraces = new HashMap<StackTrace, int[]>(); 108d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData hprofData = new HprofData(stackTraces); 109d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom try { 110d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(null); 111d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom fail(); 112d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } catch (NullPointerException expected) { 113d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 114d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 115d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 116d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 117d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_addThreadEvent() throws Exception { 118d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Map<StackTrace, int[]> stackTraces = new HashMap<StackTrace, int[]>(); 119d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData hprofData = new HprofData(stackTraces); 120d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 121d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // should have nothing in the thread history to start 122d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(0, hprofData.getThreadHistory().size()); 123d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 124d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // add thread 1 125d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int threadId = 1; 126d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int objectId = 2; 127d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ThreadEvent start1 = ThreadEvent.start(objectId, threadId, 128d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom "thread-name", "thread-group", "parent-group"); 129d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(start1); 130d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Arrays.asList(start1), hprofData.getThreadHistory()); 131d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 132d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 133d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // remove thread 2, which should not exist (but that's okay on the RI) 134d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ThreadEvent end2 = ThreadEvent.end(threadId+1); 135d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(end2); 136d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Arrays.asList(start1, end2), hprofData.getThreadHistory()); 137d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, false); // non-strict from here down because of this RI data 138d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 139d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // remove thread 1, which should exist 140d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ThreadEvent end1 = ThreadEvent.end(threadId); 141d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(end1); 142d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Arrays.asList(start1, end2, end1), hprofData.getThreadHistory()); 143d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, false); 144d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 145d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // remove thread 1 again, which should not exist (its not okay to have end followed by end) 146d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom try { 147d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(ThreadEvent.end(threadId)); 148d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom fail(); 149d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } catch (IllegalArgumentException expected) { 150d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 151d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Arrays.asList(start1, end2, end1), hprofData.getThreadHistory()); 152d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, false); 153d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 154d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 155d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom public void test_HprofData_addStackTrace() throws Exception { 156d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Map<StackTrace, int[]> stackTraces = new HashMap<StackTrace, int[]>(); 157d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData hprofData = new HprofData(stackTraces); 158d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 159d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // should have no samples to start 160d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(0, hprofData.getSamples().size()); 161d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 162d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // attempt to add a stack for a non-existent thread, should fail 163d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int stackTraceId = 1; 164d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int threadId = 2; 165d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int objectId = 3; 166d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int sampleCount = 4; 167d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom StackTraceElement[] stackFrames = new Throwable().getStackTrace(); 168d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom final int[] countCell = new int[] { 4 }; 169d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom StackTrace stackTrace = new StackTrace(stackTraceId, threadId, stackFrames); 170d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom try { 171d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addStackTrace(stackTrace, countCell); 172d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom fail(); 173d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } catch (IllegalArgumentException expected) { 174d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 175d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 176d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // add the thread and add the event 177d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ThreadEvent start = ThreadEvent.start(objectId, threadId, 178d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom "thread-name", "thread-group", "parent-group"); 179d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addThreadEvent(start); 180d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addStackTrace(stackTrace, countCell); 181d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Set<Sample> samples = hprofData.getSamples(); 182d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(samples); 183d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotSame(samples, hprofData.getSamples()); 184d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(1, samples.size()); 185d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Sample sample = samples.iterator().next(); 186d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(sample); 187d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(stackTrace, sample.stackTrace); 188d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(sampleCount, sample.count); 189d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 190d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 191d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // confirm we can mutate the sample count, but that its not 192d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // visible in the current sample, but it will be visible in a 193d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // new one. 194d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom countCell[0] += 42; 195d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(sampleCount, sample.count); 196d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Sample sample2 = hprofData.getSamples().iterator().next(); 197d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(sampleCount + 42, sample2.count); 198d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 199d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 200d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom // try to reuse the stackTraceId, should fail 201d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom try { 202d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom hprofData.addStackTrace(stackTrace, countCell); 203d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom fail(); 204d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } catch (IllegalArgumentException expected) { 205d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 206d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(1, hprofData.getSamples().size()); 207d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData(hprofData, true); 208d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 209d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 210d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 211d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom private void test_HprofData(HprofData hprofData, boolean strict) throws Exception { 212d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertHprofData(hprofData, strict); 213d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData_ascii(hprofData); 214d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom test_HprofData_binary(hprofData, strict); 215d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 216d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 217d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom /** 218d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * Assert general properities of HprofData hold true. 219d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom */ 220d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom private void assertHprofData(HprofData hprofData, boolean strict) throws Exception { 221d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom List<ThreadEvent> threadHistory = hprofData.getThreadHistory(); 222d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(threadHistory); 223cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom Set<Integer> threadsSeen = new HashSet<Integer>(); 224cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom Set<Integer> threadsActive = new HashSet<Integer>(); 225d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom for (ThreadEvent event : threadHistory) { 226d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(event); 227d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(event.type); 228d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom switch (event.type) { 229d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom case START: 230d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(event.threadName); 231d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(threadsActive.add(event.threadId)); 232d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(threadsSeen.add(event.threadId)); 233d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom break; 234d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom case END: 235d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(-1, event.objectId); 236d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNull(event.threadName); 237d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNull(event.groupName); 238d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNull(event.parentGroupName); 239d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom if (strict) { 240d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(threadsActive.remove(event.threadId)); 241d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 242d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom break; 243d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 244d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 245d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 246d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Set<Sample> samples = hprofData.getSamples(); 247d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(samples); 248d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom for (Sample sample : samples) { 249d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(sample); 250d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(sample.count > 0); 251d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(sample.stackTrace); 252d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(sample.stackTrace.stackTraceId != -1); 253d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(threadsSeen.contains(sample.stackTrace.getThreadId())); 254d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(sample.stackTrace.getStackFrames()); 255d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 256d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 257d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 258d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom /** 259d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * Convert to HprofData to ASCII to see if it triggers any exceptions 260d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom */ 261d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom private void test_HprofData_ascii(HprofData hprofData) throws Exception { 262d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ByteArrayOutputStream out = new ByteArrayOutputStream(); 263e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom AsciiHprofWriter.write(hprofData, out); 264d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertFalse(out.toByteArray().length == 0); 265d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 266d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 267d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom /** 268d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * Convert to HprofData to binary and then reparse as to 269d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom * HprofData. Make sure the accessible data is equivalent. 270d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom */ 271d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom private void test_HprofData_binary(HprofData hprofData, boolean strict) throws Exception { 272d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 273d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom ByteArrayOutputStream out = new ByteArrayOutputStream(); 274e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom BinaryHprofWriter.write(hprofData, out); 275d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom out.close(); 276d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 277d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom byte[] bytes = out.toByteArray(); 278d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertFalse(bytes.length == 0); 279d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom if (false) { 280d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom File file = new File("/sdcard/java.hprof"); 281d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom OutputStream debug = new FileOutputStream(file); 282d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom debug.write(bytes); 283d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom debug.close(); 284d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom System.out.println("Wrote binary hprof data to " + file); 285d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 286d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 287d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom InputStream in = new ByteArrayInputStream(bytes); 288d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom BinaryHprofReader reader = new BinaryHprofReader(in); 289d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertTrue(reader.getStrict()); 290d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom reader.read(); 291d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom in.close(); 292d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals("JAVA PROFILE 1.0.2", reader.getVersion()); 293d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertNotNull(reader.getHprofData()); 294d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 295d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom HprofData parsed = reader.getHprofData(); 296d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertHprofData(hprofData, strict); 297d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom 298d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Long.toHexString(hprofData.getStartMillis()), 299d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Long.toHexString(parsed.getStartMillis())); 300d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Long.toHexString(hprofData.getFlags()), 301d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Long.toHexString(parsed.getFlags())); 302d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(Long.toHexString(hprofData.getDepth()), 303d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom Long.toHexString(parsed.getDepth())); 304d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(hprofData.getThreadHistory(), 305d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom parsed.getThreadHistory()); 306d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom assertEquals(hprofData.getSamples(), 307d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom parsed.getSamples()); 308d7fd1b88b89ca762afe5609d84a8eedfb611cbe1Brian Carlstrom } 30951ee38b9c39b0c36bce728a797b2c5e637be3d2cBrian Carlstrom} 310