| OLD | NEW | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |    1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 package org.chromium.net; |    5 package org.chromium.net; | 
|    6  |    6  | 
|    7 import android.os.ConditionVariable; |    7 import android.os.ConditionVariable; | 
|    8 import android.os.StrictMode; |    8 import android.os.StrictMode; | 
|    9  |    9  | 
|   10 import static junit.framework.Assert.assertEquals; |   10 import static junit.framework.Assert.assertEquals; | 
|   11 import static junit.framework.Assert.assertFalse; |   11 import static junit.framework.Assert.assertFalse; | 
|   12 import static junit.framework.Assert.assertNotNull; |   12 import static junit.framework.Assert.assertNotNull; | 
|   13 import static junit.framework.Assert.assertNull; |   13 import static junit.framework.Assert.assertNull; | 
|   14 import static junit.framework.Assert.assertTrue; |   14 import static junit.framework.Assert.assertTrue; | 
|   15  |   15  | 
|   16 import java.nio.ByteBuffer; |   16 import java.nio.ByteBuffer; | 
|   17 import java.util.ArrayList; |   17 import java.util.ArrayList; | 
|   18 import java.util.concurrent.Executor; |   18 import java.util.concurrent.Executor; | 
|   19 import java.util.concurrent.ExecutorService; |   19 import java.util.concurrent.ExecutorService; | 
|   20 import java.util.concurrent.Executors; |   20 import java.util.concurrent.Executors; | 
|   21 import java.util.concurrent.ThreadFactory; |   21 import java.util.concurrent.ThreadFactory; | 
 |   22 import java.util.concurrent.TimeUnit; | 
|   22  |   23  | 
|   23 /** |   24 /** | 
|   24  * Callback that tracks information from different callbacks and and has a |   25  * Callback that tracks information from different callbacks and and has a | 
|   25  * method to block thread until the request completes on another thread. |   26  * method to block thread until the request completes on another thread. | 
|   26  * Allows to cancel, block request or throw an exception from an arbitrary step. |   27  * Allows to cancel, block request or throw an exception from an arbitrary step. | 
|   27  */ |   28  */ | 
|   28 class TestUrlRequestCallback extends UrlRequest.Callback { |   29 class TestUrlRequestCallback extends UrlRequest.Callback { | 
|   29     public ArrayList<UrlResponseInfo> mRedirectResponseInfoList = new ArrayList<
     UrlResponseInfo>(); |   30     public ArrayList<UrlResponseInfo> mRedirectResponseInfoList = new ArrayList<
     UrlResponseInfo>(); | 
|   30     public ArrayList<String> mRedirectUrlList = new ArrayList<String>(); |   31     public ArrayList<String> mRedirectUrlList = new ArrayList<String>(); | 
|   31     public UrlResponseInfo mResponseInfo; |   32     public UrlResponseInfo mResponseInfo; | 
|   32     public UrlRequestException mError; |   33     public UrlRequestException mError; | 
|   33  |   34  | 
|   34     public ResponseStep mResponseStep = ResponseStep.NOTHING; |   35     public ResponseStep mResponseStep = ResponseStep.NOTHING; | 
|   35  |   36  | 
|   36     public int mRedirectCount = 0; |   37     public int mRedirectCount = 0; | 
|   37     public boolean mOnErrorCalled = false; |   38     public boolean mOnErrorCalled = false; | 
|   38     public boolean mOnCanceledCalled = false; |   39     public boolean mOnCanceledCalled = false; | 
|   39  |   40  | 
|   40     public int mHttpResponseDataLength = 0; |   41     public int mHttpResponseDataLength = 0; | 
|   41     public String mResponseAsString = ""; |   42     public String mResponseAsString = ""; | 
|   42  |   43  | 
|   43     private static final int READ_BUFFER_SIZE = 32 * 1024; |   44     private static final int READ_BUFFER_SIZE = 32 * 1024; | 
|   44  |   45  | 
|   45     // When false, the consumer is responsible for all calls into the request |   46     // When false, the consumer is responsible for all calls into the request | 
|   46     // that advance it. |   47     // that advance it. | 
|   47     private boolean mAutoAdvance = true; |   48     private boolean mAutoAdvance = true; | 
 |   49     // Whether an exception is thrown by maybeThrowCancelOrPause(). | 
 |   50     private boolean mListenerExceptionThrown; | 
|   48  |   51  | 
|   49     // Conditionally fail on certain steps. |   52     // Conditionally fail on certain steps. | 
|   50     private FailureType mFailureType = FailureType.NONE; |   53     private FailureType mFailureType = FailureType.NONE; | 
|   51     private ResponseStep mFailureStep = ResponseStep.NOTHING; |   54     private ResponseStep mFailureStep = ResponseStep.NOTHING; | 
|   52  |   55  | 
|   53     // Signals when request is done either successfully or not. |   56     // Signals when request is done either successfully or not. | 
|   54     private final ConditionVariable mDone = new ConditionVariable(); |   57     private final ConditionVariable mDone = new ConditionVariable(); | 
|   55  |   58  | 
|   56     // Signaled on each step when mAutoAdvance is false. |   59     // Signaled on each step when mAutoAdvance is false. | 
|   57     private final ConditionVariable mStepBlock = new ConditionVariable(); |   60     private final ConditionVariable mStepBlock = new ConditionVariable(); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
|   84             }); |   87             }); | 
|   85             return mExecutorThread; |   88             return mExecutorThread; | 
|   86         } |   89         } | 
|   87     } |   90     } | 
|   88  |   91  | 
|   89     public enum ResponseStep { |   92     public enum ResponseStep { | 
|   90         NOTHING, |   93         NOTHING, | 
|   91         ON_RECEIVED_REDIRECT, |   94         ON_RECEIVED_REDIRECT, | 
|   92         ON_RESPONSE_STARTED, |   95         ON_RESPONSE_STARTED, | 
|   93         ON_READ_COMPLETED, |   96         ON_READ_COMPLETED, | 
|   94         ON_SUCCEEDED |   97         ON_SUCCEEDED, | 
 |   98         ON_FAILED, | 
 |   99         ON_CANCELED, | 
|   95     } |  100     } | 
|   96  |  101  | 
|   97     public enum FailureType { |  102     public enum FailureType { | 
|   98         NONE, |  103         NONE, | 
|   99         CANCEL_SYNC, |  104         CANCEL_SYNC, | 
|  100         CANCEL_ASYNC, |  105         CANCEL_ASYNC, | 
|  101         // Same as above, but continues to advance the request after posting |  106         // Same as above, but continues to advance the request after posting | 
|  102         // the cancellation task. |  107         // the cancellation task. | 
|  103         CANCEL_ASYNC_WITHOUT_PAUSE, |  108         CANCEL_ASYNC_WITHOUT_PAUSE, | 
|  104         THROW_SYNC |  109         THROW_SYNC | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  123     } |  128     } | 
|  124  |  129  | 
|  125     public Executor getExecutor() { |  130     public Executor getExecutor() { | 
|  126         return mExecutorService; |  131         return mExecutorService; | 
|  127     } |  132     } | 
|  128  |  133  | 
|  129     public void shutdownExecutor() { |  134     public void shutdownExecutor() { | 
|  130         mExecutorService.shutdown(); |  135         mExecutorService.shutdown(); | 
|  131     } |  136     } | 
|  132  |  137  | 
 |  138     /** | 
 |  139      * Shuts down the ExecutorService and waits until it executes all posted | 
 |  140      * tasks. | 
 |  141      */ | 
 |  142     public void shutdownExecutorAndWait() { | 
 |  143         mExecutorService.shutdown(); | 
 |  144         try { | 
 |  145             // Termination shouldn't take long. Use 1 min which should be more t
     han enough. | 
 |  146             mExecutorService.awaitTermination(1, TimeUnit.MINUTES); | 
 |  147         } catch (InterruptedException e) { | 
 |  148             assertTrue("ExecutorService is interrupted while waiting for termina
     tion", false); | 
 |  149         } | 
 |  150         assertTrue(mExecutorService.isTerminated()); | 
 |  151     } | 
 |  152  | 
|  133     @Override |  153     @Override | 
|  134     public void onRedirectReceived( |  154     public void onRedirectReceived( | 
|  135             UrlRequest request, UrlResponseInfo info, String newLocationUrl) { |  155             UrlRequest request, UrlResponseInfo info, String newLocationUrl) { | 
|  136         assertEquals(mExecutorThread, Thread.currentThread()); |  156         assertEquals(mExecutorThread, Thread.currentThread()); | 
|  137         assertFalse(request.isDone()); |  157         assertFalse(request.isDone()); | 
|  138         assertTrue(mResponseStep == ResponseStep.NOTHING |  158         assertTrue(mResponseStep == ResponseStep.NOTHING | 
|  139                 || mResponseStep == ResponseStep.ON_RECEIVED_REDIRECT); |  159                 || mResponseStep == ResponseStep.ON_RECEIVED_REDIRECT); | 
|  140         assertNull(mError); |  160         assertNull(mError); | 
|  141  |  161  | 
|  142         mResponseStep = ResponseStep.ON_RECEIVED_REDIRECT; |  162         mResponseStep = ResponseStep.ON_RECEIVED_REDIRECT; | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  211     @Override |  231     @Override | 
|  212     public void onFailed(UrlRequest request, UrlResponseInfo info, UrlRequestExc
     eption error) { |  232     public void onFailed(UrlRequest request, UrlResponseInfo info, UrlRequestExc
     eption error) { | 
|  213         assertEquals(mExecutorThread, Thread.currentThread()); |  233         assertEquals(mExecutorThread, Thread.currentThread()); | 
|  214         assertTrue(request.isDone()); |  234         assertTrue(request.isDone()); | 
|  215         // Shouldn't happen after success. |  235         // Shouldn't happen after success. | 
|  216         assertTrue(mResponseStep != ResponseStep.ON_SUCCEEDED); |  236         assertTrue(mResponseStep != ResponseStep.ON_SUCCEEDED); | 
|  217         // Should happen at most once for a single request. |  237         // Should happen at most once for a single request. | 
|  218         assertFalse(mOnErrorCalled); |  238         assertFalse(mOnErrorCalled); | 
|  219         assertFalse(mOnCanceledCalled); |  239         assertFalse(mOnCanceledCalled); | 
|  220         assertNull(mError); |  240         assertNull(mError); | 
|  221         if (mFailureType == FailureType.THROW_SYNC) { |  241         if (mListenerExceptionThrown) { | 
|  222             assertEquals(UrlRequestError.LISTENER_EXCEPTION_THROWN, error.getErr
     orCode()); |  242             assertEquals(UrlRequestError.LISTENER_EXCEPTION_THROWN, error.getErr
     orCode()); | 
|  223             assertEquals(0, error.getCronetInternalErrorCode()); |  243             assertEquals(0, error.getCronetInternalErrorCode()); | 
|  224             assertEquals("Exception received from UrlRequest.Callback", error.ge
     tMessage()); |  244             assertEquals("Exception received from UrlRequest.Callback", error.ge
     tMessage()); | 
|  225             assertNotNull(error.getCause()); |  245             assertNotNull(error.getCause()); | 
|  226             assertTrue(error.getCause() instanceof IllegalStateException); |  246             assertTrue(error.getCause() instanceof IllegalStateException); | 
|  227             assertEquals("Listener Exception.", error.getCause().getMessage()); |  247             assertEquals("Listener Exception.", error.getCause().getMessage()); | 
|  228             assertFalse(error.immediatelyRetryable()); |  248             assertFalse(error.immediatelyRetryable()); | 
|  229         } |  249         } | 
|  230  |  250  | 
 |  251         mResponseStep = ResponseStep.ON_FAILED; | 
|  231         mOnErrorCalled = true; |  252         mOnErrorCalled = true; | 
|  232         mError = error; |  253         mError = error; | 
|  233         openDone(); |  254         openDone(); | 
|  234         maybeThrowCancelOrPause(request); |  255         maybeThrowCancelOrPause(request); | 
|  235     } |  256     } | 
|  236  |  257  | 
|  237     @Override |  258     @Override | 
|  238     public void onCanceled(UrlRequest request, UrlResponseInfo info) { |  259     public void onCanceled(UrlRequest request, UrlResponseInfo info) { | 
|  239         assertEquals(mExecutorThread, Thread.currentThread()); |  260         assertEquals(mExecutorThread, Thread.currentThread()); | 
|  240         assertTrue(request.isDone()); |  261         assertTrue(request.isDone()); | 
|  241         // Should happen at most once for a single request. |  262         // Should happen at most once for a single request. | 
|  242         assertFalse(mOnCanceledCalled); |  263         assertFalse(mOnCanceledCalled); | 
|  243         assertFalse(mOnErrorCalled); |  264         assertFalse(mOnErrorCalled); | 
|  244         assertNull(mError); |  265         assertNull(mError); | 
|  245  |  266  | 
 |  267         mResponseStep = ResponseStep.ON_CANCELED; | 
|  246         mOnCanceledCalled = true; |  268         mOnCanceledCalled = true; | 
|  247         openDone(); |  269         openDone(); | 
|  248         maybeThrowCancelOrPause(request); |  270         maybeThrowCancelOrPause(request); | 
|  249     } |  271     } | 
|  250  |  272  | 
|  251     public void startNextRead(UrlRequest request) { |  273     public void startNextRead(UrlRequest request) { | 
|  252         startNextRead(request, ByteBuffer.allocateDirect(READ_BUFFER_SIZE)); |  274         startNextRead(request, ByteBuffer.allocateDirect(READ_BUFFER_SIZE)); | 
|  253     } |  275     } | 
|  254  |  276  | 
|  255     public void startNextRead(UrlRequest request, ByteBuffer buffer) { |  277     public void startNextRead(UrlRequest request, ByteBuffer buffer) { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  266  |  288  | 
|  267     protected void openDone() { |  289     protected void openDone() { | 
|  268         mDone.open(); |  290         mDone.open(); | 
|  269     } |  291     } | 
|  270  |  292  | 
|  271     /** |  293     /** | 
|  272      * Returns {@code false} if the listener should continue to advance the |  294      * Returns {@code false} if the listener should continue to advance the | 
|  273      * request. |  295      * request. | 
|  274      */ |  296      */ | 
|  275     private boolean maybeThrowCancelOrPause(final UrlRequest request) { |  297     private boolean maybeThrowCancelOrPause(final UrlRequest request) { | 
 |  298         assertEquals(mExecutorThread, Thread.currentThread()); | 
|  276         if (mResponseStep != mFailureStep || mFailureType == FailureType.NONE) { |  299         if (mResponseStep != mFailureStep || mFailureType == FailureType.NONE) { | 
|  277             if (!mAutoAdvance) { |  300             if (!mAutoAdvance) { | 
|  278                 mStepBlock.open(); |  301                 mStepBlock.open(); | 
|  279                 return true; |  302                 return true; | 
|  280             } |  303             } | 
|  281             return false; |  304             return false; | 
|  282         } |  305         } | 
|  283  |  306  | 
|  284         if (mFailureType == FailureType.THROW_SYNC) { |  307         if (mFailureType == FailureType.THROW_SYNC) { | 
 |  308             assertFalse(mListenerExceptionThrown); | 
 |  309             mListenerExceptionThrown = true; | 
|  285             throw new IllegalStateException("Listener Exception."); |  310             throw new IllegalStateException("Listener Exception."); | 
|  286         } |  311         } | 
|  287         Runnable task = new Runnable() { |  312         Runnable task = new Runnable() { | 
|  288             public void run() { |  313             public void run() { | 
|  289                 request.cancel(); |  314                 request.cancel(); | 
|  290             } |  315             } | 
|  291         }; |  316         }; | 
|  292         if (mFailureType == FailureType.CANCEL_ASYNC |  317         if (mFailureType == FailureType.CANCEL_ASYNC | 
|  293                 || mFailureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE) { |  318                 || mFailureType == FailureType.CANCEL_ASYNC_WITHOUT_PAUSE) { | 
|  294             getExecutor().execute(task); |  319             getExecutor().execute(task); | 
|  295         } else { |  320         } else { | 
|  296             task.run(); |  321             task.run(); | 
|  297         } |  322         } | 
|  298         return mFailureType != FailureType.CANCEL_ASYNC_WITHOUT_PAUSE; |  323         return mFailureType != FailureType.CANCEL_ASYNC_WITHOUT_PAUSE; | 
|  299     } |  324     } | 
|  300 } |  325 } | 
| OLD | NEW |