1db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler/*
2db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * Copyright (C) 2016 The Android Open Source Project
3db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler *
4db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * Licensed under the Apache License, Version 2.0 (the "License");
5db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * you may not use this file except in compliance with the License.
6db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * You may obtain a copy of the License at
7db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler *
8db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler *      http://www.apache.org/licenses/LICENSE-2.0
9db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler *
10db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * Unless required by applicable law or agreed to in writing, software
11db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * distributed under the License is distributed on an "AS IS" BASIS,
12db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * See the License for the specific language governing permissions and
14db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler * limitations under the License
15db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler */
16db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
17db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerpackage android.support.v4.content;
18db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
19fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikasimport static org.junit.Assert.fail;
20fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikas
211c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantlerimport android.support.annotation.NonNull;
22db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport android.support.test.InstrumentationRegistry;
23754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.LargeTest;
24db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport android.support.test.runner.AndroidJUnit4;
25db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
26db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport org.junit.Test;
27db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport org.junit.runner.RunWith;
28db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
29db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport java.util.concurrent.CountDownLatch;
301c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantlerimport java.util.concurrent.Executor;
31db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport java.util.concurrent.TimeUnit;
32db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
33db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler@RunWith(AndroidJUnit4.class)
34db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerpublic class ModernAsyncTaskTest {
35db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
36db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    ModernAsyncTask mModernAsyncTask;
37db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
38db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    /**
39db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     * Test to ensure that onCancelled is always called, even if doInBackground throws an exception.
40db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     *
41db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     * @throws Throwable
42db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     */
43fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikas    @LargeTest
44db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    @Test
45db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    public void testCancellationWithException() throws Throwable {
46db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch readyToCancel = new CountDownLatch(1);
47db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch readyToThrow = new CountDownLatch(1);
48db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
49db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
50db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            @Override
51db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            public void run() {
52db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                mModernAsyncTask = new ModernAsyncTask() {
53db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    @Override
54db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    protected Object doInBackground(Object[] params) {
55db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        readyToCancel.countDown();
56db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        try {
57db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                            readyToThrow.await();
58db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        } catch (InterruptedException e) {}
59db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        // This exception is expected to be caught and ignored
60db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        throw new RuntimeException();
61db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    }
62db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
63db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    @Override
64db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    protected void onCancelled(Object o) {
65db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        calledOnCancelled.countDown();
66db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    }
67db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                };
68db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            }
69db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        });
70db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
71db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        mModernAsyncTask.execute();
72db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        if (!readyToCancel.await(5, TimeUnit.SECONDS)) {
73db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            fail("Test failure: doInBackground did not run in time.");
74db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        }
75db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        mModernAsyncTask.cancel(false);
76db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        readyToThrow.countDown();
77db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
78db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            fail("onCancelled not called!");
79db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        }
80db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    }
811c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
821c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    /**
831c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * Test to ensure that onCancelled is always called instead of onPostExecute when the exception
841c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * is not suppressed by cancelling the task.
851c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     *
861c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * @throws Throwable
871c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     */
881c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    @LargeTest
891c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    @Test
901c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    public void testException() throws Throwable {
911c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
921c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
931c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            @Override
941c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            public void run() {
951c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                mModernAsyncTask = new ModernAsyncTask() {
961c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
971c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected Object doInBackground(Object[] params) {
981c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        throw new RuntimeException();
991c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1001c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1011c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
1021c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected void onPostExecute(Object o) {
1031c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        fail("onPostExecute should not be called");
1041c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1051c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1061c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
1071c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected void onCancelled(Object o) {
1081c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        calledOnCancelled.countDown();
1091c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1101c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                };
1111c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            }
1121c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        });
1131c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1141c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        mModernAsyncTask.executeOnExecutor(new Executor() {
1151c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            @Override
1161c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            public void execute(@NonNull Runnable command) {
1171c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                try {
1181c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    command.run();
1191c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    fail("Exception not thrown");
1201c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                } catch (Throwable tr) {
1211c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    // expected
1221c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                }
1231c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            }
1241c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        });
1251c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1261c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
1271c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            fail("onCancelled not called");
1281c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        }
1291c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    }
130db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler}
131