Index: components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java |
diff --git a/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java b/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java |
index c9ed886763002b02f0e9940da48e8f7125c56048..41740a0714107e71d3264d657d51bc36daeb1f98 100644 |
--- a/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java |
+++ b/components/cronet/android/test/src/org/chromium/net/CronetTestUtil.java |
@@ -5,18 +5,26 @@ |
package org.chromium.net; |
import android.os.ConditionVariable; |
+import android.os.Handler; |
+import android.os.Looper; |
-import org.chromium.base.annotations.JNINamespace; |
-import org.chromium.net.impl.CronetUrlRequest; |
import org.json.JSONException; |
import org.json.JSONObject; |
+import org.chromium.base.annotations.CalledByNative; |
+import org.chromium.base.annotations.JNINamespace; |
+import org.chromium.net.impl.CronetUrlRequest; |
+ |
+import java.nio.ByteBuffer; |
+import java.util.concurrent.Executor; |
+ |
/** |
* Utilities for Cronet testing |
*/ |
@JNINamespace("cronet") |
public class CronetTestUtil { |
private static final ConditionVariable sHostResolverBlock = new ConditionVariable(); |
+ private static CronetEngine sCronetEngineWithPreparedNetworkThread; |
kapishnikov
2016/10/20 17:25:46
It would be great if we can avoid 'static' here.
pauljensen
2016/10/24 18:52:53
Done.
|
static final String SDCH_FAKE_HOST = "fake.sdch.domain"; |
// QUIC test domain must match the certificate used |
@@ -58,12 +66,122 @@ public class CronetTestUtil { |
} |
/** |
+ * Run {@code r} on {@code engine}'s network thread. |
+ */ |
+ public static void postToNetworkThread(final CronetEngine engine, final Runnable r) { |
+ // This method works by creating a UrlRequest with {@code engine} and using a |
+ // direct-executor to execute on {@code engine}'s network thread. The UrlRequest |
+ // goes to a bogus URL which immediately triggers {@link UrlRequest#Callback#onFailed}. |
+ |
+ // UrlRequests cannot be created on the network thread (see DCHECK in |
+ // CronetURLRequestAdapter()), so this method must first post over to the main thread, |
+ // in case it was called on the network thread. |
+ new Handler(Looper.getMainLooper()).post(new Runnable() { |
+ @Override |
+ public void run() { |
+ Executor directExecutor = new Executor() { |
+ @Override |
+ public void execute(Runnable runable) { |
+ runable.run(); |
+ } |
+ }; |
+ UrlRequest.Callback callback = new UrlRequest.Callback() { |
+ @Override |
+ public void onRedirectReceived(UrlRequest request, UrlResponseInfo responseInfo, |
+ String newLocationUrl) {} |
+ |
+ @Override |
+ public void onResponseStarted( |
+ UrlRequest request, UrlResponseInfo responseInfo) {} |
+ |
+ @Override |
+ public void onReadCompleted(UrlRequest request, UrlResponseInfo responseInfo, |
+ ByteBuffer byteBuffer) {} |
+ |
+ @Override |
+ public void onSucceeded(UrlRequest request, UrlResponseInfo responseInfo) {} |
+ |
+ @Override |
+ public void onFailed(UrlRequest request, UrlResponseInfo responseInfo, |
+ UrlRequestException error) { |
+ r.run(); |
+ } |
+ }; |
+ // Bogus empty URL will trigger onFailed() immediately. |
+ new UrlRequest.Builder("", callback, directExecutor, engine).build().start(); |
+ } |
+ }); |
+ } |
+ |
+ /** |
+ * Prepare {@code cronetEngine}'s network thread so libcronet_test code can run on it. |
+ */ |
+ public static void prepareNetworkThreadForTesting(final CronetEngine cronetEngine) { |
+ sCronetEngineWithPreparedNetworkThread = cronetEngine; |
+ final ConditionVariable initDone = new ConditionVariable(); |
+ postToNetworkThread(cronetEngine, new Runnable() { |
+ @Override |
+ public void run() { |
+ nativePrepareNetworkThreadForTesting(); |
+ initDone.open(); |
+ } |
+ }); |
+ // Don't return until network thread is prepared. Some test call |
+ // {@code cronetEngine.shutdown} immediatly after calling this function, which will fail |
+ // if postToNetworkThread() isn't finished running a UrlRequest with {@code cronetEngine}. |
+ initDone.block(); |
+ } |
+ |
+ /** |
+ * Get pointer to SingleThreadTaskRunner created by {@link #prepareNetworkThreadForTesting}. |
+ */ |
+ public static long getNativeSingleThreadTaskRunner() { |
+ return nativeGetNativeSingleThreadTaskRunner(); |
+ } |
+ |
+ /** |
+ * Clean up preparation performed by {@link #prepareNetworkThreadForTesting}. |
+ */ |
+ public static void cleanupNetorkThreadForTesting() { |
+ final ConditionVariable cleanupDone = new ConditionVariable(); |
+ postToNetworkThread(sCronetEngineWithPreparedNetworkThread, new Runnable() { |
+ @Override |
+ public void run() { |
+ nativeCleanupNetorkThreadForTesting(); |
+ cleanupDone.open(); |
+ } |
+ }); |
+ // Don't return until network thread is cleaned up. Some test call |
+ // {@code cronetEngine.shutdown} immediatly after calling this function, which will fail |
+ // if postToNetworkThread() isn't finished running a UrlRequest with {@code cronetEngine}. |
+ cleanupDone.block(); |
+ } |
+ |
+ /** |
+ * Execute base::Closure pointed to by {@code closure} on network thread. |
+ */ |
+ @CalledByNative |
+ private static void postClosureToNetworkThread(final long closure) { |
+ CronetTestUtil.postToNetworkThread(sCronetEngineWithPreparedNetworkThread, new Runnable() { |
+ @Override |
+ public void run() { |
+ nativeRunClosure(closure); |
+ } |
+ }); |
+ } |
+ |
+ /** |
* Returns the value of load flags in |urlRequest|. |
* @param urlRequest is the UrlRequest object of interest. |
*/ |
public static int getLoadFlags(UrlRequest urlRequest) { |
- return nativeGetLoadFlags(((CronetUrlRequest) urlRequest).getUrlRequestAdapterForTesting()); |
+ return nativeGetLoadFlags(((CronetUrlRequest) urlRequest).getUrlRequestForTesting()); |
} |
private static native int nativeGetLoadFlags(long urlRequest); |
+ |
+ private static native void nativePrepareNetworkThreadForTesting(); |
kapishnikov
2016/10/20 17:25:46
A static method with no context. This limits us to
|
+ private static native long nativeGetNativeSingleThreadTaskRunner(); |
+ private static native void nativeCleanupNetorkThreadForTesting(); |
+ private static native void nativeRunClosure(long closure); |
} |