Merge "Add tests for ALPN-related methods."
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
new file mode 100644
index 0000000..9f32ea5
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.function.BiFunction;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLEngineResult;
+import javax.net.ssl.SSLEngineResult.HandshakeStatus;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import junit.framework.TestCase;
+
+public class SSLEngineTest extends TestCase {
+  /**
+   * A basic SSLEngine that has no behavior beyond that of the base class.
+   */
+  private static class PlainSSLEngine extends SSLEngine {
+    @Override public SSLEngineResult wrap(ByteBuffer[] byteBuffers, int i, int i1,
+        ByteBuffer byteBuffer) throws SSLException { return null; }
+    @Override public SSLEngineResult unwrap(ByteBuffer byteBuffer, ByteBuffer[] byteBuffers,
+        int i, int i1) throws SSLException { return null; }
+    @Override public Runnable getDelegatedTask() { return null; }
+    @Override public void closeInbound() throws SSLException {}
+    @Override public boolean isInboundDone() {  return false; }
+    @Override public void closeOutbound() {}
+    @Override public boolean isOutboundDone() { return false; }
+    @Override public String[] getSupportedCipherSuites() { return new String[0]; }
+    @Override public String[] getEnabledCipherSuites() { return new String[0]; }
+    @Override public void setEnabledCipherSuites(String[] strings) {}
+    @Override public String[] getSupportedProtocols() { return new String[0]; }
+    @Override public String[] getEnabledProtocols() { return new String[0]; }
+    @Override public void setEnabledProtocols(String[] strings) {}
+    @Override public SSLSession getSession() { return null; }
+    @Override public void beginHandshake() throws SSLException {}
+    @Override public HandshakeStatus getHandshakeStatus() { return null; }
+    @Override public void setUseClientMode(boolean b) {}
+    @Override public boolean getUseClientMode() { return false; }
+    @Override public void setNeedClientAuth(boolean b) {}
+    @Override public boolean getNeedClientAuth() { return false; }
+    @Override public void setWantClientAuth(boolean b) {}
+    @Override public boolean getWantClientAuth() { return false; }
+    @Override public void setEnableSessionCreation(boolean b) {}
+    @Override public boolean getEnableSessionCreation() { return false; }
+  }
+
+  public void test_Alpn() throws Exception {
+    SSLEngine engine = new PlainSSLEngine();
+    try {
+      engine.getApplicationProtocol();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.getHandshakeApplicationProtocol();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.setHandshakeApplicationProtocolSelector(
+          new BiFunction<SSLEngine, List<String>, String>() {
+            @Override
+            public String apply(SSLEngine sslEngine, List<String> strings) {
+              return "";
+            }
+          });
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+    try {
+      engine.getHandshakeApplicationProtocolSelector();
+      fail();
+    } catch (UnsupportedOperationException expected) {
+    }
+  }
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
new file mode 100644
index 0000000..620c022
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLParametersTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.javax.net.ssl;
+
+import java.util.Arrays;
+import javax.net.ssl.SSLParameters;
+import junit.framework.TestCase;
+
+public class SSLParametersTest extends TestCase {
+
+  public void test_applicationProtocols() {
+    SSLParameters params = new SSLParameters();
+    try {
+      params.setApplicationProtocols(null);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {""});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {null});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {"h2", ""});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+    try {
+      params.setApplicationProtocols(new String[] {"h2", null});
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+
+    // Test that both setApplicationProtocols and getApplicationProtocols clone arrays properly
+    String[] protocols = new String[] {"h2"};
+    params.setApplicationProtocols(protocols);
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+    protocols[0] = "bad";
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+    protocols = params.getApplicationProtocols();
+    protocols[0] = "bad";
+    assertTrue(Arrays.equals(new String[] {"h2"}, params.getApplicationProtocols()));
+  }
+
+}
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
index fe5e1ae..0f87d14 100644
--- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java
@@ -17,6 +17,8 @@
 package libcore.javax.net.ssl;
 
 import java.io.IOException;
+import java.util.List;
+import java.util.function.BiFunction;
 import javax.net.ssl.HandshakeCompletedListener;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
@@ -24,34 +26,39 @@
 
 public class SSLSocketTest extends TestCase {
 
+    /**
+     * A basic SSLSocket that has no behavior beyond that of the base class.
+     */
+    private static class PlainSSLSocket extends SSLSocket {
+        @Override public String[] getSupportedCipherSuites() { return new String[0]; }
+        @Override public String[] getEnabledCipherSuites() { return new String[0]; }
+        @Override public void setEnabledCipherSuites(String[] strings) { }
+        @Override public String[] getSupportedProtocols() { return new String[0]; }
+        @Override public String[] getEnabledProtocols() { return new String[0]; }
+        @Override public void setEnabledProtocols(String[] strings) { }
+        @Override public SSLSession getSession() { return null; }
+        @Override public void addHandshakeCompletedListener(
+            HandshakeCompletedListener handshakeCompletedListener) { }
+        @Override public void removeHandshakeCompletedListener(
+            HandshakeCompletedListener handshakeCompletedListener) { }
+        @Override public void startHandshake() throws IOException { }
+        @Override public void setUseClientMode(boolean b) { }
+        @Override public boolean getUseClientMode() { return false; }
+        @Override public void setNeedClientAuth(boolean b) { }
+        @Override public boolean getNeedClientAuth() { return false; }
+        @Override public void setWantClientAuth(boolean b) { }
+        @Override public boolean getWantClientAuth() { return false; }
+        @Override public void setEnableSessionCreation(boolean b) { }
+        @Override public boolean getEnableSessionCreation() { return false; }
+    }
+
     // We modified the toString() of SSLSocket, and it's based on the output
     // of Socket.toString(), so we want to make sure that a change in
     // Socket.toString() doesn't cause us to output nonsense.
     public void test_SSLSocket_toString() throws Exception {
         // The actual implementation from a security provider might do something
         // special for its toString(), so we create our own implementation
-        SSLSocket socket = new SSLSocket() {
-            @Override public String[] getSupportedCipherSuites() { return new String[0]; }
-            @Override public String[] getEnabledCipherSuites() { return new String[0]; }
-            @Override public void setEnabledCipherSuites(String[] strings) { }
-            @Override public String[] getSupportedProtocols() { return new String[0]; }
-            @Override public String[] getEnabledProtocols() { return new String[0]; }
-            @Override public void setEnabledProtocols(String[] strings) { }
-            @Override public SSLSession getSession() { return null; }
-            @Override public void addHandshakeCompletedListener(
-                    HandshakeCompletedListener handshakeCompletedListener) { }
-            @Override public void removeHandshakeCompletedListener(
-                    HandshakeCompletedListener handshakeCompletedListener) { }
-            @Override public void startHandshake() throws IOException { }
-            @Override public void setUseClientMode(boolean b) { }
-            @Override public boolean getUseClientMode() { return false; }
-            @Override public void setNeedClientAuth(boolean b) { }
-            @Override public boolean getNeedClientAuth() { return false; }
-            @Override public void setWantClientAuth(boolean b) { }
-            @Override public boolean getWantClientAuth() { return false; }
-            @Override public void setEnableSessionCreation(boolean b) { }
-            @Override public boolean getEnableSessionCreation() { return false; }
-        };
+        SSLSocket socket = new PlainSSLSocket();
         assertTrue(socket.toString().startsWith("SSLSocket["));
     }
 
@@ -80,6 +87,36 @@
         }
     }
 
+    public void test_Alpn() throws Exception {
+        SSLSocket socket = new PlainSSLSocket();
+        try {
+            socket.getApplicationProtocol();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.getHandshakeApplicationProtocol();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.setHandshakeApplicationProtocolSelector(
+                new BiFunction<SSLSocket, List<String>, String>() {
+                    @Override
+                    public String apply(SSLSocket sslSocket, List<String> strings) {
+                        return "";
+                    }
+                });
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            socket.getHandshakeApplicationProtocolSelector();
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        }
+    }
+
     public static void main (String[] args) {
         new SSLSocketTest().stress_test_TestSSLSocketPair_create();
     }