1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import android.support.annotation.NonNull; 8 import android.support.test.filters.SmallTest; 9 10 import org.hamcrest.CoreMatchers; 11 import org.junit.Rule; 12 import org.junit.Test; 13 import org.junit.rules.ExpectedException; 14 import org.junit.runner.RunWith; 15 16 import org.chromium.base.test.BaseJUnit4ClassRunner; 17 18 import java.util.concurrent.ArrayBlockingQueue; 19 import java.util.concurrent.Executor; 20 import java.util.concurrent.RejectedExecutionException; 21 import java.util.concurrent.ThreadFactory; 22 import java.util.concurrent.TimeUnit; 23 24 /** 25 * Tests for our AsyncTask modifications 26 * 27 * Not a robolectric test because the reflection doesn't work with ShadowAsyncTask. 28 */ 29 @RunWith(BaseJUnit4ClassRunner.class) 30 public class AsyncTaskTest { 31 private static class SpecialChromeAsyncTask extends AsyncTask<Void, Void, Void> { 32 @Override doInBackground(Void... params)33 protected Void doInBackground(Void... params) { 34 return null; 35 } 36 } 37 38 private static class SpecialOsAsyncTask extends android.os.AsyncTask<Void, Void, Void> { 39 @Override doInBackground(Void... params)40 protected Void doInBackground(Void... params) { 41 return null; 42 } 43 } 44 45 private static class SpecialRunnable implements Runnable { 46 @Override run()47 public void run() {} 48 } 49 50 private static final int QUEUE_SIZE = 40; 51 52 @Rule 53 public ExpectedException thrown = ExpectedException.none(); 54 55 /** 56 * Test filling the queue with basic Runnables, then add a final AsyncTask to overfill it, and 57 * ensure the Runnable is the one blamed in the exception message. 58 */ 59 @Test 60 @SmallTest testChromeThreadPoolExecutorRunnables()61 public void testChromeThreadPoolExecutorRunnables() { 62 Executor executor = new AsyncTask.ChromeThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, 63 new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new ThreadFactory() { 64 @Override 65 public Thread newThread(@NonNull Runnable r) { 66 return null; 67 } 68 }); 69 for (int i = 0; i < QUEUE_SIZE; i++) { 70 executor.execute(new SpecialRunnable()); 71 } 72 thrown.expect(RejectedExecutionException.class); 73 thrown.expectMessage( 74 CoreMatchers.containsString("org.chromium.base.AsyncTaskTest$SpecialRunnable")); 75 thrown.expectMessage( 76 CoreMatchers.not(CoreMatchers.containsString("SpecialChromeAsyncTask"))); 77 new SpecialChromeAsyncTask().executeOnExecutor(executor); 78 } 79 80 /** 81 * Test filling the queue with Chrome AsyncTasks, then add a final OS AsyncTask to 82 * overfill it and ensure the Chrome AsyncTask is the one blamed in the exception message. 83 */ 84 @Test 85 @SmallTest testChromeThreadPoolExecutorChromeAsyncTask()86 public void testChromeThreadPoolExecutorChromeAsyncTask() { 87 Executor executor = new AsyncTask.ChromeThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, 88 new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new ThreadFactory() { 89 @Override 90 public Thread newThread(@NonNull Runnable r) { 91 return null; 92 } 93 }); 94 for (int i = 0; i < QUEUE_SIZE; i++) { 95 new SpecialChromeAsyncTask().executeOnExecutor(executor); 96 } 97 thrown.expect(RejectedExecutionException.class); 98 thrown.expectMessage(CoreMatchers.containsString( 99 "org.chromium.base.AsyncTaskTest$SpecialChromeAsyncTask")); 100 thrown.expectMessage(CoreMatchers.not(CoreMatchers.containsString("SpecialOsAsyncTask"))); 101 new SpecialOsAsyncTask().executeOnExecutor(executor); 102 } 103 104 /** 105 * Test filling the queue with android.os.AsyncTasks, then add a final ChromeAsyncTask to 106 * overfill it and ensure the OsAsyncTask is the one blamed in the exception message. 107 */ 108 @Test 109 @SmallTest testChromeThreadPoolExecutorOsAsyncTask()110 public void testChromeThreadPoolExecutorOsAsyncTask() { 111 Executor executor = new AsyncTask.ChromeThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, 112 new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new ThreadFactory() { 113 @Override 114 public Thread newThread(@NonNull Runnable r) { 115 return null; 116 } 117 }); 118 for (int i = 0; i < QUEUE_SIZE; i++) { 119 new SpecialOsAsyncTask().executeOnExecutor(executor); 120 } 121 thrown.expect(RejectedExecutionException.class); 122 thrown.expectMessage( 123 CoreMatchers.containsString("org.chromium.base.AsyncTaskTest$SpecialOsAsyncTask")); 124 thrown.expectMessage( 125 CoreMatchers.not(CoreMatchers.containsString("SpecialChromeAsyncTask"))); 126 new SpecialChromeAsyncTask().executeOnExecutor(executor); 127 } 128 } 129