Added test cases for EofSensorInputStream, ConnectionReleaseTriggerImpl, RequestEntityWrapper, ResponseEntityWrapper
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1405557 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
87a46db5c2
commit
d550a62fe3
|
@ -33,14 +33,8 @@ import org.apache.http.annotation.NotThreadSafe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A stream wrapper that triggers actions on {@link #close close()} and EOF.
|
* A stream wrapper that triggers actions on {@link #close close()} and EOF.
|
||||||
* Primarily used to auto-release an underlying
|
* Primarily used to auto-release an underlying managed connection when the response
|
||||||
* {@link ManagedClientConnection connection}
|
* body is consumed or no longer needed.
|
||||||
* when the response body is consumed or no longer needed.
|
|
||||||
* <p>
|
|
||||||
* This class is based on <code>AutoCloseInputStream</code> in HttpClient 3.1,
|
|
||||||
* but has notable differences. It does not allow mark/reset, distinguishes
|
|
||||||
* different kinds of event, and does not always close the underlying stream
|
|
||||||
* on EOF. That decision is left to the {@link EofSensorWatcher watcher}.
|
|
||||||
*
|
*
|
||||||
* @see EofSensorWatcher
|
* @see EofSensorWatcher
|
||||||
*
|
*
|
||||||
|
@ -87,15 +81,21 @@ public class EofSensorInputStream extends InputStream implements ConnectionRelea
|
||||||
public EofSensorInputStream(final InputStream in,
|
public EofSensorInputStream(final InputStream in,
|
||||||
final EofSensorWatcher watcher) {
|
final EofSensorWatcher watcher) {
|
||||||
if (in == null) {
|
if (in == null) {
|
||||||
throw new IllegalArgumentException
|
throw new IllegalArgumentException("Wrapped stream may not be null");
|
||||||
("Wrapped stream may not be null.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedStream = in;
|
wrappedStream = in;
|
||||||
selfClosed = false;
|
selfClosed = false;
|
||||||
eofWatcher = watcher;
|
eofWatcher = watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isSelfClosed() {
|
||||||
|
return selfClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputStream getWrappedStream() {
|
||||||
|
return wrappedStream;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the underlying stream can be read from.
|
* Checks whether the underlying stream can be read from.
|
||||||
*
|
*
|
||||||
|
@ -148,18 +148,7 @@ public class EofSensorInputStream extends InputStream implements ConnectionRelea
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int read(byte[] b) throws IOException {
|
public int read(byte[] b) throws IOException {
|
||||||
int l = -1;
|
return read(b, 0, b.length);
|
||||||
|
|
||||||
if (isReadAllowed()) {
|
|
||||||
try {
|
|
||||||
l = wrappedStream.read(b);
|
|
||||||
checkEOF(l);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
checkAbort();
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -95,8 +95,22 @@ class ConnectionReleaseTriggerImpl implements ConnectionReleaseTrigger, Cancella
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.released = true;
|
this.released = true;
|
||||||
|
if (this.reusable) {
|
||||||
this.manager.releaseConnection(this.managedConn,
|
this.manager.releaseConnection(this.managedConn,
|
||||||
this.state, this.validDuration, this.tunit);
|
this.state, this.validDuration, this.tunit);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
this.managedConn.close();
|
||||||
|
log.debug("Connection discarded");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
if (this.log.isDebugEnabled()) {
|
||||||
|
this.log.debug(ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.manager.releaseConnection(
|
||||||
|
this.managedConn, null, 0, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,7 @@
|
||||||
|
|
||||||
package org.apache.http.impl.client.builder;
|
package org.apache.http.impl.client.builder;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
|
||||||
|
|
||||||
import org.apache.http.annotation.NotThreadSafe;
|
import org.apache.http.annotation.NotThreadSafe;
|
||||||
|
|
||||||
|
@ -44,10 +40,8 @@ import org.apache.http.ProtocolException;
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
import org.apache.http.RequestLine;
|
import org.apache.http.RequestLine;
|
||||||
import org.apache.http.client.methods.HttpUriRequest;
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.entity.HttpEntityWrapper;
|
|
||||||
import org.apache.http.message.AbstractHttpMessage;
|
import org.apache.http.message.AbstractHttpMessage;
|
||||||
import org.apache.http.message.BasicRequestLine;
|
import org.apache.http.message.BasicRequestLine;
|
||||||
import org.apache.http.params.HttpProtocolParams;
|
|
||||||
import org.apache.http.protocol.HTTP;
|
import org.apache.http.protocol.HTTP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,34 +56,22 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
private final HttpRequest original;
|
private final HttpRequest original;
|
||||||
|
|
||||||
private URI uri;
|
private URI uri;
|
||||||
private String method;
|
|
||||||
private ProtocolVersion version;
|
|
||||||
private HttpHost virtualHost;
|
private HttpHost virtualHost;
|
||||||
|
|
||||||
private HttpRequestWrapper(
|
private HttpRequestWrapper(final HttpRequest request) {
|
||||||
final ProtocolVersion version,
|
|
||||||
final URI uri,
|
|
||||||
final String method,
|
|
||||||
final HttpRequest request) {
|
|
||||||
super();
|
super();
|
||||||
this.original = request;
|
this.original = request;
|
||||||
this.uri = uri;
|
if (request instanceof HttpUriRequest) {
|
||||||
this.method = method;
|
this.uri = ((HttpUriRequest) request).getURI();
|
||||||
this.version = version;
|
} else {
|
||||||
|
this.uri = null;
|
||||||
|
}
|
||||||
setParams(request.getParams());
|
setParams(request.getParams());
|
||||||
setHeaders(request.getAllHeaders());
|
setHeaders(request.getAllHeaders());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProtocolVersion getProtocolVersion() {
|
public ProtocolVersion getProtocolVersion() {
|
||||||
if (this.version != null) {
|
return this.original.getProtocolVersion();
|
||||||
return this.version;
|
|
||||||
} else {
|
|
||||||
return HttpProtocolParams.getVersion(getParams());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProtocolVersion(final ProtocolVersion version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public URI getURI() {
|
public URI getURI() {
|
||||||
|
@ -101,18 +83,18 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestLine getRequestLine() {
|
public RequestLine getRequestLine() {
|
||||||
|
ProtocolVersion version = this.original.getRequestLine().getProtocolVersion();
|
||||||
|
String method = this.original.getRequestLine().getMethod();
|
||||||
String uritext = null;
|
String uritext = null;
|
||||||
if (this.uri != null) {
|
if (this.uri != null) {
|
||||||
uritext = uri.toASCIIString();
|
uritext = this.uri.toASCIIString();
|
||||||
|
} else {
|
||||||
|
uritext = this.original.getRequestLine().getUri();
|
||||||
}
|
}
|
||||||
if (uritext == null || uritext.length() == 0) {
|
if (uritext == null || uritext.length() == 0) {
|
||||||
uritext = "/";
|
uritext = "/";
|
||||||
}
|
}
|
||||||
return new BasicRequestLine(this.method, uritext, getProtocolVersion());
|
return new BasicRequestLine(method, uritext, version);
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethod() {
|
|
||||||
return this.method;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpRequest getOriginal() {
|
public HttpRequest getOriginal() {
|
||||||
|
@ -133,22 +115,17 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.method + " " + this.uri + " " + this.headergroup;
|
return getRequestLine() + " " + this.headergroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class HttpEntityEnclosingRequestWrapper extends HttpRequestWrapper
|
static class HttpEntityEnclosingRequestWrapper extends HttpRequestWrapper
|
||||||
implements HttpEntityEnclosingRequest {
|
implements HttpEntityEnclosingRequest {
|
||||||
|
|
||||||
private HttpEntity entity;
|
private HttpEntity entity;
|
||||||
private boolean consumed;
|
|
||||||
|
|
||||||
public HttpEntityEnclosingRequestWrapper(
|
public HttpEntityEnclosingRequestWrapper(final HttpEntityEnclosingRequest request)
|
||||||
final ProtocolVersion version,
|
|
||||||
final URI uri,
|
|
||||||
final String method,
|
|
||||||
final HttpEntityEnclosingRequest request)
|
|
||||||
throws ProtocolException {
|
throws ProtocolException {
|
||||||
super(version, uri, method, request);
|
super(request);
|
||||||
setEntity(request.getEntity());
|
setEntity(request.getEntity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +134,7 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEntity(final HttpEntity entity) {
|
public void setEntity(final HttpEntity entity) {
|
||||||
this.entity = entity != null ? new EntityWrapper(entity) : null;
|
this.entity = entity != null ? new RequestEntityWrapper(entity) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean expectContinue() {
|
public boolean expectContinue() {
|
||||||
|
@ -167,32 +144,7 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRepeatable() {
|
public boolean isRepeatable() {
|
||||||
return this.entity == null || this.entity.isRepeatable() || !this.consumed;
|
return this.entity == null || this.entity.isRepeatable();
|
||||||
}
|
|
||||||
|
|
||||||
class EntityWrapper extends HttpEntityWrapper {
|
|
||||||
|
|
||||||
EntityWrapper(final HttpEntity entity) {
|
|
||||||
super(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void consumeContent() throws IOException {
|
|
||||||
consumed = true;
|
|
||||||
super.consumeContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getContent() throws IOException {
|
|
||||||
return super.getContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(final OutputStream outstream) throws IOException {
|
|
||||||
consumed = true;
|
|
||||||
super.writeTo(outstream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -201,28 +153,10 @@ class HttpRequestWrapper extends AbstractHttpMessage implements HttpRequest {
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
ProtocolVersion version;
|
|
||||||
URI uri;
|
|
||||||
String method;
|
|
||||||
if (request instanceof HttpUriRequest) {
|
|
||||||
version = ((HttpUriRequest) request).getProtocolVersion();
|
|
||||||
uri = ((HttpUriRequest) request).getURI();
|
|
||||||
method = ((HttpUriRequest) request).getMethod();
|
|
||||||
} else {
|
|
||||||
RequestLine requestLine = request.getRequestLine();
|
|
||||||
version = request.getProtocolVersion();
|
|
||||||
try {
|
|
||||||
uri = new URI(requestLine.getUri());
|
|
||||||
} catch (URISyntaxException ex) {
|
|
||||||
throw new ProtocolException("Invalid request URI: " + requestLine.getUri(), ex);
|
|
||||||
}
|
|
||||||
method = request.getRequestLine().getMethod();
|
|
||||||
}
|
|
||||||
if (request instanceof HttpEntityEnclosingRequest) {
|
if (request instanceof HttpEntityEnclosingRequest) {
|
||||||
return new HttpEntityEnclosingRequestWrapper(version, uri, method,
|
return new HttpEntityEnclosingRequestWrapper((HttpEntityEnclosingRequest) request);
|
||||||
(HttpEntityEnclosingRequest) request);
|
|
||||||
} else {
|
} else {
|
||||||
return new HttpRequestWrapper(version, uri, method, request);
|
return new HttpRequestWrapper(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ class ProtocolExec implements ClientExecChain {
|
||||||
final HttpRoute route) throws ProtocolException {
|
final HttpRoute route) throws ProtocolException {
|
||||||
try {
|
try {
|
||||||
URI uri = request.getURI();
|
URI uri = request.getURI();
|
||||||
|
if (uri != null) {
|
||||||
if (route.getProxyHost() != null && !route.isTunnelled()) {
|
if (route.getProxyHost() != null && !route.isTunnelled()) {
|
||||||
// Make sure the request URI is absolute
|
// Make sure the request URI is absolute
|
||||||
if (!uri.isAbsolute()) {
|
if (!uri.isAbsolute()) {
|
||||||
|
@ -95,6 +96,7 @@ class ProtocolExec implements ClientExecChain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request.setURI(uri);
|
request.setURI(uri);
|
||||||
|
}
|
||||||
} catch (URISyntaxException ex) {
|
} catch (URISyntaxException ex) {
|
||||||
throw new ProtocolException("Invalid URI: " +
|
throw new ProtocolException("Invalid URI: " +
|
||||||
request.getRequestLine().getUri(), ex);
|
request.getRequestLine().getUri(), ex);
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.apache.http.impl.client.builder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.annotation.NotThreadSafe;
|
||||||
|
import org.apache.http.entity.HttpEntityWrapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper class for {@link HttpEntity} enclosed in a request message.
|
||||||
|
*
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
@NotThreadSafe
|
||||||
|
class RequestEntityWrapper extends HttpEntityWrapper {
|
||||||
|
|
||||||
|
private boolean consumed = false;
|
||||||
|
|
||||||
|
RequestEntityWrapper(final HttpEntity entity) {
|
||||||
|
super(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRepeatable() {
|
||||||
|
if (!this.consumed) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return super.isRepeatable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public void consumeContent() throws IOException {
|
||||||
|
consumed = true;
|
||||||
|
super.consumeContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(final OutputStream outstream) throws IOException {
|
||||||
|
consumed = true;
|
||||||
|
super.writeTo(outstream);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConsumed() {
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -37,10 +37,9 @@ import org.apache.http.annotation.NotThreadSafe;
|
||||||
import org.apache.http.conn.EofSensorInputStream;
|
import org.apache.http.conn.EofSensorInputStream;
|
||||||
import org.apache.http.conn.EofSensorWatcher;
|
import org.apache.http.conn.EofSensorWatcher;
|
||||||
import org.apache.http.entity.HttpEntityWrapper;
|
import org.apache.http.entity.HttpEntityWrapper;
|
||||||
import org.apache.http.util.EntityUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper class for {@link HttpEntity} encloded in a response message.
|
* A wrapper class for {@link HttpEntity} enclosed in a response message.
|
||||||
*
|
*
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +65,6 @@ class ResponseEntityWrapper extends HttpEntityWrapper implements EofSensorWatche
|
||||||
if (this.connReleaseTrigger != null) {
|
if (this.connReleaseTrigger != null) {
|
||||||
try {
|
try {
|
||||||
if (this.connReleaseTrigger.isReusable()) {
|
if (this.connReleaseTrigger.isReusable()) {
|
||||||
EntityUtils.consume(this.wrappedEntity);
|
|
||||||
this.connReleaseTrigger.releaseConnection();
|
this.connReleaseTrigger.releaseConnection();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -93,8 +91,12 @@ class ResponseEntityWrapper extends HttpEntityWrapper implements EofSensorWatche
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(final OutputStream outstream) throws IOException {
|
public void writeTo(final OutputStream outstream) throws IOException {
|
||||||
|
try {
|
||||||
this.wrappedEntity.writeTo(outstream);
|
this.wrappedEntity.writeTo(outstream);
|
||||||
releaseConnection();
|
releaseConnection();
|
||||||
|
} finally {
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean eofDetected(final InputStream wrapped) throws IOException {
|
public boolean eofDetected(final InputStream wrapped) throws IOException {
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.conn;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
public class TestEofSensorInputStream {
|
||||||
|
|
||||||
|
private InputStream instream;
|
||||||
|
private EofSensorWatcher eofwatcher;
|
||||||
|
private EofSensorInputStream eofstream;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
instream = Mockito.mock(InputStream.class);
|
||||||
|
eofwatcher = Mockito.mock(EofSensorWatcher.class);
|
||||||
|
eofstream = new EofSensorInputStream(instream, eofwatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClose() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamClosed(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
|
||||||
|
eofstream.close();
|
||||||
|
|
||||||
|
Assert.assertTrue(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(eofwatcher).streamClosed(instream);
|
||||||
|
|
||||||
|
eofstream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCloseIOError() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamClosed(Mockito.<InputStream>any())).thenThrow(new IOException());
|
||||||
|
|
||||||
|
try {
|
||||||
|
eofstream.close();
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Assert.assertTrue(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher).streamClosed(instream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReleaseConnection() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamClosed(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
|
||||||
|
eofstream.releaseConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(eofwatcher).streamClosed(instream);
|
||||||
|
|
||||||
|
eofstream.releaseConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbortConnection() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamAbort(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
|
||||||
|
eofstream.abortConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(eofwatcher).streamAbort(instream);
|
||||||
|
|
||||||
|
eofstream.abortConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbortConnectionIOError() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamAbort(Mockito.<InputStream>any())).thenThrow(new IOException());
|
||||||
|
|
||||||
|
try {
|
||||||
|
eofstream.abortConnection();
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Assert.assertTrue(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher).streamAbort(instream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
Mockito.when(instream.read()).thenReturn(0, -1);
|
||||||
|
|
||||||
|
Assert.assertEquals(0, eofstream.read());
|
||||||
|
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNotNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
|
||||||
|
|
||||||
|
Assert.assertEquals(-1, eofstream.read());
|
||||||
|
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(eofwatcher).eofDetected(instream);
|
||||||
|
|
||||||
|
Assert.assertEquals(-1, eofstream.read());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadIOError() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
Mockito.when(instream.read()).thenThrow(new IOException());
|
||||||
|
|
||||||
|
try {
|
||||||
|
eofstream.read();
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher).streamAbort(instream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadByteArray() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
|
||||||
|
.thenReturn(1, -1);
|
||||||
|
|
||||||
|
byte[] tmp = new byte[1];
|
||||||
|
|
||||||
|
Assert.assertEquals(1, eofstream.read(tmp));
|
||||||
|
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNotNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher, Mockito.never()).eofDetected(instream);
|
||||||
|
|
||||||
|
Assert.assertEquals(-1, eofstream.read(tmp));
|
||||||
|
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(eofwatcher).eofDetected(instream);
|
||||||
|
|
||||||
|
Assert.assertEquals(-1, eofstream.read(tmp));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadByteArrayIOError() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.eofDetected(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
Mockito.when(instream.read(Mockito.<byte []>any(), Mockito.anyInt(), Mockito.anyInt()))
|
||||||
|
.thenThrow(new IOException());
|
||||||
|
|
||||||
|
byte[] tmp = new byte[1];
|
||||||
|
try {
|
||||||
|
eofstream.read(tmp);
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Assert.assertFalse(eofstream.isSelfClosed());
|
||||||
|
Assert.assertNull(eofstream.getWrappedStream());
|
||||||
|
|
||||||
|
Mockito.verify(eofwatcher).streamAbort(instream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadAfterAbort() throws Exception {
|
||||||
|
Mockito.when(eofwatcher.streamAbort(Mockito.<InputStream>any())).thenReturn(true);
|
||||||
|
|
||||||
|
eofstream.abortConnection();
|
||||||
|
|
||||||
|
try {
|
||||||
|
eofstream.read();
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
byte[] tmp = new byte[1];
|
||||||
|
try {
|
||||||
|
eofstream.read(tmp);
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.impl.client.builder;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.http.HttpClientConnection;
|
||||||
|
import org.apache.http.conn.HttpClientConnectionManager;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
public class TestConnectionReleaseTriggerImpl {
|
||||||
|
|
||||||
|
private Log log;
|
||||||
|
private HttpClientConnectionManager mgr;
|
||||||
|
private HttpClientConnection conn;
|
||||||
|
private ConnectionReleaseTriggerImpl releaseTrigger;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
log = Mockito.mock(Log.class);
|
||||||
|
mgr = Mockito.mock(HttpClientConnectionManager.class);
|
||||||
|
conn = Mockito.mock(HttpClientConnection.class);
|
||||||
|
releaseTrigger = new ConnectionReleaseTriggerImpl(log, mgr, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbortConnection() throws Exception {
|
||||||
|
releaseTrigger.abortConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(releaseTrigger.isReleased());
|
||||||
|
|
||||||
|
Mockito.verify(conn).shutdown();
|
||||||
|
Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
releaseTrigger.abortConnection();
|
||||||
|
|
||||||
|
Mockito.verify(conn, Mockito.times(1)).shutdown();
|
||||||
|
Mockito.verify(mgr, Mockito.times(1)).releaseConnection(
|
||||||
|
Mockito.<HttpClientConnection>any(),
|
||||||
|
Mockito.anyObject(),
|
||||||
|
Mockito.anyLong(),
|
||||||
|
Mockito.<TimeUnit>any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAbortConnectionIOError() throws Exception {
|
||||||
|
Mockito.doThrow(new IOException()).when(conn).shutdown();
|
||||||
|
|
||||||
|
releaseTrigger.abortConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(releaseTrigger.isReleased());
|
||||||
|
|
||||||
|
Mockito.verify(conn).shutdown();
|
||||||
|
Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCancell() throws Exception {
|
||||||
|
Assert.assertTrue(releaseTrigger.cancel());
|
||||||
|
|
||||||
|
Assert.assertTrue(releaseTrigger.isReleased());
|
||||||
|
|
||||||
|
Mockito.verify(conn).shutdown();
|
||||||
|
Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
Assert.assertFalse(releaseTrigger.cancel());
|
||||||
|
|
||||||
|
Mockito.verify(conn, Mockito.times(1)).shutdown();
|
||||||
|
Mockito.verify(mgr, Mockito.times(1)).releaseConnection(
|
||||||
|
Mockito.<HttpClientConnection>any(),
|
||||||
|
Mockito.anyObject(),
|
||||||
|
Mockito.anyLong(),
|
||||||
|
Mockito.<TimeUnit>any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReleaseConnectionReusable() throws Exception {
|
||||||
|
releaseTrigger.setState("some state");
|
||||||
|
releaseTrigger.setValidFor(100, TimeUnit.SECONDS);
|
||||||
|
releaseTrigger.markReusable();
|
||||||
|
|
||||||
|
releaseTrigger.releaseConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(releaseTrigger.isReleased());
|
||||||
|
|
||||||
|
Mockito.verify(conn, Mockito.never()).close();
|
||||||
|
Mockito.verify(mgr).releaseConnection(conn, "some state", 100, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
releaseTrigger.releaseConnection();
|
||||||
|
|
||||||
|
Mockito.verify(mgr, Mockito.times(1)).releaseConnection(
|
||||||
|
Mockito.<HttpClientConnection>any(),
|
||||||
|
Mockito.anyObject(),
|
||||||
|
Mockito.anyLong(),
|
||||||
|
Mockito.<TimeUnit>any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReleaseConnectionNonReusable() throws Exception {
|
||||||
|
releaseTrigger.setState("some state");
|
||||||
|
releaseTrigger.setValidFor(100, TimeUnit.SECONDS);
|
||||||
|
releaseTrigger.markNonReusable();
|
||||||
|
|
||||||
|
releaseTrigger.releaseConnection();
|
||||||
|
|
||||||
|
Assert.assertTrue(releaseTrigger.isReleased());
|
||||||
|
|
||||||
|
Mockito.verify(conn, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(mgr).releaseConnection(conn, null, 0, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
|
releaseTrigger.releaseConnection();
|
||||||
|
|
||||||
|
Mockito.verify(mgr, Mockito.times(1)).releaseConnection(
|
||||||
|
Mockito.<HttpClientConnection>any(),
|
||||||
|
Mockito.anyObject(),
|
||||||
|
Mockito.anyLong(),
|
||||||
|
Mockito.<TimeUnit>any());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.impl.client.builder;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
public class TestRequestEntityWrapper {
|
||||||
|
|
||||||
|
private HttpEntity entity;
|
||||||
|
private RequestEntityWrapper wrapper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
entity = Mockito.mock(HttpEntity.class);;
|
||||||
|
wrapper = new RequestEntityWrapper(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonRepeatableEntityWriteTo() throws Exception {
|
||||||
|
Mockito.when(entity.isRepeatable()).thenReturn(false);
|
||||||
|
|
||||||
|
Assert.assertTrue(wrapper.isRepeatable());
|
||||||
|
|
||||||
|
OutputStream outstream = Mockito.mock(OutputStream.class);
|
||||||
|
wrapper.writeTo(outstream);
|
||||||
|
|
||||||
|
Assert.assertTrue(wrapper.isConsumed());
|
||||||
|
Assert.assertFalse(wrapper.isRepeatable());
|
||||||
|
|
||||||
|
Mockito.verify(entity).writeTo(outstream);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.impl.client.builder;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.SocketException;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
public class TestResponseEntityWrapper {
|
||||||
|
|
||||||
|
private InputStream instream;
|
||||||
|
private HttpEntity entity;
|
||||||
|
private ConnectionReleaseTriggerImpl releaseTrigger;
|
||||||
|
private ResponseEntityWrapper wrapper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
instream = Mockito.mock(InputStream.class);
|
||||||
|
entity = Mockito.mock(HttpEntity.class);;
|
||||||
|
Mockito.when(entity.getContent()).thenReturn(instream);
|
||||||
|
releaseTrigger = Mockito.mock(ConnectionReleaseTriggerImpl.class);
|
||||||
|
wrapper = new ResponseEntityWrapper(entity, releaseTrigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityStreamClosed() throws Exception {
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
EntityUtils.consume(wrapper);
|
||||||
|
|
||||||
|
Mockito.verify(instream, Mockito.times(1)).close();
|
||||||
|
Mockito.verify(releaseTrigger).releaseConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityStreamClosedIOError() throws Exception {
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
Mockito.doThrow(new IOException()).when(instream).close();
|
||||||
|
try {
|
||||||
|
EntityUtils.consume(wrapper);
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Mockito.verify(releaseTrigger).abortConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntityStreamClosedIOErrorAlreadyReleased() throws Exception {
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReleased()).thenReturn(true);
|
||||||
|
Mockito.doThrow(new SocketException()).when(instream).close();
|
||||||
|
EntityUtils.consume(wrapper);
|
||||||
|
Mockito.verify(releaseTrigger).abortConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityWriteTo() throws Exception {
|
||||||
|
OutputStream outstream = Mockito.mock(OutputStream.class);
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
wrapper.writeTo(outstream);
|
||||||
|
Mockito.verify(releaseTrigger).releaseConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityWriteToIOError() throws Exception {
|
||||||
|
OutputStream outstream = Mockito.mock(OutputStream.class);
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
Mockito.doThrow(new IOException()).when(entity).writeTo(outstream);
|
||||||
|
try {
|
||||||
|
wrapper.writeTo(outstream);
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Mockito.verify(releaseTrigger, Mockito.never()).releaseConnection();
|
||||||
|
Mockito.verify(releaseTrigger).abortConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityEndOfStream() throws Exception {
|
||||||
|
Mockito.when(instream.read()).thenReturn(-1);
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
InputStream content = wrapper.getContent();
|
||||||
|
Assert.assertEquals(-1, content.read());
|
||||||
|
Mockito.verify(instream).close();
|
||||||
|
Mockito.verify(releaseTrigger).releaseConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReusableEntityEndOfStreamIOError() throws Exception {
|
||||||
|
Mockito.when(instream.read()).thenReturn(-1);
|
||||||
|
Mockito.when(entity.isStreaming()).thenReturn(true);
|
||||||
|
Mockito.when(releaseTrigger.isReusable()).thenReturn(true);
|
||||||
|
Mockito.doThrow(new IOException()).when(instream).close();
|
||||||
|
InputStream content = wrapper.getContent();
|
||||||
|
try {
|
||||||
|
content.read();
|
||||||
|
Assert.fail("IOException expected");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
}
|
||||||
|
Mockito.verify(releaseTrigger).abortConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,7 +25,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.http.conn;
|
package org.apache.http.impl.client.integration;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
Loading…
Reference in New Issue