Repository: square/leakcanary
File: leakcanary-analyzer/src/test/java/com/squareup/leakcanary/AsyncTaskLeakTest.java (Java)

Code before:
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_M;
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_O;
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_PRE_M;
import static com.squareup.leakcanary.TestUtil.analyze;
import static java.util.Arrays.asList;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

@RunWith(Parameterized.class) //
public class AsyncTaskLeakTest {

  static final String ASYNC_TASK_THREAD = "AsyncTask #1";
  static final String ASYNC_TASK_CLASS = "android.os.AsyncTask";
  static final String EXECUTOR_FIELD_1 = "SERIAL_EXECUTOR";
  static final String EXECUTOR_FIELD_2 = "sDefaultExecutor";

  @Parameterized.Parameters public static Collection<Object[]> data() {
    return asList(new Object[][] {
        { ASYNC_TASK_PRE_M }, //
        { ASYNC_TASK_M }, //
        // TODO With the latest perflib, all the tests for this O Heap Dump are failing because
        // we're unable to find a "mBuffer" field in Bitmap when computing the retained size.
        // Perflib added new code related to bitmaps so there's probably something there.
        { ASYNC_TASK_O } //
    });
  }

  private final TestUtil.HeapDumpFile heapDumpFile;
  ExcludedRefs.BuilderWithParams excludedRefs;

  public AsyncTaskLeakTest(TestUtil.HeapDumpFile heapDumpFile) {
    this.heapDumpFile = heapDumpFile;
  }

  @Before public void setUp() {
    excludedRefs = new ExcludedRefs.BuilderWithParams() //
        .clazz(WeakReference.class.getName())
        .alwaysExclude()
        .clazz("java.lang.ref.FinalizerReference")
        .alwaysExclude()
        .clazz(PhantomReference.class.getName())
        .alwaysExclude();
  }

  @Test public void leakFound() {
    AnalysisResult result = analyze(heapDumpFile, excludedRefs);
    assertTrue(result.leakFound);
    assertFalse(result.excludedLeak);

Review comment (suggestion):
huh that existed prior: https://github.com/square/leakcanary/commit/b818140d3f5ed95430360ab07efe39f73e6a845d

Code after:
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_M;
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_O;
import static com.squareup.leakcanary.TestUtil.HeapDumpFile.ASYNC_TASK_PRE_M;
import static com.squareup.leakcanary.TestUtil.analyze;
import static java.util.Arrays.asList;
import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

@RunWith(Parameterized.class) //
public class AsyncTaskLeakTest {

  static final String ASYNC_TASK_THREAD = "AsyncTask #1";
  static final String ASYNC_TASK_CLASS = "android.os.AsyncTask";
  static final String EXECUTOR_FIELD_1 = "SERIAL_EXECUTOR";
  static final String EXECUTOR_FIELD_2 = "sDefaultExecutor";

  @Parameterized.Parameters public static Collection<Object[]> data() {
    return asList(new Object[][] {
        { ASYNC_TASK_PRE_M }, //
        { ASYNC_TASK_M }, //
        { ASYNC_TASK_O } //
    });
  }

  private final TestUtil.HeapDumpFile heapDumpFile;
  ExcludedRefs.BuilderWithParams excludedRefs;

  public AsyncTaskLeakTest(TestUtil.HeapDumpFile heapDumpFile) {
    this.heapDumpFile = heapDumpFile;
  }

  @Before public void setUp() {
    excludedRefs = new ExcludedRefs.BuilderWithParams() //
        .clazz(WeakReference.class.getName())
        .alwaysExclude()
        .clazz("java.lang.ref.FinalizerReference")
        .alwaysExclude()
        .clazz(PhantomReference.class.getName())
        .alwaysExclude();
  }

  @Test public void leakFound() {
    AnalysisResult result = analyze(heapDumpFile, excludedRefs);
    assertTrue(result.leakFound);
    assertFalse(result.excludedLeak);
    LeakTraceElement gcRoot = result.leakTrace.elements.get(0);
    assertEquals(Thread.class.getName(), gcRoot.className);
    assertEquals(THREAD, gcRoot.holder);