• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
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.task;
6 
7 import androidx.annotation.NonNull;
8 import androidx.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 BackgroundOnlyAsyncTask<Void> {
32         @Override
doInBackground()33         protected Void doInBackground() {
34             return null;
35         }
36     }
37 
38     @SuppressWarnings("NoAndroidAsyncTaskCheck")
39     private static class SpecialOsAsyncTask extends android.os.AsyncTask<Void, Void, Void> {
40         @Override
doInBackground(Void... params)41         protected Void doInBackground(Void... params) {
42             return null;
43         }
44     }
45 
46     private static class SpecialRunnable implements Runnable {
47         @Override
run()48         public void run() {}
49     }
50 
51     private static final int QUEUE_SIZE = 40;
52 
53     @Rule 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 =
63                 new ChromeThreadPoolExecutor(
64                         1,
65                         1,
66                         1,
67                         TimeUnit.SECONDS,
68                         new ArrayBlockingQueue<Runnable>(QUEUE_SIZE),
69                         new ThreadFactory() {
70                             @Override
71                             public Thread newThread(@NonNull Runnable r) {
72                                 return null;
73                             }
74                         });
75         for (int i = 0; i < QUEUE_SIZE; i++) {
76             executor.execute(new SpecialRunnable());
77         }
78         thrown.expect(RejectedExecutionException.class);
79         thrown.expectMessage(
80                 CoreMatchers.containsString(
81                         "org.chromium.base.task.AsyncTaskTest$SpecialRunnable"));
82         thrown.expectMessage(
83                 CoreMatchers.not(CoreMatchers.containsString("SpecialChromeAsyncTask")));
84         new SpecialChromeAsyncTask().executeOnExecutor(executor);
85     }
86 
87     /**
88      * Test filling the queue with Chrome AsyncTasks, then add a final OS AsyncTask to
89      * overfill it and ensure the Chrome AsyncTask is the one blamed in the exception message.
90      */
91     @Test
92     @SmallTest
testChromeThreadPoolExecutorChromeAsyncTask()93     public void testChromeThreadPoolExecutorChromeAsyncTask() {
94         Executor executor =
95                 new ChromeThreadPoolExecutor(
96                         1,
97                         1,
98                         1,
99                         TimeUnit.SECONDS,
100                         new ArrayBlockingQueue<Runnable>(QUEUE_SIZE),
101                         new ThreadFactory() {
102                             @Override
103                             public Thread newThread(@NonNull Runnable r) {
104                                 return null;
105                             }
106                         });
107         for (int i = 0; i < QUEUE_SIZE; i++) {
108             new SpecialChromeAsyncTask().executeOnExecutor(executor);
109         }
110         thrown.expect(RejectedExecutionException.class);
111         thrown.expectMessage(
112                 CoreMatchers.containsString(
113                         "org.chromium.base.task.AsyncTaskTest$SpecialChromeAsyncTask"));
114         thrown.expectMessage(CoreMatchers.not(CoreMatchers.containsString("SpecialOsAsyncTask")));
115         new SpecialOsAsyncTask().executeOnExecutor(executor);
116     }
117 
118     /**
119      * Test filling the queue with android.os.AsyncTasks, then add a final ChromeAsyncTask to
120      * overfill it and ensure the OsAsyncTask is the one blamed in the exception message.
121      */
122     @Test
123     @SmallTest
testChromeThreadPoolExecutorOsAsyncTask()124     public void testChromeThreadPoolExecutorOsAsyncTask() {
125         Executor executor =
126                 new ChromeThreadPoolExecutor(
127                         1,
128                         1,
129                         1,
130                         TimeUnit.SECONDS,
131                         new ArrayBlockingQueue<Runnable>(QUEUE_SIZE),
132                         new ThreadFactory() {
133                             @Override
134                             public Thread newThread(@NonNull Runnable r) {
135                                 return null;
136                             }
137                         });
138         for (int i = 0; i < QUEUE_SIZE; i++) {
139             new SpecialOsAsyncTask().executeOnExecutor(executor);
140         }
141         thrown.expect(RejectedExecutionException.class);
142         thrown.expectMessage(
143                 CoreMatchers.containsString(
144                         "org.chromium.base.task.AsyncTaskTest$SpecialOsAsyncTask"));
145         thrown.expectMessage(
146                 CoreMatchers.not(CoreMatchers.containsString("SpecialChromeAsyncTask")));
147         new SpecialChromeAsyncTask().executeOnExecutor(executor);
148     }
149 
150     /**
151      * Test verifying that tasks which specify that they are not using onPostExecute
152      * don't trigger it.
153      */
154     @Test
155     @SmallTest
testTaskNotNeedingPostExecutionDoesNotTriggerIt()156     public void testTaskNotNeedingPostExecutionDoesNotTriggerIt() {
157         new BackgroundOnlyAsyncTask<Void>() {
158             @Override
159             protected Void doInBackground() {
160                 return null;
161             }
162             // Calling onPostExecute on this class causes failure.
163         }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
164     }
165 
166     // TODO(ksolt): do we need any post execution tests here?
167 }
168