1
0
mirror of https://github.com/square/okhttp.git synced 2025-11-24 18:41:06 +03:00

Move okhttp-testing-support to Kotlin (#5906)

Moving the last big block of src/main Java code (outside of Samples).
This commit is contained in:
Yuri Schimke
2020-04-09 07:23:43 +01:00
committed by GitHub
parent 1a07f49bcb
commit b48d30aa5c
28 changed files with 949 additions and 849 deletions

View File

@@ -74,7 +74,7 @@ sealed class CallEvent {
val protocol: Protocol?
) : CallEvent() {
override fun closes(timestampNs: Long) =
ConnectStart(timestampNs, call, inetSocketAddress, proxy)
ConnectStart(timestampNs, call, inetSocketAddress, proxy)
}
data class ConnectFailed(
@@ -86,7 +86,7 @@ sealed class CallEvent {
val ioe: IOException
) : CallEvent() {
override fun closes(timestampNs: Long) =
ConnectStart(timestampNs, call, inetSocketAddress, proxy)
ConnectStart(timestampNs, call, inetSocketAddress, proxy)
}
data class SecureConnectStart(

View File

@@ -21,7 +21,10 @@ import java.net.InetSocketAddress
import java.net.Proxy
import java.util.concurrent.TimeUnit
class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (String) -> Unit) : EventListener(),
class ClientRuleEventListener(
val delegate: EventListener = NONE,
var logger: (String) -> Unit
) : EventListener(),
EventListener.Factory {
private var startNs: Long = 0
@@ -35,31 +38,49 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.callStart(call)
}
override fun proxySelectStart(call: Call, url: HttpUrl) {
override fun proxySelectStart(
call: Call,
url: HttpUrl
) {
logWithTime("proxySelectStart: $url")
delegate.proxySelectStart(call, url)
}
override fun proxySelectEnd(call: Call, url: HttpUrl, proxies: List<Proxy>) {
override fun proxySelectEnd(
call: Call,
url: HttpUrl,
proxies: List<Proxy>
) {
logWithTime("proxySelectEnd: $proxies")
delegate.proxySelectEnd(call, url, proxies)
}
override fun dnsStart(call: Call, domainName: String) {
override fun dnsStart(
call: Call,
domainName: String
) {
logWithTime("dnsStart: $domainName")
delegate.dnsStart(call, domainName)
}
override fun dnsEnd(call: Call, domainName: String, inetAddressList: List<InetAddress>) {
override fun dnsEnd(
call: Call,
domainName: String,
inetAddressList: List<InetAddress>
) {
logWithTime("dnsEnd: $inetAddressList")
delegate.dnsEnd(call, domainName, inetAddressList)
}
override fun connectStart(call: Call, inetSocketAddress: InetSocketAddress, proxy: Proxy) {
override fun connectStart(
call: Call,
inetSocketAddress: InetSocketAddress,
proxy: Proxy
) {
logWithTime("connectStart: $inetSocketAddress $proxy")
delegate.connectStart(call, inetSocketAddress, proxy)
@@ -71,7 +92,10 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.secureConnectStart(call)
}
override fun secureConnectEnd(call: Call, handshake: Handshake?) {
override fun secureConnectEnd(
call: Call,
handshake: Handshake?
) {
logWithTime("secureConnectEnd: $handshake")
delegate.secureConnectEnd(call, handshake)
@@ -100,13 +124,19 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.connectFailed(call, inetSocketAddress, proxy, protocol, ioe)
}
override fun connectionAcquired(call: Call, connection: Connection) {
override fun connectionAcquired(
call: Call,
connection: Connection
) {
logWithTime("connectionAcquired: $connection")
delegate.connectionAcquired(call, connection)
}
override fun connectionReleased(call: Call, connection: Connection) {
override fun connectionReleased(
call: Call,
connection: Connection
) {
logWithTime("connectionReleased")
delegate.connectionReleased(call, connection)
@@ -118,7 +148,10 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.requestHeadersStart(call)
}
override fun requestHeadersEnd(call: Call, request: Request) {
override fun requestHeadersEnd(
call: Call,
request: Request
) {
logWithTime("requestHeadersEnd")
delegate.requestHeadersEnd(call, request)
@@ -130,13 +163,19 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.requestBodyStart(call)
}
override fun requestBodyEnd(call: Call, byteCount: Long) {
override fun requestBodyEnd(
call: Call,
byteCount: Long
) {
logWithTime("requestBodyEnd: byteCount=$byteCount")
delegate.requestBodyEnd(call, byteCount)
}
override fun requestFailed(call: Call, ioe: IOException) {
override fun requestFailed(
call: Call,
ioe: IOException
) {
logWithTime("requestFailed: $ioe")
delegate.requestFailed(call, ioe)
@@ -148,7 +187,10 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.responseHeadersStart(call)
}
override fun responseHeadersEnd(call: Call, response: Response) {
override fun responseHeadersEnd(
call: Call,
response: Response
) {
logWithTime("responseHeadersEnd: $response")
delegate.responseHeadersEnd(call, response)
@@ -160,13 +202,19 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.responseBodyStart(call)
}
override fun responseBodyEnd(call: Call, byteCount: Long) {
override fun responseBodyEnd(
call: Call,
byteCount: Long
) {
logWithTime("responseBodyEnd: byteCount=$byteCount")
delegate.responseBodyEnd(call, byteCount)
}
override fun responseFailed(call: Call, ioe: IOException) {
override fun responseFailed(
call: Call,
ioe: IOException
) {
logWithTime("responseFailed: $ioe")
delegate.responseFailed(call, ioe)
@@ -178,7 +226,10 @@ class ClientRuleEventListener(val delegate: EventListener = NONE, var logger: (S
delegate.callEnd(call)
}
override fun callFailed(call: Call, ioe: IOException) {
override fun callFailed(
call: Call,
ioe: IOException
) {
logWithTime("callFailed: $ioe")
delegate.callFailed(call, ioe)

View File

@@ -1,78 +0,0 @@
/*
* Copyright (C) 2012 Square, Inc.
*
* 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 okhttp3;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
public final class FakeDns implements Dns {
private final Map<String, List<InetAddress>> hostAddresses = new LinkedHashMap<>();
private final List<String> requestedHosts = new ArrayList<>();
private int nextAddress = 100;
/** Sets the results for {@code hostname}. */
public FakeDns set(String hostname, List<InetAddress> addresses) {
hostAddresses.put(hostname, addresses);
return this;
}
/** Clears the results for {@code hostname}. */
public FakeDns clear(String hostname) {
hostAddresses.remove(hostname);
return this;
}
public InetAddress lookup(String hostname, int index) throws UnknownHostException {
return hostAddresses.get(hostname).get(index);
}
@Override public List<InetAddress> lookup(String hostname) throws UnknownHostException {
requestedHosts.add(hostname);
List<InetAddress> result = hostAddresses.get(hostname);
if (result != null) return result;
throw new UnknownHostException();
}
public void assertRequests(String... expectedHosts) {
assertThat(requestedHosts).containsExactly(expectedHosts);
requestedHosts.clear();
}
/** Allocates and returns {@code count} fake addresses like [255.0.0.100, 255.0.0.101]. */
public List<InetAddress> allocate(int count) {
try {
List<InetAddress> result = new ArrayList<>();
for (int i = 0; i < count; i++) {
if (nextAddress > 255) {
throw new AssertionError("too many addresses allocated");
}
result.add(InetAddress.getByAddress(
new byte[] {(byte) 255, (byte) 0, (byte) 0, (byte) nextAddress++}));
}
return result;
} catch (UnknownHostException e) {
throw new AssertionError();
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2012 Square, Inc.
*
* 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 okhttp3
import java.net.InetAddress
import java.net.UnknownHostException
import org.assertj.core.api.Assertions.assertThat
class FakeDns : Dns {
private val hostAddresses: MutableMap<String, List<InetAddress>> = mutableMapOf()
private val requestedHosts: MutableList<String> = mutableListOf()
private var nextAddress = 100
/** Sets the results for `hostname`. */
operator fun set(
hostname: String,
addresses: List<InetAddress>
): FakeDns {
hostAddresses[hostname] = addresses
return this
}
/** Clears the results for `hostname`. */
fun clear(hostname: String): FakeDns {
hostAddresses.remove(hostname)
return this
}
@Throws(UnknownHostException::class) fun lookup(
hostname: String,
index: Int
): InetAddress {
return hostAddresses[hostname]!!.get(index)
}
@Throws(UnknownHostException::class)
override fun lookup(hostname: String): List<InetAddress> {
requestedHosts.add(hostname)
return hostAddresses[hostname] ?: throw UnknownHostException()
}
fun assertRequests(vararg expectedHosts: String?) {
assertThat(requestedHosts).containsExactly(*expectedHosts)
requestedHosts.clear()
}
/** Allocates and returns `count` fake addresses like [255.0.0.100, 255.0.0.101]. */
fun allocate(count: Int): List<InetAddress> {
return try {
val result: MutableList<InetAddress> = mutableListOf()
for (i in 0 until count) {
if (nextAddress > 255) {
throw AssertionError("too many addresses allocated")
}
result.add(
InetAddress.getByAddress(
byteArrayOf(
255.toByte(), 0.toByte(), 0.toByte(),
nextAddress++.toByte()
)
)
)
}
result
} catch (e: UnknownHostException) {
throw AssertionError()
}
}
}

View File

@@ -13,31 +13,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3;
package okhttp3
import java.io.IOException;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.io.IOException
import java.net.Proxy
import java.net.ProxySelector
import java.net.SocketAddress
import java.net.URI
public final class FakeProxySelector extends ProxySelector {
public final List<Proxy> proxies = new ArrayList<>();
class FakeProxySelector : ProxySelector() {
val proxies: MutableList<Proxy> = mutableListOf()
public FakeProxySelector addProxy(Proxy proxy) {
proxies.add(proxy);
return this;
fun addProxy(proxy: Proxy): FakeProxySelector {
proxies.add(proxy)
return this
}
@Override public List<Proxy> select(URI uri) {
override fun select(uri: URI): List<Proxy> {
// Don't handle 'socket' schemes, which the RI's Socket class may request (for SOCKS).
return uri.getScheme().equals("http") || uri.getScheme().equals("https") ? proxies
: Collections.singletonList(Proxy.NO_PROXY);
return if (uri.scheme == "http" || uri.scheme == "https") proxies else listOf(Proxy.NO_PROXY)
}
@Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
override fun connectFailed(
uri: URI,
sa: SocketAddress,
ioe: IOException
) {
}
}

View File

@@ -1,141 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You 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 okhttp3;
import java.security.Principal;
import java.security.cert.Certificate;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.security.cert.X509Certificate;
public final class FakeSSLSession implements SSLSession {
private final Certificate[] certificates;
public FakeSSLSession(Certificate... certificates) throws Exception {
this.certificates = certificates;
}
@Override
public int getApplicationBufferSize() {
throw new UnsupportedOperationException();
}
@Override
public String getCipherSuite() {
throw new UnsupportedOperationException();
}
@Override
public long getCreationTime() {
throw new UnsupportedOperationException();
}
@Override
public byte[] getId() {
throw new UnsupportedOperationException();
}
@Override
public long getLastAccessedTime() {
throw new UnsupportedOperationException();
}
@Override
public Certificate[] getLocalCertificates() {
throw new UnsupportedOperationException();
}
@Override
public Principal getLocalPrincipal() {
throw new UnsupportedOperationException();
}
@Override
public int getPacketBufferSize() {
throw new UnsupportedOperationException();
}
@Override
public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
if (certificates.length == 0) {
throw new SSLPeerUnverifiedException("peer not authenticated");
} else {
return certificates;
}
}
@Override
public X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException {
throw new UnsupportedOperationException();
}
@Override
public String getPeerHost() {
throw new UnsupportedOperationException();
}
@Override
public int getPeerPort() {
throw new UnsupportedOperationException();
}
@Override
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
throw new UnsupportedOperationException();
}
@Override
public String getProtocol() {
throw new UnsupportedOperationException();
}
@Override
public SSLSessionContext getSessionContext() {
throw new UnsupportedOperationException();
}
@Override
public void putValue(String s, Object obj) {
throw new UnsupportedOperationException();
}
@Override
public void removeValue(String s) {
throw new UnsupportedOperationException();
}
@Override
public Object getValue(String s) {
throw new UnsupportedOperationException();
}
@Override
public String[] getValueNames() {
throw new UnsupportedOperationException();
}
@Override
public void invalidate() {
throw new UnsupportedOperationException();
}
@Override
public boolean isValid() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,123 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You 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 okhttp3
import java.security.Principal
import java.security.cert.Certificate
import javax.net.ssl.SSLPeerUnverifiedException
import javax.net.ssl.SSLSession
import javax.net.ssl.SSLSessionContext
import javax.security.cert.X509Certificate
class FakeSSLSession(vararg val certificates: Certificate) : SSLSession {
override fun getApplicationBufferSize(): Int {
throw UnsupportedOperationException()
}
override fun getCipherSuite(): String {
throw UnsupportedOperationException()
}
override fun getCreationTime(): Long {
throw UnsupportedOperationException()
}
override fun getId(): ByteArray {
throw UnsupportedOperationException()
}
override fun getLastAccessedTime(): Long {
throw UnsupportedOperationException()
}
override fun getLocalCertificates(): Array<Certificate> {
throw UnsupportedOperationException()
}
override fun getLocalPrincipal(): Principal {
throw UnsupportedOperationException()
}
override fun getPacketBufferSize(): Int {
throw UnsupportedOperationException()
}
@Suppress("UNCHECKED_CAST")
@Throws(SSLPeerUnverifiedException::class)
override fun getPeerCertificates(): Array<Certificate> {
return if (certificates.isEmpty()) {
throw SSLPeerUnverifiedException("peer not authenticated")
} else {
certificates as Array<Certificate>
}
}
@Throws(
SSLPeerUnverifiedException::class
)
override fun getPeerCertificateChain(): Array<X509Certificate> {
throw UnsupportedOperationException()
}
override fun getPeerHost(): String {
throw UnsupportedOperationException()
}
override fun getPeerPort(): Int {
throw UnsupportedOperationException()
}
@Throws(SSLPeerUnverifiedException::class)
override fun getPeerPrincipal(): Principal {
throw UnsupportedOperationException()
}
override fun getProtocol(): String {
throw UnsupportedOperationException()
}
override fun getSessionContext(): SSLSessionContext {
throw UnsupportedOperationException()
}
override fun putValue(
s: String,
obj: Any
) {
throw UnsupportedOperationException()
}
override fun removeValue(s: String) {
throw UnsupportedOperationException()
}
override fun getValue(s: String): Any {
throw UnsupportedOperationException()
}
override fun getValueNames(): Array<String> {
throw UnsupportedOperationException()
}
override fun invalidate() {
throw UnsupportedOperationException()
}
override fun isValid(): Boolean {
throw UnsupportedOperationException()
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3;
import java.io.IOException;
import javax.annotation.Nullable;
import okio.BufferedSink;
public class ForwardingRequestBody extends RequestBody {
private final RequestBody delegate;
public ForwardingRequestBody(RequestBody delegate) {
if (delegate == null) throw new IllegalArgumentException("delegate == null");
this.delegate = delegate;
}
public final RequestBody delegate() {
return delegate;
}
@Override public @Nullable MediaType contentType() {
return delegate.contentType();
}
@Override public long contentLength() throws IOException {
return delegate.contentLength();
}
@Override public void writeTo(BufferedSink sink) throws IOException {
delegate.writeTo(sink);
}
@Override public boolean isDuplex() {
return delegate.isDuplex();
}
@Override public String toString() {
return getClass().getSimpleName() + "(" + delegate.toString() + ")";
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3
import java.io.IOException
import okio.BufferedSink
open class ForwardingRequestBody(delegate: RequestBody?) : RequestBody() {
private val delegate: RequestBody
fun delegate(): RequestBody {
return delegate
}
override fun contentType(): MediaType? {
return delegate.contentType()
}
@Throws(IOException::class) override fun contentLength(): Long {
return delegate.contentLength()
}
@Throws(IOException::class)
override fun writeTo(sink: BufferedSink) {
delegate.writeTo(sink)
}
override fun isDuplex(): Boolean {
return delegate.isDuplex()
}
override fun toString(): String {
return javaClass.simpleName + "(" + delegate.toString() + ")"
}
init {
requireNotNull(delegate) { "delegate == null" }
this.delegate = delegate
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3;
import javax.annotation.Nullable;
import okio.BufferedSource;
public class ForwardingResponseBody extends ResponseBody {
private final ResponseBody delegate;
public ForwardingResponseBody(ResponseBody delegate) {
if (delegate == null) throw new IllegalArgumentException("delegate == null");
this.delegate = delegate;
}
public final ResponseBody delegate() {
return delegate;
}
@Override public @Nullable MediaType contentType() {
return delegate.contentType();
}
@Override public long contentLength() {
return delegate.contentLength();
}
@Override public BufferedSource source() {
return delegate.source();
}
@Override public String toString() {
return getClass().getSimpleName() + "(" + delegate.toString() + ")";
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3
import okio.BufferedSource
open class ForwardingResponseBody(delegate: ResponseBody?) : ResponseBody() {
private val delegate: ResponseBody
fun delegate(): ResponseBody {
return delegate
}
override fun contentType(): MediaType? {
return delegate.contentType()
}
override fun contentLength(): Long {
return delegate.contentLength()
}
override fun source(): BufferedSource {
return delegate.source()
}
override fun toString(): String {
return javaClass.simpleName + "(" + delegate.toString() + ")"
}
init {
requireNotNull(delegate) { "delegate == null" }
this.delegate = delegate
}
}

View File

@@ -44,7 +44,8 @@ class OkHttpClientTestRule : TestRule {
}
fun wrap(eventListenerFactory: EventListener.Factory) = object : EventListener.Factory {
override fun create(call: Call) = ClientRuleEventListener(eventListenerFactory.create(call)) { addEvent(it) }
override fun create(call: Call) =
ClientRuleEventListener(eventListenerFactory.create(call)) { addEvent(it) }
}
/**
@@ -102,7 +103,10 @@ class OkHttpClientTestRule : TestRule {
}
}
override fun apply(base: Statement, description: Description): Statement {
override fun apply(
base: Statement,
description: Description
): Statement {
return object : Statement() {
override fun evaluate() {
val defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler()

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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 okhttp3;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.List;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
public final class RecordingCookieJar implements CookieJar {
private final Deque<List<Cookie>> requestCookies = new ArrayDeque<>();
private final Deque<List<Cookie>> responseCookies = new ArrayDeque<>();
public void enqueueRequestCookies(Cookie... cookies) {
requestCookies.add(asList(cookies));
}
public List<Cookie> takeResponseCookies() {
return responseCookies.removeFirst();
}
public void assertResponseCookies(String... cookies) {
List<Cookie> actualCookies = takeResponseCookies();
List<String> actualCookieStrings = new ArrayList<>();
for (Cookie cookie : actualCookies) {
actualCookieStrings.add(cookie.toString());
}
assertThat(actualCookieStrings).containsExactly(cookies);
}
@Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
responseCookies.add(cookies);
}
@Override public List<Cookie> loadForRequest(HttpUrl url) {
if (requestCookies.isEmpty()) return Collections.emptyList();
return requestCookies.removeFirst();
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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 okhttp3
import java.util.ArrayDeque
import java.util.Deque
import org.assertj.core.api.Assertions.assertThat
class RecordingCookieJar : CookieJar {
private val requestCookies: Deque<List<Cookie>> = ArrayDeque()
private val responseCookies: Deque<List<Cookie>> = ArrayDeque()
fun enqueueRequestCookies(vararg cookies: Cookie) {
requestCookies.add(cookies.toList())
}
fun takeResponseCookies(): List<Cookie> {
return responseCookies.removeFirst()
}
fun assertResponseCookies(vararg cookies: String?) {
assertThat(takeResponseCookies().map(Cookie::toString)).containsExactly(*cookies)
}
override fun saveFromResponse(
url: HttpUrl,
cookies: List<Cookie>
) {
responseCookies.add(cookies)
}
override fun loadForRequest(url: HttpUrl): List<Cookie> {
return if (requestCookies.isEmpty()) emptyList() else requestCookies.removeFirst()
}
}

View File

@@ -90,7 +90,10 @@ open class RecordingEventListener : EventListener() {
* @param elapsedMs the time in milliseconds elapsed since the immediately-preceding event, or
* -1L to take any duration.
*/
fun takeEvent(eventClass: Class<*>? = null, elapsedMs: Long = -1L): CallEvent {
fun takeEvent(
eventClass: Class<*>? = null,
elapsedMs: Long = -1L
): CallEvent {
val result = eventSequence.remove()
val actualElapsedNs = result.timestampNs - (lastTimestampNs ?: result.timestampNs)
lastTimestampNs = result.timestampNs
@@ -100,7 +103,10 @@ open class RecordingEventListener : EventListener() {
}
if (elapsedMs != -1L) {
assertThat(TimeUnit.NANOSECONDS.toMillis(actualElapsedNs).toDouble())
assertThat(
TimeUnit.NANOSECONDS.toMillis(actualElapsedNs)
.toDouble()
)
.isCloseTo(elapsedMs.toDouble(), Offset.offset(100.0))
}

View File

@@ -13,19 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okhttp3;
package okhttp3
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import javax.net.ssl.HostnameVerifier
import javax.net.ssl.SSLSession
public final class RecordingHostnameVerifier implements HostnameVerifier {
public final List<String> calls = new ArrayList<>();
class RecordingHostnameVerifier : HostnameVerifier {
@JvmField
val calls: MutableList<String> = mutableListOf()
@Override
public synchronized boolean verify(String hostname, SSLSession session) {
calls.add("verify " + hostname);
return true;
@Synchronized override fun verify(
hostname: String,
session: SSLSession
): Boolean {
calls.add("verify $hostname")
return true
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2018 Square, Inc.
*
* 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 okhttp3;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import okhttp3.internal.http2.Header;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeNoException;
public final class TestUtil {
public static final InetSocketAddress UNREACHABLE_ADDRESS
= new InetSocketAddress("198.51.100.1", 8080);
private TestUtil() {
}
public static List<Header> headerEntries(String... elements) {
List<Header> result = new ArrayList<>(elements.length / 2);
for (int i = 0; i < elements.length; i += 2) {
result.add(new Header(elements[i], elements[i + 1]));
}
return result;
}
public static String repeat(char c, int count) {
char[] array = new char[count];
Arrays.fill(array, c);
return new String(array);
}
/**
* See FinalizationTester for discussion on how to best trigger GC in tests.
* https://android.googlesource.com/platform/libcore/+/master/support/src/test/java/libcore/
* java/lang/ref/FinalizationTester.java
*/
public static void awaitGarbageCollection() throws Exception {
Runtime.getRuntime().gc();
Thread.sleep(100);
System.runFinalization();
}
public static void assumeNetwork() {
try {
InetAddress.getByName("www.google.com");
} catch (UnknownHostException uhe) {
assumeNoException(uhe);
}
}
public static void assumeNotWindows() {
boolean isWindows = false;
try {
String osName = System.getProperty("os.name");
isWindows = osName.startsWith("Windows");
} catch (final Exception ex) {
// Any exception means this is not a Windows system
// or we do not have permissions to check
}
assumeFalse("This test fails on Windows.", isWindows);
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2018 Square, Inc.
*
* 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 okhttp3
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.UnknownHostException
import java.util.Arrays
import okhttp3.internal.http2.Header
import org.junit.Assume
object TestUtil {
@JvmField
val UNREACHABLE_ADDRESS = InetSocketAddress("198.51.100.1", 8080)
@JvmStatic
fun headerEntries(vararg elements: String?): List<Header> {
return List(elements.size / 2) { Header(elements[it * 2]!!, elements[it * 2 + 1]!!) }
}
@JvmStatic
fun repeat(
c: Char,
count: Int
): String {
val array = CharArray(count)
Arrays.fill(array, c)
return String(array)
}
/**
* See FinalizationTester for discussion on how to best trigger GC in tests.
* https://android.googlesource.com/platform/libcore/+/master/support/src/test/java/libcore/
* java/lang/ref/FinalizationTester.java
*/
@Throws(Exception::class)
@JvmStatic
fun awaitGarbageCollection() {
Runtime.getRuntime().gc()
Thread.sleep(100)
System.runFinalization()
}
@JvmStatic
fun assumeNetwork() {
try {
InetAddress.getByName("www.google.com")
} catch (uhe: UnknownHostException) {
Assume.assumeNoException(uhe)
}
}
@JvmStatic
fun assumeNotWindows() {
var isWindows = false
try {
val osName = System.getProperty("os.name")
isWindows = osName.startsWith("Windows")
} catch (ex: Exception) {
// Any exception means this is not a Windows system
// or we do not have permissions to check
}
Assume.assumeFalse("This test fails on Windows.", isWindows)
}
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3;
import java.io.IOException;
import okio.Buffer;
import okio.BufferedSink;
import okio.ByteString;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;
/** Rewrites the request body sent to the server to be all uppercase. */
public final class UppercaseRequestInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
return chain.proceed(uppercaseRequest(chain.request()));
}
/** Returns a request that transforms {@code request} to be all uppercase. */
private Request uppercaseRequest(Request request) {
RequestBody uppercaseBody = new ForwardingRequestBody(request.body()) {
@Override public void writeTo(BufferedSink sink) throws IOException {
delegate().writeTo(Okio.buffer(uppercaseSink(sink)));
}
};
return request.newBuilder()
.method(request.method(), uppercaseBody)
.build();
}
private Sink uppercaseSink(Sink sink) {
return new ForwardingSink(sink) {
@Override public void write(Buffer source, long byteCount) throws IOException {
ByteString bytes = source.readByteString(byteCount);
delegate().write(new Buffer().write(bytes.toAsciiUppercase()), byteCount);
}
};
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3
import java.io.IOException
import okhttp3.Interceptor.Chain
import okio.Buffer
import okio.BufferedSink
import okio.ForwardingSink
import okio.Sink
import okio.buffer
/** Rewrites the request body sent to the server to be all uppercase. */
class UppercaseRequestInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Chain): Response {
return chain.proceed(uppercaseRequest(chain.request()))
}
/** Returns a request that transforms `request` to be all uppercase. */
private fun uppercaseRequest(request: Request): Request {
val uppercaseBody: RequestBody = object : ForwardingRequestBody(request.body) {
@Throws(IOException::class)
override fun writeTo(sink: BufferedSink) {
delegate().writeTo(uppercaseSink(sink).buffer())
}
}
return request.newBuilder()
.method(request.method, uppercaseBody)
.build()
}
private fun uppercaseSink(sink: Sink): Sink {
return object : ForwardingSink(sink) {
@Throws(IOException::class)
override fun write(
source: Buffer,
byteCount: Long
) {
val bytes = source.readByteString(byteCount)
delegate.write(
Buffer()
.write(bytes.toAsciiUppercase()), byteCount
)
}
}
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3;
import java.io.IOException;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
/** Rewrites the response body returned from the server to be all uppercase. */
public final class UppercaseResponseInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
return uppercaseResponse(chain.proceed(chain.request()));
}
private Response uppercaseResponse(Response response) {
ResponseBody uppercaseBody = new ForwardingResponseBody(response.body()) {
@Override public BufferedSource source() {
return Okio.buffer(uppercaseSource(delegate().source()));
}
};
return response.newBuilder()
.body(uppercaseBody)
.build();
}
private ForwardingSource uppercaseSource(BufferedSource source) {
return new ForwardingSource(source) {
@Override public long read(Buffer sink, long byteCount) throws IOException {
Buffer buffer = new Buffer();
long read = delegate().read(buffer, byteCount);
if (read != -1L) sink.write(buffer.readByteString().toAsciiUppercase());
return read;
}
};
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3
import java.io.IOException
import okhttp3.Interceptor.Chain
import okio.Buffer
import okio.BufferedSource
import okio.ForwardingSource
import okio.buffer
/** Rewrites the response body returned from the server to be all uppercase. */
class UppercaseResponseInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Chain): Response {
return uppercaseResponse(chain.proceed(chain.request()))
}
private fun uppercaseResponse(response: Response): Response {
val uppercaseBody: ResponseBody =
object : ForwardingResponseBody(response.body) {
override fun source(): BufferedSource {
return uppercaseSource(delegate().source()).buffer()
}
}
return response.newBuilder()
.body(uppercaseBody)
.build()
}
private fun uppercaseSource(source: BufferedSource): ForwardingSource {
return object : ForwardingSource(source) {
@Throws(IOException::class)
override fun read(
sink: Buffer,
byteCount: Long
): Long {
val buffer = Buffer()
val read = delegate.read(buffer, byteCount)
if (read != -1L) {
sink.write(buffer.readByteString().toAsciiUppercase())
}
return read
}
}
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3.internal.duplex;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.BufferedSink;
import static junit.framework.TestCase.assertTrue;
/** A duplex request body that keeps the provided sinks so they can be written to later. */
public final class AsyncRequestBody extends RequestBody {
private final BlockingQueue<BufferedSink> requestBodySinks = new LinkedBlockingQueue<>();
@Override public @Nullable MediaType contentType() {
return null;
}
@Override public void writeTo(BufferedSink sink) {
requestBodySinks.add(sink);
}
@Override public boolean isDuplex() {
return true;
}
public BufferedSink takeSink() throws InterruptedException {
BufferedSink result = requestBodySinks.poll(5, TimeUnit.SECONDS);
if (result == null) throw new AssertionError("no sink to take");
return result;
}
public void assertNoMoreSinks() {
assertTrue(requestBodySinks.isEmpty());
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2019 Square, Inc.
*
* 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 okhttp3.internal.duplex
import java.util.concurrent.BlockingQueue
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.TimeUnit.SECONDS
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.BufferedSink
import org.junit.Assert.assertTrue
/** A duplex request body that keeps the provided sinks so they can be written to later. */
class AsyncRequestBody : RequestBody() {
private val requestBodySinks: BlockingQueue<BufferedSink> = LinkedBlockingQueue()
override fun contentType(): MediaType? = null
override fun writeTo(sink: BufferedSink) {
requestBodySinks.add(sink)
}
override fun isDuplex(): Boolean = true
@Throws(InterruptedException::class)
fun takeSink(): BufferedSink {
return requestBodySinks.poll(5, SECONDS) ?: throw AssertionError("no sink to take")
}
fun assertNoMoreSinks() {
assertTrue(requestBodySinks.isEmpty())
}
}

View File

@@ -1,138 +0,0 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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 okhttp3.internal.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import okio.Buffer;
import okio.ForwardingSink;
import okio.ForwardingSource;
import okio.Sink;
import okio.Source;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
/** A simple file system where all files are held in memory. Not safe for concurrent use. */
public final class InMemoryFileSystem implements FileSystem, TestRule {
private final Map<File, Buffer> files = new LinkedHashMap<>();
private final Map<Source, File> openSources = new IdentityHashMap<>();
private final Map<Sink, File> openSinks = new IdentityHashMap<>();
@Override public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override public void evaluate() throws Throwable {
base.evaluate();
ensureResourcesClosed();
}
};
}
public void ensureResourcesClosed() {
List<String> openResources = new ArrayList<>();
for (File file : openSources.values()) {
openResources.add("Source for " + file);
}
for (File file : openSinks.values()) {
openResources.add("Sink for " + file);
}
if (!openResources.isEmpty()) {
StringBuilder builder = new StringBuilder("Resources acquired but not closed:");
for (String resource : openResources) {
builder.append("\n * ").append(resource);
}
throw new IllegalStateException(builder.toString());
}
}
@Override public Source source(File file) throws FileNotFoundException {
Buffer result = files.get(file);
if (result == null) throw new FileNotFoundException();
final Source source = result.clone();
openSources.put(source, file);
return new ForwardingSource(source) {
@Override public void close() throws IOException {
openSources.remove(source);
super.close();
}
};
}
@Override public Sink sink(File file) throws FileNotFoundException {
return sink(file, false);
}
@Override public Sink appendingSink(File file) throws FileNotFoundException {
return sink(file, true);
}
private Sink sink(File file, boolean appending) {
Buffer result = null;
if (appending) {
result = files.get(file);
}
if (result == null) {
result = new Buffer();
}
files.put(file, result);
final Sink sink = result;
openSinks.put(sink, file);
return new ForwardingSink(sink) {
@Override public void close() throws IOException {
openSinks.remove(sink);
super.close();
}
};
}
@Override public void delete(File file) throws IOException {
files.remove(file);
}
@Override public boolean exists(File file) {
return files.containsKey(file);
}
@Override public long size(File file) {
Buffer buffer = files.get(file);
return buffer != null ? buffer.size() : 0L;
}
@Override public void rename(File from, File to) throws IOException {
Buffer buffer = files.remove(from);
if (buffer == null) throw new FileNotFoundException();
files.put(to, buffer);
}
@Override public void deleteContents(File directory) throws IOException {
String prefix = directory.toString() + "/";
for (Iterator<File> i = files.keySet().iterator(); i.hasNext(); ) {
File file = i.next();
if (file.toString().startsWith(prefix)) i.remove();
}
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (C) 2015 Square, Inc.
*
* 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 okhttp3.internal.io
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
import java.util.IdentityHashMap
import okio.Buffer
import okio.ForwardingSink
import okio.ForwardingSource
import okio.Sink
import okio.Source
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
/** A simple file system where all files are held in memory. Not safe for concurrent use. */
class InMemoryFileSystem : FileSystem, TestRule {
private val files: MutableMap<File, Buffer> = mutableMapOf()
private val openSources: MutableMap<Source, File> = IdentityHashMap()
private val openSinks: MutableMap<Sink, File> = IdentityHashMap()
override fun apply(
base: Statement,
description: Description
): Statement {
return object : Statement() {
@Throws(Throwable::class) override fun evaluate() {
base.evaluate()
ensureResourcesClosed()
}
}
}
fun ensureResourcesClosed() {
val openResources: MutableList<String> = mutableListOf()
for (file in openSources.values) {
openResources.add("Source for $file")
}
for (file in openSinks.values) {
openResources.add("Sink for $file")
}
if (!openResources.isEmpty()) {
val builder =
StringBuilder("Resources acquired but not closed:")
for (resource in openResources) {
builder.append("\n * ")
.append(resource)
}
throw IllegalStateException(builder.toString())
}
}
@Throws(
FileNotFoundException::class
) override fun source(file: File): Source {
val result = files[file] ?: throw FileNotFoundException()
val source: Source = result.clone()
openSources[source] = file
return object : ForwardingSource(source) {
@Throws(IOException::class) override fun close() {
openSources.remove(source)
super.close()
}
}
}
@Throws(FileNotFoundException::class)
override fun sink(file: File): Sink {
return sink(file, false)
}
@Throws(
FileNotFoundException::class
) override fun appendingSink(file: File): Sink {
return sink(file, true)
}
private fun sink(
file: File,
appending: Boolean
): Sink {
var result: Buffer? = null
if (appending) {
result = files[file]
}
if (result == null) {
result = Buffer()
}
files[file] = result
val sink: Sink = result
openSinks[sink] = file
return object : ForwardingSink(sink) {
@Throws(IOException::class) override fun close() {
openSinks.remove(sink)
super.close()
}
}
}
@Throws(IOException::class)
override fun delete(file: File) {
files.remove(file)
}
override fun exists(file: File): Boolean {
return files.containsKey(file)
}
override fun size(file: File): Long {
val buffer = files[file]
return buffer?.size ?: 0L
}
@Throws(IOException::class) override fun rename(
from: File,
to: File
) {
val buffer = files.remove(from) ?: throw FileNotFoundException()
files[to] = buffer
}
@Throws(
IOException::class
) override fun deleteContents(directory: File) {
val prefix = "$directory/"
val i = files.keys.iterator()
while (i.hasNext()) {
val file = i.next()
if (file.toString()
.startsWith(prefix)
) i.remove()
}
}
}

View File

@@ -55,7 +55,10 @@ open class PlatformRule @JvmOverloads constructor(
) : TestRule {
private val versionChecks = mutableListOf<Pair<Matcher<out Any>, Matcher<out Any>>>()
override fun apply(base: Statement, description: org.junit.runner.Description): Statement {
override fun apply(
base: Statement,
description: org.junit.runner.Description
): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
@@ -198,83 +201,131 @@ open class PlatformRule @JvmOverloads constructor(
fun hasHttp2Support() = !isJdk8()
fun assumeConscrypt() {
assumeThat(getPlatformSystemProperty(), equalTo(
CONSCRYPT_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
CONSCRYPT_PROPERTY
)
)
}
fun assumeJdk9() {
assumeThat(getPlatformSystemProperty(), equalTo(
JDK9_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
JDK9_PROPERTY
)
)
}
fun assumeOpenJSSE() {
assumeThat(getPlatformSystemProperty(), equalTo(
OPENJSSE_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
OPENJSSE_PROPERTY
)
)
}
fun assumeJdk8() {
assumeThat(getPlatformSystemProperty(), equalTo(
JDK8_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
JDK8_PROPERTY
)
)
}
fun assumeJdk8Alpn() {
assumeThat(getPlatformSystemProperty(), equalTo(
JDK8_ALPN_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
JDK8_ALPN_PROPERTY
)
)
}
fun assumeCorretto() {
assumeThat(getPlatformSystemProperty(), equalTo(
CORRETTO_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
CORRETTO_PROPERTY
)
)
}
fun assumeBouncyCastle() {
assumeThat(getPlatformSystemProperty(), equalTo(
BOUNCYCASTLE_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
BOUNCYCASTLE_PROPERTY
)
)
}
fun assumeHttp2Support() {
assumeThat(getPlatformSystemProperty(), not(
JDK8_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
JDK8_PROPERTY
)
)
}
fun assumeNotConscrypt() {
assumeThat(getPlatformSystemProperty(), not(
CONSCRYPT_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
CONSCRYPT_PROPERTY
)
)
}
fun assumeNotJdk9() {
assumeThat(getPlatformSystemProperty(), not(
JDK9_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
JDK9_PROPERTY
)
)
}
fun assumeNotJdk8() {
assumeThat(getPlatformSystemProperty(), not(
JDK8_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
JDK8_PROPERTY
)
)
}
fun assumeNotJdk8Alpn() {
assumeThat(getPlatformSystemProperty(), not(
JDK8_ALPN_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
JDK8_ALPN_PROPERTY
)
)
}
fun assumeNotOpenJSSE() {
assumeThat(getPlatformSystemProperty(), not(
OPENJSSE_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
OPENJSSE_PROPERTY
)
)
}
fun assumeNotCorretto() {
assumeThat(getPlatformSystemProperty(), not(
CORRETTO_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
CORRETTO_PROPERTY
)
)
}
fun assumeNotBouncyCastle() {
assumeThat(getPlatformSystemProperty(), not(
BOUNCYCASTLE_PROPERTY))
assumeThat(
getPlatformSystemProperty(), not(
BOUNCYCASTLE_PROPERTY
)
)
}
fun assumeNotHttp2Support() {
assumeThat(getPlatformSystemProperty(), equalTo(
JDK8_PROPERTY))
assumeThat(
getPlatformSystemProperty(), equalTo(
JDK8_PROPERTY
)
)
}
fun assumeJettyBootEnabled() {
@@ -299,7 +350,9 @@ open class PlatformRule @JvmOverloads constructor(
System.err.println("Warning: Conscrypt not available")
}
val provider = Conscrypt.newProviderBuilder().provideTrustManager(true).build()
val provider = Conscrypt.newProviderBuilder()
.provideTrustManager(true)
.build()
Security.insertProviderAt(provider, 1)
} else if (platformSystemProperty == JDK8_ALPN_PROPERTY) {
if (!isAlpnBootEnabled()) {
@@ -385,6 +438,7 @@ open class PlatformRule @JvmOverloads constructor(
}
val isCorrettoInstalled: Boolean =
isCorrettoSupported && Security.getProviders().first().name == AmazonCorrettoCryptoProvider.PROVIDER_NAME
isCorrettoSupported && Security.getProviders()
.first().name == AmazonCorrettoCryptoProvider.PROVIDER_NAME
}
}