Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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 
     17 package android.os.cts;
     18 
     19 import dalvik.annotation.TestLevel;
     20 import dalvik.annotation.TestTargetClass;
     21 import dalvik.annotation.TestTargetNew;
     22 import dalvik.annotation.TestTargets;
     23 
     24 import android.os.AsyncTask;
     25 import android.test.InstrumentationTestCase;
     26 import android.view.animation.cts.DelayedCheck;
     27 
     28 import java.util.concurrent.TimeUnit;
     29 
     30 @TestTargetClass(AsyncTask.class)
     31 public class AsyncTaskTest extends InstrumentationTestCase {
     32     private static final long COMPUTE_TIME = 1000;
     33     private static final long RESULT = 1000;
     34     private static final Integer[] UPDATE_VALUE = { 0, 1, 2 };
     35     private static final long DURATION = 2000;
     36     private static final String[] PARAM = { "Test" };
     37 
     38     private static MyAsyncTask mAsyncTask;
     39 
     40     @TestTargets({
     41         @TestTargetNew(
     42             level = TestLevel.COMPLETE,
     43             method = "AsyncTask",
     44             args = {}
     45         ),
     46         @TestTargetNew(
     47             level = TestLevel.COMPLETE,
     48             method = "execute",
     49             args = {Object[].class}
     50         ),
     51         @TestTargetNew(
     52             level = TestLevel.COMPLETE,
     53             method = "get",
     54             args = {}
     55         ),
     56         @TestTargetNew(
     57             level = TestLevel.COMPLETE,
     58             method = "doInBackground",
     59             args = {Object[].class}
     60         ),
     61         @TestTargetNew(
     62             level = TestLevel.COMPLETE,
     63             method = "onPreExecute",
     64             args = {}
     65         ),
     66         @TestTargetNew(
     67             level = TestLevel.COMPLETE,
     68             method = "getStatus",
     69             args = {}
     70         ),
     71         @TestTargetNew(
     72             level = TestLevel.COMPLETE,
     73             method = "onProgressUpdate",
     74             args = {Object[].class}
     75         ),
     76         @TestTargetNew(
     77             level = TestLevel.COMPLETE,
     78             method = "onPostExecute",
     79             args = {Object.class}
     80         ),
     81         @TestTargetNew(
     82             level = TestLevel.COMPLETE,
     83             method = "publishProgress",
     84             args = {Object[].class}
     85         )
     86     })
     87     public void testAsyncTask() throws Throwable {
     88         doTestAsyncTask(0);
     89     }
     90 
     91     @TestTargets({
     92         @TestTargetNew(
     93                 level = TestLevel.COMPLETE,
     94                 method = "get",
     95                 args = {long.class, TimeUnit.class}
     96             )
     97     })
     98     public void testAsyncTaskWithTimeout() throws Throwable {
     99         doTestAsyncTask(DURATION);
    100     }
    101 
    102     private void doTestAsyncTask(final long timeout) throws Throwable {
    103         startAsyncTask();
    104         if (timeout > 0) {
    105             assertEquals(RESULT, mAsyncTask.get(DURATION, TimeUnit.MILLISECONDS).longValue());
    106         } else {
    107             assertEquals(RESULT, mAsyncTask.get().longValue());
    108         }
    109 
    110         // wait for the task to finish completely (including onPostResult()).
    111         new DelayedCheck(DURATION) {
    112             protected boolean check() {
    113                 return mAsyncTask.getStatus() == AsyncTask.Status.FINISHED;
    114             }
    115         }.run();
    116 
    117         assertTrue(mAsyncTask.isOnPreExecuteCalled);
    118         assert(mAsyncTask.hasRun);
    119         assertEquals(PARAM.length, mAsyncTask.parameters.length);
    120         for (int i = 0; i < PARAM.length; i++) {
    121             assertEquals(PARAM[i], mAsyncTask.parameters[i]);
    122         }
    123         // even though the background task has run, the onPostExecute() may not have been
    124         // executed yet and the progress update may not have been processed. Wait until the task
    125         // has completed, which guarantees that onPostExecute has been called.
    126 
    127         assertEquals(RESULT, mAsyncTask.postResult.longValue());
    128         assertEquals(AsyncTask.Status.FINISHED, mAsyncTask.getStatus());
    129 
    130         if (mAsyncTask.exception != null) {
    131             throw mAsyncTask.exception;
    132         }
    133 
    134         // wait for progress update to be processed (happens asynchronously)
    135         new DelayedCheck(DURATION) {
    136             protected boolean check() {
    137                 return mAsyncTask.updateValue != null;
    138             }
    139         }.run();
    140         assertEquals(UPDATE_VALUE.length, mAsyncTask.updateValue.length);
    141         for (int i = 0; i < UPDATE_VALUE.length; i++) {
    142             assertEquals(UPDATE_VALUE[i], mAsyncTask.updateValue[i]);
    143         }
    144 
    145         runTestOnUiThread(new Runnable() {
    146             public void run() {
    147                 try {
    148                     // task should not be allowed to execute twice
    149                     mAsyncTask.execute(PARAM);
    150                     fail("Failed to throw exception!");
    151                 } catch (IllegalStateException e) {
    152                     // expected
    153                 }
    154             }
    155         });
    156     }
    157 
    158     @TestTargets({
    159         @TestTargetNew(
    160             level = TestLevel.PARTIAL_COMPLETE,
    161             method = "cancel",
    162             args = {boolean.class}
    163         ),
    164         @TestTargetNew(
    165             level = TestLevel.PARTIAL_COMPLETE,
    166             method = "isCancelled",
    167             args = {}
    168         ),
    169         @TestTargetNew(
    170             level = TestLevel.PARTIAL_COMPLETE,
    171             method = "onCancelled",
    172             args = {}
    173         )
    174     })
    175     public void testCancelWithInterrupt() throws Throwable {
    176         startAsyncTask();
    177         Thread.sleep(COMPUTE_TIME / 2);
    178         assertTrue(mAsyncTask.cancel(true));
    179         // already cancelled
    180         assertFalse(mAsyncTask.cancel(true));
    181         Thread.sleep(DURATION);
    182         assertTrue(mAsyncTask.isCancelled());
    183         assertTrue(mAsyncTask.isOnCancelledCalled);
    184         assertNotNull(mAsyncTask.exception);
    185         assertTrue(mAsyncTask.exception instanceof InterruptedException);
    186     }
    187 
    188     @TestTargets({
    189         @TestTargetNew(
    190             level = TestLevel.PARTIAL_COMPLETE,
    191             method = "cancel",
    192             args = {boolean.class}
    193         ),
    194         @TestTargetNew(
    195             level = TestLevel.PARTIAL_COMPLETE,
    196             method = "isCancelled",
    197             args = {}
    198         ),
    199         @TestTargetNew(
    200             level = TestLevel.PARTIAL_COMPLETE,
    201             method = "onCancelled",
    202             args = {}
    203         )
    204     })
    205     public void testCancel() throws Throwable {
    206         startAsyncTask();
    207         Thread.sleep(COMPUTE_TIME / 2);
    208         assertTrue(mAsyncTask.cancel(false));
    209         // already cancelled
    210         assertFalse(mAsyncTask.cancel(false));
    211         Thread.sleep(DURATION);
    212         assertTrue(mAsyncTask.isCancelled());
    213         assertTrue(mAsyncTask.isOnCancelledCalled);
    214         assertNull(mAsyncTask.exception);
    215     }
    216 
    217     @TestTargets({
    218         @TestTargetNew(
    219             level = TestLevel.PARTIAL_COMPLETE,
    220             method = "cancel",
    221             args = {boolean.class}
    222         ),
    223         @TestTargetNew(
    224             level = TestLevel.PARTIAL_COMPLETE,
    225             method = "isCancelled",
    226             args = {}
    227         ),
    228         @TestTargetNew(
    229             level = TestLevel.PARTIAL_COMPLETE,
    230             method = "onCancelled",
    231             args = {}
    232         )
    233     })
    234     public void testCancelTooLate() throws Throwable {
    235         startAsyncTask();
    236         Thread.sleep(DURATION);
    237         assertFalse(mAsyncTask.cancel(false));
    238         assertFalse(mAsyncTask.isCancelled());
    239         assertFalse(mAsyncTask.isOnCancelledCalled);
    240         assertNull(mAsyncTask.exception);
    241     }
    242 
    243     private void startAsyncTask() throws Throwable {
    244         runTestOnUiThread(new Runnable() {
    245             public void run() {
    246                 mAsyncTask = new MyAsyncTask();
    247                 assertEquals(AsyncTask.Status.PENDING, mAsyncTask.getStatus());
    248                 assertEquals(mAsyncTask, mAsyncTask.execute(PARAM));
    249                 assertEquals(AsyncTask.Status.RUNNING, mAsyncTask.getStatus());
    250             }
    251         });
    252     }
    253 
    254     private static class MyAsyncTask extends AsyncTask<String, Integer, Long> {
    255         public boolean isOnCancelledCalled;
    256         public boolean isOnPreExecuteCalled;
    257         public boolean hasRun;
    258         public Exception exception;
    259         public Long postResult;
    260         public Integer[] updateValue;
    261         public String[] parameters;
    262 
    263         @Override
    264         protected Long doInBackground(String... params) {
    265             hasRun = true;
    266             parameters = params;
    267             try {
    268                 publishProgress(UPDATE_VALUE);
    269                 Thread.sleep(COMPUTE_TIME);
    270             } catch (Exception e) {
    271                 exception = e;
    272             }
    273             return RESULT;
    274         }
    275 
    276         @Override
    277         protected void onCancelled() {
    278             super.onCancelled();
    279             isOnCancelledCalled = true;
    280         }
    281 
    282         @Override
    283         protected void onPostExecute(Long result) {
    284             super.onPostExecute(result);
    285             postResult = result;
    286         }
    287 
    288         @Override
    289         protected void onPreExecute() {
    290             super.onPreExecute();
    291             isOnPreExecuteCalled = true;
    292         }
    293 
    294         @Override
    295         protected void onProgressUpdate(Integer... values) {
    296             super.onProgressUpdate(values);
    297             updateValue = values;
    298         }
    299     }
    300 }
    301