blob: e55c970fcea457d01efd25788a809b55861fbf3c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2015,2017 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.mat.tests.acquire;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.number.OrderingComparison.greaterThan;
import static org.hamcrest.number.OrderingComparison.greaterThanOrEqualTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.internal.acquire.HeapDumpProviderDescriptor;
import org.eclipse.mat.internal.acquire.HeapDumpProviderRegistry;
import org.eclipse.mat.query.IContextObject;
import org.eclipse.mat.query.IResult;
import org.eclipse.mat.query.IResultTree;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.SnapshotFactory;
import org.eclipse.mat.snapshot.acquire.IHeapDumpProvider;
import org.eclipse.mat.snapshot.acquire.VmInfo;
import org.eclipse.mat.snapshot.query.SnapshotQuery;
import org.eclipse.mat.tests.TestSnapshots;
import org.eclipse.mat.util.IProgressListener;
import org.eclipse.mat.util.VoidProgressListener;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
/**
* Test the triggering and collection of heap dumps from other processes.
*/
public class AcquireDumpTest
{
@Rule
public ErrorCollector collector = new ErrorCollector();
/**
* Check there are JMap and IBM dump providers
*/
@Test
public void test()
{
Collection<HeapDumpProviderDescriptor> descs = HeapDumpProviderRegistry.instance().getHeapDumpProviders();
collector.checkThat("Should be HPROF and IBM Dumps descriptors", descs.size(), greaterThanOrEqualTo(2));
}
/**
* Check the providers have sensible properties
*/
@Test
public void test2()
{
Collection<HeapDumpProviderDescriptor> descs = HeapDumpProviderRegistry.instance().getHeapDumpProviders();
for (HeapDumpProviderDescriptor hd : descs)
{
collector.checkThat("Should be some help", hd.getHelp().length(), greaterThan(20));
collector.checkThat("Should be a name", hd.getName().length(), greaterThan(3));
collector.checkThat("Locale", hd.getHelpLocale(), notNullValue());
// collector.checkThat("Icon", hd.getIcon(), notNullValue());
collector.checkThat("Should be an ID", hd.getIdentifier().length(), greaterThan(3));
IHeapDumpProvider hdp = hd.getHeapDumpProvider();
collector.checkThat("Heap Dump Provider", hdp, notNullValue());
collector.checkThat("Heap Dump Provider toString", hdp.toString(), notNullValue());
}
}
/**
* Actually generate a dump and parse it
*
* @throws SnapshotException
* @throws IOException
*/
@Test
public void test3() throws SnapshotException, IOException
{
Collection<HeapDumpProviderDescriptor> descs = HeapDumpProviderRegistry.instance().getHeapDumpProviders();
int count = 0;
int found = 0;
File tmpdir = TestSnapshots.createGeneratedName("acquire", null);
for (HeapDumpProviderDescriptor hd : descs)
{
IHeapDumpProvider hdp = hd.getHeapDumpProvider();
collector.checkThat("Heap Dump Provider", hdp, notNullValue());
IProgressListener l = new VoidProgressListener();
List<? extends VmInfo> ls;
try
{
ls = hdp.getAvailableVMs(l);
}
catch (SnapshotException e)
{
continue;
}
collector.checkThat("Heap dump provider "+hdp, ls, notNullValue());
if (ls == null)
continue;
for (VmInfo vm : ls)
{
++count;
String desc = vm.getDescription();
collector.checkThat("VM description", desc, notNullValue());
if (desc.contains("org.eclipse.mat.tests"))
{
System.out.println("Desc " + desc);
File f = new File(vm.getProposedFileName());
System.out.println("Proposed name "+f);
String fname = f.getName();
int ldot = fname.lastIndexOf('.');
String fname2 = "acquire_dump" + fname.substring(ldot);
File tmpdump = new File(tmpdir, fname2);
System.out.println("Dump " + tmpdump);
File dmp = hdp.acquireDump(vm, tmpdump, l);
collector.checkThat("Dump file", dmp, notNullValue());
try
{
ISnapshot answer = SnapshotFactory.openSnapshot(dmp, Collections.<String, String> emptyMap(), l);
try
{
collector.checkThat("Snapshot", answer, notNullValue());
found++;
checkEclipseBundleQuery(answer);
}
finally
{
answer.dispose();
}
}
finally
{
dmp.delete();
}
}
}
}
collector.checkThat("Available VMs", count, greaterThan(0));
collector.checkThat("Available dumps from VMs", found, greaterThan(0));
}
/**
* This query requires an heap dump from a running Eclipse system to
* test the Eclipse bundle query. Other test dumps from non-Eclipse programs won't work.
* @param snapshot
* @throws SnapshotException
*/
private void checkEclipseBundleQuery(ISnapshot snapshot) throws SnapshotException
{
SnapshotQuery query = SnapshotQuery.parse("bundle_registry -groupby NONE", snapshot);
assertNotNull(query);
IResult result = query.execute(new VoidProgressListener());
assertNotNull(result);
IResultTree tree = (IResultTree) result;
int found = 0;
int f2 = 0;
for (Object o : tree.getElements())
{
IContextObject ctx = tree.getContext(o);
Object o2 = tree.getColumnValue(o, 0);
if (o2.toString().startsWith("org.eclipse.mat.tests "))
{
found++;
}
if (o2.toString().startsWith("org.eclipse.mat.api "))
{
List<?> l3 = tree.getChildren(o);
for (Object o3 : l3)
{
Object o4 = tree.getColumnValue(o3, 0);
if (o4.toString().startsWith("Dependencies"))
{
f2 |= 1;
checkSubtree(tree, o3, 2, "org.eclipse.mat.report ", "Expected dependencies of org.eclipse.mat.api to include");
}
if (o4.toString().startsWith("Dependents"))
{
f2 |= 2;
checkSubtree(tree, o3, 2, "org.eclipse.mat.parser ", "Expected dependendents of org.eclipse.mat.api to include");
}
if (o4.toString().startsWith("Extension Points"))
{
f2 |= 4;
checkSubtree(tree, o3, 2, "org.eclipse.mat.api.factory", "Expected extension points of org.eclipse.mat.api to include");
}
if (o4.toString().startsWith("Extensions"))
{
f2 |= 8;
checkSubtree(tree, o3, 2, "org.eclipse.mat.api.nameResolver", "Expected extensions of org.eclipse.mat.api to include");
}
if (o4.toString().startsWith("Used Services"))
{
f2 |= 16;
checkSubtree(tree, o3, 1, "org.eclipse.osgi.service.debug.DebugOptions", "Expected used services of org.eclipse.mat.api to include");
}
}
}
}
assertEquals("Expected to find a org.eclipse.mat.tests plugin", found, 1);
assertEquals("Expected Dependencies,Dependents, Extension Points, Extensions, Used Services from org.eclipse.mat.api", f2, 31);
}
private void checkSubtree(IResultTree tree, Object o3, int minElements, String toFind, String errMsg)
{
List<?> l5 = tree.getChildren(o3);
assertTrue(l5.size() >= minElements);
boolean foundItem = false;
for (Object o6 : l5)
{
Object o7 = tree.getColumnValue(o6, 0);
if (o7.toString().startsWith(toFind))
{
foundItem = true;
}
//System.out.println("Found "+o7+" "+errMsg);
}
assertTrue(errMsg+" "+toFind, foundItem);
}
}