/*
* Copyright (C) 2014 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.tools.perflib.heap.io;
import com.android.tools.perflib.heap.HprofParser;
import com.android.tools.perflib.heap.Snapshot;
import junit.framework.TestCase;
import sun.misc.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.RandomAccessFile;
import java.util.Arrays;
public class HprofBufferTest extends TestCase {
File file = new File(getClass().getResource("/dialer.android-hprof").getFile());
public void testSimpleMapping() throws Exception {
Snapshot snapshot = (new HprofParser(new MemoryMappedFileBuffer(file))).parse();
assertSnapshotCorrect(snapshot);
}
public void testMultiMapping() throws Exception {
// Split the file into chunks of 4096 bytes each, leave 128 bytes for padding.
MemoryMappedFileBuffer shardedBuffer = new MemoryMappedFileBuffer(file, 4096, 128);
Snapshot snapshot = (new HprofParser(shardedBuffer)).parse();
assertSnapshotCorrect(snapshot);
}
public void testMultiMappingWrappedRead() throws Exception {
// Leave just 8 bytes for padding to force wrapped reads.
MemoryMappedFileBuffer shardedBuffer = new MemoryMappedFileBuffer(file, 9973, 8);
Snapshot snapshot = (new HprofParser(shardedBuffer)).parse();
assertSnapshotCorrect(snapshot);
}
public void testMemoryMappingRemoval() throws Exception {
File tmpFile = File.createTempFile("test_vm", ".tmp");
System.err.println("vm temp file: " + tmpFile.getAbsolutePath());
System.err.println("jvm " + System.getProperty("sun.arch.data.model"));
long n = 500000000L;
RandomAccessFile raf = new RandomAccessFile(tmpFile, "rw");
raf.setLength(n);
raf.write(1);
raf.seek(n - 1);
raf.write(2);
raf.close();
MemoryMappedFileBuffer buffer = new MemoryMappedFileBuffer(tmpFile);
assertEquals(1, buffer.readByte());
buffer.setPosition(n - 1);
assertEquals(2, buffer.readByte());
// On Windows, tmpFile can't be deleted without unmapping it first.
buffer.dispose();
tmpFile.delete();
File g = new File(tmpFile.getCanonicalPath());
assertFalse(g.exists());
}
public void testSubsequenceReads() throws Exception {
byte[] fileContents = null;
FileInputStream fileInputStream = new FileInputStream(file);
try {
fileContents = IOUtils.readFully(fileInputStream, -1, true);
}
finally {
fileInputStream.close();
}
MemoryMappedFileBuffer mappedBuffer = new MemoryMappedFileBuffer(file, 8259, 8);
byte[] buffer = new byte[8190];
mappedBuffer.readSubSequence(buffer, 0, 8190);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 0, 8190)));
assertEquals(mappedBuffer.position(), 8190);
buffer = new byte[8190];
mappedBuffer.setPosition(0);
mappedBuffer.readSubSequence(buffer, 2000, 8190);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 2000, 2000 + 8190)));
assertEquals(mappedBuffer.position(), 2000 + 8190);
buffer = new byte[100000];
mappedBuffer.setPosition(0);
mappedBuffer.readSubSequence(buffer, 19242, 100000);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 19242, 19242 + 100000)));
assertEquals(mappedBuffer.position(), 19242 + 100000);
buffer = new byte[8259];
mappedBuffer.setPosition(0);
mappedBuffer.readSubSequence(buffer, 0, 8259);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 0, 8259)));
assertEquals(mappedBuffer.position(), 8259);
buffer = new byte[8259];
mappedBuffer.setPosition(0);
mappedBuffer.readSubSequence(buffer, 8259, 8259);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 8259, 8259 + 8259)));
assertEquals(mappedBuffer.position(), 8259 + 8259);
mappedBuffer.readSubSequence(buffer, 8259, 8259);
assertTrue(Arrays.equals(buffer, Arrays.copyOfRange(fileContents, 8259 * 3, 8259 * 4)));
assertEquals(mappedBuffer.position(), 8259 * 4);
}
private void assertSnapshotCorrect(Snapshot snapshot) {
assertEquals(11182, snapshot.getGCRoots().size());
assertEquals(38, snapshot.getHeap(65).getClasses().size());
assertEquals(1406, snapshot.getHeap(65).getInstances().size());
assertEquals(3533, snapshot.getHeap(90).getClasses().size());
assertEquals(38710, snapshot.getHeap(90).getInstances().size());
}
}