1 /* 2 * Copyright (C) 2016 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 17 package com.android.ahat; 18 19 import com.android.ahat.heapdump.AhatHeap; 20 import com.android.ahat.heapdump.AhatInstance; 21 import com.android.ahat.heapdump.AhatSnapshot; 22 import com.android.ahat.heapdump.Diff; 23 import com.android.ahat.heapdump.FieldValue; 24 import com.android.tools.perflib.heap.hprof.HprofClassDump; 25 import com.android.tools.perflib.heap.hprof.HprofConstant; 26 import com.android.tools.perflib.heap.hprof.HprofDumpRecord; 27 import com.android.tools.perflib.heap.hprof.HprofHeapDump; 28 import com.android.tools.perflib.heap.hprof.HprofInstanceDump; 29 import com.android.tools.perflib.heap.hprof.HprofInstanceField; 30 import com.android.tools.perflib.heap.hprof.HprofLoadClass; 31 import com.android.tools.perflib.heap.hprof.HprofPrimitiveArrayDump; 32 import com.android.tools.perflib.heap.hprof.HprofRecord; 33 import com.android.tools.perflib.heap.hprof.HprofRootDebugger; 34 import com.android.tools.perflib.heap.hprof.HprofStaticField; 35 import com.android.tools.perflib.heap.hprof.HprofStringBuilder; 36 import com.android.tools.perflib.heap.hprof.HprofType; 37 import com.google.common.io.ByteArrayDataOutput; 38 import com.google.common.io.ByteStreams; 39 import java.io.IOException; 40 import java.util.ArrayList; 41 import java.util.List; 42 import org.junit.Test; 43 44 import static org.junit.Assert.assertEquals; 45 import static org.junit.Assert.assertNotNull; 46 import static org.junit.Assert.assertNull; 47 import static org.junit.Assert.assertTrue; 48 49 public class DiffTest { 50 @Test diffMatchedHeap()51 public void diffMatchedHeap() throws IOException { 52 TestDump dump = TestDump.getTestDump(); 53 AhatHeap a = dump.getAhatSnapshot().getHeap("app"); 54 assertNotNull(a); 55 AhatHeap b = dump.getBaselineAhatSnapshot().getHeap("app"); 56 assertNotNull(b); 57 assertEquals(a.getBaseline(), b); 58 assertEquals(b.getBaseline(), a); 59 } 60 61 @Test diffUnchanged()62 public void diffUnchanged() throws IOException { 63 TestDump dump = TestDump.getTestDump(); 64 65 AhatInstance a = dump.getDumpedAhatInstance("unchangedObject"); 66 assertNotNull(a); 67 68 AhatInstance b = dump.getBaselineDumpedAhatInstance("unchangedObject"); 69 assertNotNull(b); 70 assertEquals(a, b.getBaseline()); 71 assertEquals(b, a.getBaseline()); 72 assertEquals(a.getSite(), b.getSite().getBaseline()); 73 assertEquals(b.getSite(), a.getSite().getBaseline()); 74 } 75 76 @Test diffAdded()77 public void diffAdded() throws IOException { 78 TestDump dump = TestDump.getTestDump(); 79 80 AhatInstance a = dump.getDumpedAhatInstance("addedObject"); 81 assertNotNull(a); 82 assertNull(dump.getBaselineDumpedAhatInstance("addedObject")); 83 assertTrue(a.getBaseline().isPlaceHolder()); 84 } 85 86 @Test diffRemoved()87 public void diffRemoved() throws IOException { 88 TestDump dump = TestDump.getTestDump(); 89 90 assertNull(dump.getDumpedAhatInstance("removedObject")); 91 AhatInstance b = dump.getBaselineDumpedAhatInstance("removedObject"); 92 assertNotNull(b); 93 assertTrue(b.getBaseline().isPlaceHolder()); 94 } 95 96 @Test nullClassObj()97 public void nullClassObj() throws IOException { 98 // Set up a heap dump that has a null classObj. 99 // The heap dump is derived from the InstanceTest.asStringEmbedded test. 100 HprofStringBuilder strings = new HprofStringBuilder(0); 101 List<HprofRecord> records = new ArrayList<HprofRecord>(); 102 List<HprofDumpRecord> dump = new ArrayList<HprofDumpRecord>(); 103 104 final int stringClassObjectId = 1; 105 records.add(new HprofLoadClass(0, 0, stringClassObjectId, 0, strings.get("java.lang.String"))); 106 dump.add(new HprofClassDump(stringClassObjectId, 0, 0, 0, 0, 0, 0, 0, 0, 107 new HprofConstant[0], new HprofStaticField[0], 108 new HprofInstanceField[]{ 109 new HprofInstanceField(strings.get("count"), HprofType.TYPE_INT), 110 new HprofInstanceField(strings.get("hashCode"), HprofType.TYPE_INT), 111 new HprofInstanceField(strings.get("offset"), HprofType.TYPE_INT), 112 new HprofInstanceField(strings.get("value"), HprofType.TYPE_OBJECT)})); 113 114 dump.add(new HprofPrimitiveArrayDump(0x41, 0, HprofType.TYPE_CHAR, 115 new long[]{'n', 'o', 't', ' ', 'h', 'e', 'l', 'l', 'o', 'o', 'p'})); 116 117 ByteArrayDataOutput values = ByteStreams.newDataOutput(); 118 values.writeInt(5); // count 119 values.writeInt(0); // hashCode 120 values.writeInt(4); // offset 121 values.writeInt(0x41); // value 122 dump.add(new HprofInstanceDump(0x42, 0, stringClassObjectId, values.toByteArray())); 123 dump.add(new HprofRootDebugger(stringClassObjectId)); 124 dump.add(new HprofRootDebugger(0x42)); 125 126 records.add(new HprofHeapDump(0, dump.toArray(new HprofDumpRecord[0]))); 127 AhatSnapshot snapshot = SnapshotBuilder.makeSnapshot(strings, records); 128 129 // Diffing should not crash. 130 Diff.snapshots(snapshot, snapshot); 131 } 132 133 @Test diffFields()134 public void diffFields() { 135 List<FieldValue> a = new ArrayList<FieldValue>(); 136 a.add(new FieldValue("n0", "t0", null)); 137 a.add(new FieldValue("n2", "t2", null)); 138 a.add(new FieldValue("n3", "t3", null)); 139 a.add(new FieldValue("n4", "t4", null)); 140 a.add(new FieldValue("n5", "t5", null)); 141 a.add(new FieldValue("n6", "t6", null)); 142 143 List<FieldValue> b = new ArrayList<FieldValue>(); 144 b.add(new FieldValue("n0", "t0", null)); 145 b.add(new FieldValue("n1", "t1", null)); 146 b.add(new FieldValue("n2", "t2", null)); 147 b.add(new FieldValue("n3", "t3", null)); 148 b.add(new FieldValue("n5", "t5", null)); 149 b.add(new FieldValue("n6", "t6", null)); 150 b.add(new FieldValue("n7", "t7", null)); 151 152 Diff.fields(a, b); 153 assertEquals(8, a.size()); 154 assertEquals(8, b.size()); 155 for (int i = 0; i < 8; i++) { 156 assertEquals(a.get(i), b.get(i).getBaseline()); 157 assertEquals(b.get(i), a.get(i).getBaseline()); 158 } 159 assertTrue(a.get(1).isPlaceHolder()); 160 assertTrue(a.get(7).isPlaceHolder()); 161 assertTrue(b.get(4).isPlaceHolder()); 162 } 163 } 164