1db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 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
140fe4145f1077734837efbc0209f0afafe7d2b505Aurimas Liutikas * limitations under the License.
15db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler */
16db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.loader.content;
18db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
19fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikasimport static org.junit.Assert.fail;
20fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikas
21db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport android.support.test.InstrumentationRegistry;
22754cb29c50f09a83251dd4bb633ba445b2411adbAurimas Liutikasimport android.support.test.filters.LargeTest;
23db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport android.support.test.runner.AndroidJUnit4;
24db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
256160d5a551afe96c4180acf0454b5b4dbae89b9eAurimas Liutikasimport androidx.annotation.NonNull;
266160d5a551afe96c4180acf0454b5b4dbae89b9eAurimas Liutikas
27db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport org.junit.Test;
28db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport org.junit.runner.RunWith;
29db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
30db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport java.util.concurrent.CountDownLatch;
311c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantlerimport java.util.concurrent.Executor;
32db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerimport java.util.concurrent.TimeUnit;
33db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
34db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler@RunWith(AndroidJUnit4.class)
35db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantlerpublic class ModernAsyncTaskTest {
36db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
37db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    ModernAsyncTask mModernAsyncTask;
38db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
39db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    /**
40db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     * Test to ensure that onCancelled is always called, even if doInBackground throws an exception.
41db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     *
42db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     * @throws Throwable
43db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler     */
44fad2335f169d36b7b6f2c0ec8ddfe6c0094c2072Aurimas Liutikas    @LargeTest
45db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    @Test
46db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    public void testCancellationWithException() throws Throwable {
47db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch readyToCancel = new CountDownLatch(1);
48db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch readyToThrow = new CountDownLatch(1);
49db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
50db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
51db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            @Override
52db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            public void run() {
53db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                mModernAsyncTask = new ModernAsyncTask() {
54db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    @Override
55db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    protected Object doInBackground(Object[] params) {
56db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        readyToCancel.countDown();
57db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        try {
58db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                            readyToThrow.await();
590fe4145f1077734837efbc0209f0afafe7d2b505Aurimas Liutikas                        } catch (InterruptedException e) { }
60db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        // This exception is expected to be caught and ignored
61db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        throw new RuntimeException();
62db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    }
63db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
64db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    @Override
65db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    protected void onCancelled(Object o) {
66db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                        calledOnCancelled.countDown();
67db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                    }
68db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler                };
69db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            }
70db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        });
71db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler
72db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        mModernAsyncTask.execute();
73db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        if (!readyToCancel.await(5, TimeUnit.SECONDS)) {
74db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            fail("Test failure: doInBackground did not run in time.");
75db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        }
76db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        mModernAsyncTask.cancel(false);
77db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        readyToThrow.countDown();
78db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
79db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler            fail("onCancelled not called!");
80db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler        }
81db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler    }
821c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
831c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    /**
841c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * Test to ensure that onCancelled is always called instead of onPostExecute when the exception
851c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * is not suppressed by cancelling the task.
861c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     *
871c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     * @throws Throwable
881c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler     */
891c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    @LargeTest
901c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    @Test
911c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    public void testException() throws Throwable {
921c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        final CountDownLatch calledOnCancelled = new CountDownLatch(1);
931c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
941c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            @Override
951c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            public void run() {
961c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                mModernAsyncTask = new ModernAsyncTask() {
971c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
981c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected Object doInBackground(Object[] params) {
991c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        throw new RuntimeException();
1001c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1011c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1021c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
1031c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected void onPostExecute(Object o) {
1041c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        fail("onPostExecute should not be called");
1051c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1061c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1071c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    @Override
1081c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    protected void onCancelled(Object o) {
1091c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                        calledOnCancelled.countDown();
1101c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    }
1111c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                };
1121c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            }
1131c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        });
1141c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1151c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        mModernAsyncTask.executeOnExecutor(new Executor() {
1161c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            @Override
1171c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            public void execute(@NonNull Runnable command) {
1181c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                try {
1191c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    command.run();
1201c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    fail("Exception not thrown");
1211c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                } catch (Throwable tr) {
1221c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                    // expected
1231c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler                }
1241c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            }
1251c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        });
1261c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler
1271c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        if (!calledOnCancelled.await(5, TimeUnit.SECONDS)) {
1281c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler            fail("onCancelled not called");
1291c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler        }
1301c5b7649f5bf2879095b5585e0f13a6d2695d3b2Tony Mantler    }
131db7cc953f35069e445cf1dd1d59058b9b1665e5cTony Mantler}
132