| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.ahat; |
| |
| import com.android.ahat.heapdump.AhatHeap; |
| import com.android.ahat.heapdump.AhatInstance; |
| import com.android.ahat.heapdump.AhatSnapshot; |
| import com.android.ahat.heapdump.Diff; |
| import com.android.ahat.heapdump.FieldValue; |
| import com.android.tools.perflib.heap.hprof.HprofClassDump; |
| import com.android.tools.perflib.heap.hprof.HprofConstant; |
| import com.android.tools.perflib.heap.hprof.HprofDumpRecord; |
| import com.android.tools.perflib.heap.hprof.HprofHeapDump; |
| import com.android.tools.perflib.heap.hprof.HprofInstanceDump; |
| import com.android.tools.perflib.heap.hprof.HprofInstanceField; |
| import com.android.tools.perflib.heap.hprof.HprofLoadClass; |
| import com.android.tools.perflib.heap.hprof.HprofPrimitiveArrayDump; |
| import com.android.tools.perflib.heap.hprof.HprofRecord; |
| import com.android.tools.perflib.heap.hprof.HprofRootDebugger; |
| import com.android.tools.perflib.heap.hprof.HprofStaticField; |
| import com.android.tools.perflib.heap.hprof.HprofStringBuilder; |
| import com.android.tools.perflib.heap.hprof.HprofType; |
| import com.google.common.io.ByteArrayDataOutput; |
| import com.google.common.io.ByteStreams; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| import org.junit.Test; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| |
| public class DiffTest { |
| @Test |
| public void diffMatchedHeap() throws IOException { |
| TestDump dump = TestDump.getTestDump(); |
| AhatHeap a = dump.getAhatSnapshot().getHeap("app"); |
| assertNotNull(a); |
| AhatHeap b = dump.getBaselineAhatSnapshot().getHeap("app"); |
| assertNotNull(b); |
| assertEquals(a.getBaseline(), b); |
| assertEquals(b.getBaseline(), a); |
| } |
| |
| @Test |
| public void diffUnchanged() throws IOException { |
| TestDump dump = TestDump.getTestDump(); |
| |
| AhatInstance a = dump.getDumpedAhatInstance("unchangedObject"); |
| assertNotNull(a); |
| |
| AhatInstance b = dump.getBaselineDumpedAhatInstance("unchangedObject"); |
| assertNotNull(b); |
| assertEquals(a, b.getBaseline()); |
| assertEquals(b, a.getBaseline()); |
| assertEquals(a.getSite(), b.getSite().getBaseline()); |
| assertEquals(b.getSite(), a.getSite().getBaseline()); |
| } |
| |
| @Test |
| public void diffAdded() throws IOException { |
| TestDump dump = TestDump.getTestDump(); |
| |
| AhatInstance a = dump.getDumpedAhatInstance("addedObject"); |
| assertNotNull(a); |
| assertNull(dump.getBaselineDumpedAhatInstance("addedObject")); |
| assertTrue(a.getBaseline().isPlaceHolder()); |
| } |
| |
| @Test |
| public void diffRemoved() throws IOException { |
| TestDump dump = TestDump.getTestDump(); |
| |
| assertNull(dump.getDumpedAhatInstance("removedObject")); |
| AhatInstance b = dump.getBaselineDumpedAhatInstance("removedObject"); |
| assertNotNull(b); |
| assertTrue(b.getBaseline().isPlaceHolder()); |
| } |
| |
| @Test |
| public void nullClassObj() throws IOException { |
| // Set up a heap dump that has a null classObj. |
| // The heap dump is derived from the InstanceTest.asStringEmbedded test. |
| HprofStringBuilder strings = new HprofStringBuilder(0); |
| List<HprofRecord> records = new ArrayList<HprofRecord>(); |
| List<HprofDumpRecord> dump = new ArrayList<HprofDumpRecord>(); |
| |
| final int stringClassObjectId = 1; |
| records.add(new HprofLoadClass(0, 0, stringClassObjectId, 0, strings.get("java.lang.String"))); |
| dump.add(new HprofClassDump(stringClassObjectId, 0, 0, 0, 0, 0, 0, 0, 0, |
| new HprofConstant[0], new HprofStaticField[0], |
| new HprofInstanceField[]{ |
| new HprofInstanceField(strings.get("count"), HprofType.TYPE_INT), |
| new HprofInstanceField(strings.get("hashCode"), HprofType.TYPE_INT), |
| new HprofInstanceField(strings.get("offset"), HprofType.TYPE_INT), |
| new HprofInstanceField(strings.get("value"), HprofType.TYPE_OBJECT)})); |
| |
| dump.add(new HprofPrimitiveArrayDump(0x41, 0, HprofType.TYPE_CHAR, |
| new long[]{'n', 'o', 't', ' ', 'h', 'e', 'l', 'l', 'o', 'o', 'p'})); |
| |
| ByteArrayDataOutput values = ByteStreams.newDataOutput(); |
| values.writeInt(5); // count |
| values.writeInt(0); // hashCode |
| values.writeInt(4); // offset |
| values.writeInt(0x41); // value |
| dump.add(new HprofInstanceDump(0x42, 0, stringClassObjectId, values.toByteArray())); |
| dump.add(new HprofRootDebugger(stringClassObjectId)); |
| dump.add(new HprofRootDebugger(0x42)); |
| |
| records.add(new HprofHeapDump(0, dump.toArray(new HprofDumpRecord[0]))); |
| AhatSnapshot snapshot = SnapshotBuilder.makeSnapshot(strings, records); |
| |
| // Diffing should not crash. |
| Diff.snapshots(snapshot, snapshot); |
| } |
| |
| @Test |
| public void diffFields() { |
| List<FieldValue> a = new ArrayList<FieldValue>(); |
| a.add(new FieldValue("n0", "t0", null)); |
| a.add(new FieldValue("n2", "t2", null)); |
| a.add(new FieldValue("n3", "t3", null)); |
| a.add(new FieldValue("n4", "t4", null)); |
| a.add(new FieldValue("n5", "t5", null)); |
| a.add(new FieldValue("n6", "t6", null)); |
| |
| List<FieldValue> b = new ArrayList<FieldValue>(); |
| b.add(new FieldValue("n0", "t0", null)); |
| b.add(new FieldValue("n1", "t1", null)); |
| b.add(new FieldValue("n2", "t2", null)); |
| b.add(new FieldValue("n3", "t3", null)); |
| b.add(new FieldValue("n5", "t5", null)); |
| b.add(new FieldValue("n6", "t6", null)); |
| b.add(new FieldValue("n7", "t7", null)); |
| |
| Diff.fields(a, b); |
| assertEquals(8, a.size()); |
| assertEquals(8, b.size()); |
| for (int i = 0; i < 8; i++) { |
| assertEquals(a.get(i), b.get(i).getBaseline()); |
| assertEquals(b.get(i), a.get(i).getBaseline()); |
| } |
| assertTrue(a.get(1).isPlaceHolder()); |
| assertTrue(a.get(7).isPlaceHolder()); |
| assertTrue(b.get(4).isPlaceHolder()); |
| } |
| } |