ModernAsyncTaskTest.java revision 1c5b7649f5bf2879095b5585e0f13a6d2695d3b2
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package android.support.v4.content;
18
19import static org.junit.Assert.fail;
20
21import android.support.annotation.NonNull;
22import android.support.test.InstrumentationRegistry;
23import android.support.test.runner.AndroidJUnit4;
24import android.test.suitebuilder.annotation.LargeTest;
25
26import org.junit.Test;
27import org.junit.runner.RunWith;
28
29import java.util.concurrent.CountDownLatch;
30import java.util.concurrent.Executor;
31import java.util.concurrent.TimeUnit;
32
33@RunWith(AndroidJUnit4.class)
34public class ModernAsyncTaskTest {
35
36    ModernAsyncTask mModernAsyncTask;
37
38    /**
39     * Test to ensure that onCancelled is always called, even if doInBackground throws an exception.
40     *
41     * @throws Throwable
42     */
43    @LargeTest
44    @Test
45    public void testCancellationWithException() throws Throwable {
46        final CountDownLatch readyToCancel = new CountDownLatch(1);
47        final CountDownLatch readyToThrow = new CountDownLatch(1);
48        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
49        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
50            @Override
51            public void run() {
52                mModernAsyncTask = new ModernAsyncTask() {
53                    @Override
54                    protected Object doInBackground(Object[] params) {
55                        readyToCancel.countDown();
56                        try {
57                            readyToThrow.await();
58                        } catch (InterruptedException e) {}
59                        // This exception is expected to be caught and ignored
60                        throw new RuntimeException();
61                    }
62
63                    @Override
64                    protected void onCancelled(Object o) {
65                        calledOnCancelled.countDown();
66                    }
67                };
68            }
69        });
70
71        mModernAsyncTask.execute();
72        if (!readyToCancel.await(5, TimeUnit.SECONDS)) {
73            fail("Test failure: doInBackground did not run in time.");
74        }
75        mModernAsyncTask.cancel(false);
76        readyToThrow.countDown();
77        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
78            fail("onCancelled not called!");
79        }
80    }
81
82    /**
83     * Test to ensure that onCancelled is always called instead of onPostExecute when the exception
84     * is not suppressed by cancelling the task.
85     *
86     * @throws Throwable
87     */
88    @LargeTest
89    @Test
90    public void testException() throws Throwable {
91        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
92        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
93            @Override
94            public void run() {
95                mModernAsyncTask = new ModernAsyncTask() {
96                    @Override
97                    protected Object doInBackground(Object[] params) {
98                        throw new RuntimeException();
99                    }
100
101                    @Override
102                    protected void onPostExecute(Object o) {
103                        fail("onPostExecute should not be called");
104                    }
105
106                    @Override
107                    protected void onCancelled(Object o) {
108                        calledOnCancelled.countDown();
109                    }
110                };
111            }
112        });
113
114        mModernAsyncTask.executeOnExecutor(new Executor() {
115            @Override
116            public void execute(@NonNull Runnable command) {
117                try {
118                    command.run();
119                    fail("Exception not thrown");
120                } catch (Throwable tr) {
121                    // expected
122                }
123            }
124        });
125
126        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
127            fail("onCancelled not called");
128        }
129    }
130}
131