Generate an hprof file to test ahat.

This change sets up the infrastructure to write test cases for ahat
that make use of an hprof file automatically generated from a sample
program.

Change-Id: Id11f656afb69c96a26655cc4caeb745ad844f431
diff --git a/tools/ahat/test/InstanceUtilsTest.java b/tools/ahat/test/InstanceUtilsTest.java
new file mode 100644
index 0000000..7613df4
--- /dev/null
+++ b/tools/ahat/test/InstanceUtilsTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 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.tools.perflib.heap.Instance;
+import java.io.IOException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import org.junit.Test;
+
+public class InstanceUtilsTest {
+  @Test
+  public void basicString() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance str = (Instance)dump.getDumpedThing("basicString");
+    assertEquals("hello, world", InstanceUtils.asString(str));
+  }
+
+  @Test
+  public void nullString() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance obj = (Instance)dump.getDumpedThing("nullString");
+    assertNull(InstanceUtils.asString(obj));
+  }
+
+  @Test
+  public void notString() throws IOException {
+    TestDump dump = TestDump.getTestDump();
+    Instance obj = (Instance)dump.getDumpedThing("anObject");
+    assertNotNull(obj);
+    assertNull(InstanceUtils.asString(obj));
+  }
+}
diff --git a/tools/ahat/test/TestDump.java b/tools/ahat/test/TestDump.java
new file mode 100644
index 0000000..c3a76e4
--- /dev/null
+++ b/tools/ahat/test/TestDump.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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.tools.perflib.heap.ClassObj;
+import com.android.tools.perflib.heap.Field;
+import com.android.tools.perflib.heap.Instance;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * The TestDump class is used to get an AhatSnapshot for the test-dump
+ * program.
+ */
+public class TestDump {
+  // It can take on the order of a second to parse and process the test-dump
+  // hprof. To avoid repeating this overhead for each test case, we cache the
+  // loaded instance of TestDump and reuse it when possible. In theory the
+  // test cases should not be able to modify the cached snapshot in a way that
+  // is visible to other test cases.
+  private static TestDump mCachedTestDump = null;
+
+  private AhatSnapshot mSnapshot = null;
+
+  /**
+   * Load the test-dump.hprof file.
+   * The location of the file is read from the system property
+   * "ahat.test.dump.hprof", which is expected to be set on the command line.
+   * For example:
+   *   java -Dahat.test.dump.hprof=test-dump.hprof -jar ahat-tests.jar
+   *
+   * An IOException is thrown if there is a failure reading the hprof file.
+   */
+  private TestDump() throws IOException {
+      String hprof = System.getProperty("ahat.test.dump.hprof");
+      mSnapshot = AhatSnapshot.fromHprof(new File(hprof));
+  }
+
+  /**
+   * Get the AhatSnapshot for the test dump program.
+   */
+  public AhatSnapshot getAhatSnapshot() {
+    return mSnapshot;
+  }
+
+  /**
+   * Return the value of a field in the DumpedStuff instance in the
+   * snapshot for the test-dump program.
+   */
+  public Object getDumpedThing(String name) {
+    ClassObj main = mSnapshot.findClass("Main");
+    Instance stuff = null;
+    for (Map.Entry<Field, Object> fields : main.getStaticFieldValues().entrySet()) {
+      if ("stuff".equals(fields.getKey().getName())) {
+        stuff = (Instance) fields.getValue();
+      }
+    }
+    return InstanceUtils.getField(stuff, name);
+  }
+
+  /**
+   * Get the test dump.
+   * An IOException is thrown if there is an error reading the test dump hprof
+   * file.
+   * To improve performance, this returns a cached instance of the TestDump
+   * when possible.
+   */
+  public static synchronized TestDump getTestDump() throws IOException {
+    if (mCachedTestDump == null) {
+      mCachedTestDump = new TestDump();
+    }
+    return mCachedTestDump;
+  }
+}
diff --git a/tools/ahat/test/Tests.java b/tools/ahat/test/Tests.java
index fb53d90..bab7121 100644
--- a/tools/ahat/test/Tests.java
+++ b/tools/ahat/test/Tests.java
@@ -22,6 +22,7 @@
   public static void main(String[] args) {
     if (args.length == 0) {
       args = new String[]{
+        "com.android.ahat.InstanceUtilsTest",
         "com.android.ahat.QueryTest",
         "com.android.ahat.SortTest"
       };