android-interop-testing: improvements for instrumentation tests (#4570)

This commit is contained in:
Eric Gribkoff 2018-06-20 08:07:31 -07:00 committed by GitHub
parent 13ca42aff6
commit 2b703342ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 31 additions and 40 deletions

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.grpc.android.integrationtest.test" >
<!-- API level 14+ is required for TLS since Google Play Services v10.2 -->
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22"/>
<instrumentation
android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="io.grpc.android.integrationtest" />
<application android:debuggable="true" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>

View File

@ -19,6 +19,7 @@ package io.grpc.android.integrationtest;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
import android.util.Log; import android.util.Log;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException; import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
@ -31,13 +32,14 @@ import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
public class InteropInstrumentationTest { public class InteropInstrumentationTest {
private static final int TIMEOUT_SECONDS = 10; private static final int TIMEOUT_SECONDS = 10;
private static String LOG_TAG = "GrpcInteropInstrumentationTest"; private static final String LOG_TAG = "GrpcInteropInstrumentationTest";
private String host; private String host;
private int port; private int port;
@ -46,6 +48,12 @@ public class InteropInstrumentationTest {
private boolean useTestCa; private boolean useTestCa;
private String testCase; private String testCase;
// Ensures Looper is initialized for tests running on API level 15. Otherwise instantiating an
// AsyncTask throws an exception.
@Rule
public ActivityTestRule<TesterActivity> activityRule =
new ActivityTestRule<TesterActivity>(TesterActivity.class);
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
host = InstrumentationRegistry.getArguments().getString("server_host", "10.0.2.2"); host = InstrumentationRegistry.getArguments().getString("server_host", "10.0.2.2");
@ -107,7 +115,6 @@ public class InteropInstrumentationTest {
new Listener() { new Listener() {
@Override @Override
public void onComplete(String result) { public void onComplete(String result) {
resultFuture.set(result); resultFuture.set(result);
} }
}; };

View File

@ -13,7 +13,8 @@
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/Base.V7.Theme.AppCompat.Light" > android:theme="@style/Base.V7.Theme.AppCompat.Light"
android:name="android.support.multidex.MultiDexApplication" >
<activity <activity
android:name=".TesterActivity" android:name=".TesterActivity"
android:label="@string/app_name" > android:label="@string/app_name" >

View File

@ -67,7 +67,7 @@ final class InteropTask extends AsyncTask<Void, Void, String> {
// Then print to the error message. // Then print to the error message.
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw)); t.printStackTrace(new PrintWriter(sw));
return "Failed... : " + t.getMessage() + "\n" + sw.toString(); return "Failed... : " + t.getMessage() + "\n" + sw;
} finally { } finally {
try { try {
tester.tearDown(); tester.tearDown();
@ -147,7 +147,7 @@ final class InteropTask extends AsyncTask<Void, Void, String> {
} }
} }
private class Tester extends AbstractInteropTest { private static class Tester extends AbstractInteropTest {
private final ManagedChannel channel; private final ManagedChannel channel;
private final List<ClientInterceptor> interceptors; private final List<ClientInterceptor> interceptors;

View File

@ -16,15 +16,11 @@
package io.grpc.android.integrationtest; package io.grpc.android.integrationtest;
import android.annotation.TargetApi;
import android.net.SSLCertificateSocketFactory;
import android.os.Build;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import io.grpc.ManagedChannel; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder; import io.grpc.ManagedChannelBuilder;
import io.grpc.okhttp.OkHttpChannelBuilder; import io.grpc.okhttp.OkHttpChannelBuilder;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Method;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.cert.CertificateFactory; import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
@ -74,37 +70,6 @@ class TesterOkHttpChannelBuilder {
return context.getSocketFactory(); return context.getSocketFactory();
} }
@TargetApi(14)
private static SSLCertificateSocketFactory getSslCertificateSocketFactory(
@Nullable InputStream testCa, String androidSocketFatoryTls) throws Exception {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH /* API level 14 */) {
throw new RuntimeException(
"android_socket_factory_tls doesn't work with API level less than 14.");
}
SSLCertificateSocketFactory factory = (SSLCertificateSocketFactory)
SSLCertificateSocketFactory.getDefault(5000 /* Timeout in ms*/);
// Use HTTP/2.0
byte[] h2 = "h2".getBytes();
byte[][] protocols = new byte[][]{h2};
if (androidSocketFatoryTls.equals("alpn")) {
Method setAlpnProtocols =
factory.getClass().getDeclaredMethod("setAlpnProtocols", byte[][].class);
setAlpnProtocols.invoke(factory, new Object[] { protocols });
} else if (androidSocketFatoryTls.equals("npn")) {
Method setNpnProtocols =
factory.getClass().getDeclaredMethod("setNpnProtocols", byte[][].class);
setNpnProtocols.invoke(factory, new Object[]{protocols});
} else {
throw new RuntimeException("Unknown protocol: " + androidSocketFatoryTls);
}
if (testCa != null) {
factory.setTrustManagers(getTrustManagers(testCa));
}
return factory;
}
private static TrustManager[] getTrustManagers(InputStream testCa) throws Exception { private static TrustManager[] getTrustManagers(InputStream testCa) throws Exception {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null); ks.load(null);