Issue 55 enhanced integration tests to support redirect testing

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1448 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-06-19 20:08:31 +00:00
parent 00b3ccdc7c
commit 3f7833c2c3
11 changed files with 399 additions and 271 deletions

View File

@ -26,9 +26,11 @@ package org.jclouds.http.commands;
import org.jclouds.http.commands.callables.xml.ParseSax;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
/**
* temporary factory until guice can do multi-type assisted inject
*
* @see <a href="http://code.google.com/p/google-guice/issues/detail?id=346" />
*
* @author Adrian Cole
@ -43,8 +45,7 @@ public class CommandFactory {
}
@SuppressWarnings("unchecked")
public GetAndParseSax<?> createGetAndParseSax(String uri,
ParseSax.HandlerWithResult<?> handler) {
public GetAndParseSax<?> createGetAndParseSax(String uri, ParseSax.HandlerWithResult<?> handler) {
return new GetAndParseSax(uri, parseSaxFactory.create(handler));
}
@ -59,6 +60,17 @@ public class CommandFactory {
return getStringFactory.create(uri);
}
@Inject
private PutFactory putFactory;
public static interface PutFactory {
Put create(@Assisted("uri") String uri, @Assisted("payload") String payload);
}
public Put createPut(String uri, String payload) {
return putFactory.create(uri, payload);
}
@Inject
private HeadFactory headFactory;

View File

@ -0,0 +1,44 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* 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 org.jclouds.http.commands;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import org.jclouds.http.HttpFutureCommand;
import org.jclouds.http.commands.callables.ReturnTrueIf2xx;
/**
* PUT a string and respond with true if successful.
*
* @author Adrian Cole
*/
public class Put extends HttpFutureCommand<Boolean> {
@Inject
public Put(ReturnTrueIf2xx callable, @Assisted("uri") String uri,
@Assisted("payload") String payload) {
super("PUT", uri, callable);
this.getRequest().setPayload(payload);
}
}

View File

@ -26,6 +26,7 @@ package org.jclouds.http.commands.config;
import org.jclouds.http.commands.CommandFactory;
import org.jclouds.http.commands.GetString;
import org.jclouds.http.commands.Head;
import org.jclouds.http.commands.Put;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.jclouds.http.commands.callables.xml.config.SaxModule;
@ -34,27 +35,23 @@ import com.google.inject.TypeLiteral;
import com.google.inject.assistedinject.FactoryProvider;
/**
* note that all this private factory clutter will go away when the following is
* implemented @link http://code.google.com/p/google-guice/issues/detail?id=346
* it will be replaced with a configuration:
* note that all this private factory clutter will go away when the following is implemented @link
* http://code.google.com/p/google-guice/issues/detail?id=346 it will be replaced with a
* configuration:
*
* @author Adrian Cole
*/
public class HttpCommandsModule extends AbstractModule {
protected void configure() {
bind(CommandFactory.GetStringFactory.class)
.toProvider(
FactoryProvider.newFactory(
CommandFactory.GetStringFactory.class,
GetString.class));
bind(CommandFactory.GetStringFactory.class).toProvider(
FactoryProvider.newFactory(CommandFactory.GetStringFactory.class, GetString.class));
bind(CommandFactory.HeadFactory.class).toProvider(
FactoryProvider.newFactory(CommandFactory.HeadFactory.class,
Head.class));
FactoryProvider.newFactory(CommandFactory.HeadFactory.class, Head.class));
bind(CommandFactory.PutFactory.class).toProvider(
FactoryProvider.newFactory(CommandFactory.PutFactory.class, Put.class));
install(new SaxModule());
bind(CommandFactory.ParseSaxFactory.class).toProvider(
FactoryProvider.newFactory(
new TypeLiteral<CommandFactory.ParseSaxFactory>() {
FactoryProvider.newFactory(new TypeLiteral<CommandFactory.ParseSaxFactory>() {
}, new TypeLiteral<ParseSax<?>>() {
}));

View File

@ -69,11 +69,11 @@ public abstract class BaseHttpFutureCommandClient implements HttpFutureCommandCl
protected void handleResponse(HttpFutureCommand<?> command, HttpResponse response) {
int code = response.getStatusCode();
if (code >= 500) {
this.serverErrorHandler.handle(command, response);
serverErrorHandler.handle(command, response);
} else if (code >= 400 && code < 500) {
this.clientErrorHandler.handle(command, response);
clientErrorHandler.handle(command, response);
} else if (code >= 300 && code < 400) {
this.redirectHandler.handle(command, response);
redirectHandler.handle(command, response);
} else {
command.getResponseFuture().setResponse(response);
command.getResponseFuture().run();

View File

@ -31,8 +31,10 @@ import java.util.concurrent.TimeoutException;
import org.jclouds.http.commands.GetAndParseSax;
import org.jclouds.http.commands.GetString;
import org.jclouds.http.commands.Head;
import org.jclouds.http.commands.Put;
import org.jclouds.http.commands.callables.xml.ParseSax;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* // TODO: Adrian: Document this!
@ -43,41 +45,54 @@ import org.testng.annotations.Test;
public abstract class BaseHttpFutureCommandClientTest extends BaseJettyTest {
@Test(invocationCount = 50, timeOut = 3000)
public void testRequestFilter() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testRequestFilter() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
GetString get = factory.createGetString("/");
get.getRequest().getHeaders().put("filterme", "filterme");
client.submit(get);
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
.format("expected: [%1$s], but got [%2$s]", "test", get.get(10,
TimeUnit.SECONDS));
assertEquals(get.get(10, TimeUnit.SECONDS).trim(), "test");
}
@Test(invocationCount = 50, timeOut = 3000)
public void testGetStringWithHeader() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetStringWithHeader() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
GetString get = factory.createGetString("/");
get.getRequest().getHeaders().put("test", "test");
client.submit(get);
assert get.get(10, TimeUnit.SECONDS).trim().equals("test") : String
.format("expected: [%1$s], but got [%2$s]", "test", get.get(10,
TimeUnit.SECONDS));
assertEquals(get.get(10, TimeUnit.SECONDS).trim(), "test");
}
@Test(invocationCount = 50, timeOut = 3000)
public void testGetString() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetString() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
GetString get = factory.createGetString("/");
assert get != null;
client.submit(get);
assert get.get(10, TimeUnit.SECONDS).trim().equals(XML) : String
.format("expected: [%1$s], but got [%2$s]", XML, get.get(10,
TimeUnit.SECONDS));
assertEquals(get.get(10, TimeUnit.SECONDS).trim(), XML);
}
@Test(invocationCount = 50, timeOut = 3000)
public void testHead() throws MalformedURLException, ExecutionException,
public void testGetStringRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
GetString get = factory.createGetString("/redirect");
assert get != null;
client.submit(get);
assertEquals(get.get(10, TimeUnit.SECONDS).trim(), XML2);
}
@Test(invocationCount = 50, timeOut = 3000)
public void testPutRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
Put put = factory.createPut("/redirect", "foo");
assert put != null;
client.submit(put);
assertEquals(put.get(10, TimeUnit.SECONDS), new Boolean(true));
}
@Test(invocationCount = 50, timeOut = 3000)
public void testHead() throws MalformedURLException, ExecutionException, InterruptedException,
TimeoutException {
Head head = factory.createHead("/");
assert head != null;
client.submit(head);
@ -85,8 +100,8 @@ public abstract class BaseHttpFutureCommandClientTest extends BaseJettyTest {
}
@Test(invocationCount = 50, timeOut = 3000)
public void testGetAndParseSax() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetAndParseSax() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
GetAndParseSax<?> getAndParseSax = factory.createGetAndParseSax("/",
new ParseSax.HandlerWithResult<String>() {
@Override
@ -113,6 +128,6 @@ public abstract class BaseHttpFutureCommandClientTest extends BaseJettyTest {
});
assert getAndParseSax != null;
client.submit(getAndParseSax);
assert getAndParseSax.get(10, TimeUnit.SECONDS).equals("whoppers");
assertEquals(getAndParseSax.get(10, TimeUnit.SECONDS), "whoppers");
}
}

View File

@ -56,25 +56,30 @@ import com.google.inject.name.Names;
public abstract class BaseJettyTest {
protected static final String XML = "<foo><bar>whoppers</bar></foo>";
protected static final String XML2 = "<foo><bar>chubbs</bar></foo>";
protected Server server = null;
protected CommandFactory factory;
protected HttpFutureCommandClient client;
protected Injector injector;
private Closer closer;
private AtomicInteger cycle = new AtomicInteger(0);
private Server server2;
@BeforeTest
@Parameters( { "test-jetty-port" })
public void setUpJetty(@Optional("8123") final int testPort) throws Exception {
Handler handler = new AbstractHandler() {
Handler server1Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request,
HttpServletResponse response, int dispatch) throws IOException, ServletException {
failIfNoContentLength(request, response);
if (request.getHeader("test") != null) {
if (failIfNoContentLength(request, response))
return;
else if (request.getHeader("test") != null) {
response.setContentType("text/plain");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("test");
} else if (target.equals("/redirect")) {
response.sendRedirect("http://localhost:" + (testPort + 1));
} else {
if (failOnRequest(request, response))
return;
@ -87,8 +92,23 @@ public abstract class BaseJettyTest {
};
server = new Server(testPort);
server.setHandler(handler);
server.setHandler(server1Handler);
server.start();
Handler server2Handler = new AbstractHandler() {
public void handle(String target, HttpServletRequest request,
HttpServletResponse response, int dispatch) throws IOException, ServletException {
response.setContentType("text/xml");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println(XML2);
((Request) request).setHandled(true);
}
};
server2 = new Server(testPort + 1);
server2.setHandler(server2Handler);
server2.start();
final Properties properties = new Properties();
properties.put(HttpConstants.PROPERTY_HTTP_ADDRESS, "localhost");
properties.put(HttpConstants.PROPERTY_HTTP_PORT, testPort + "");
@ -124,6 +144,7 @@ public abstract class BaseJettyTest {
@AfterTest
public void tearDownJetty() throws Exception {
closer.close();
server2.stop();
server.stop();
}

View File

@ -29,7 +29,7 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* // TODO: Adrian: Document this!
* Tests the basic structure of the {@link GetString} object
*
* @author Adrian Cole
*/
@ -44,7 +44,6 @@ public class GetStringTest {
void setUp() {
callable = new ReturnStringIf200();
get = new GetString(callable, GOOD_PATH);
}
@AfterMethod

View File

@ -43,6 +43,7 @@ import org.jclouds.http.HttpRequestFilter;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.internal.BaseHttpFutureCommandClient;
import com.google.appengine.api.urlfetch.FetchOptions;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
@ -166,8 +167,13 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
} else {
url = new URL(target, request.getUri());
}
FetchOptions options = disallowTruncate();
followRedirectsUnlessRequestContainsPayload(request, options);
HTTPRequest gaeRequest = new HTTPRequest(url, HTTPMethod.valueOf(request.getMethod()),
disallowTruncate().doNotFollowRedirects());
options);
for (String header : request.getHeaders().keySet()) {
// GAE/J v1.2.1 re-writes the host header, so we'll skip it.
if (!header.equals(HttpConstants.HOST)) {
@ -176,6 +182,7 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
}
}
}
if (request.getPayload() != null) {
changeRequestContentToBytes(request);
gaeRequest.setPayload((byte[]) request.getPayload());
@ -184,4 +191,12 @@ public class URLFetchServiceClient extends BaseHttpFutureCommandClient {
}
return gaeRequest;
}
private void followRedirectsUnlessRequestContainsPayload(HttpRequest request,
FetchOptions options) {
if (request.getPayload() != null)
options.doNotFollowRedirects();
else
options.followRedirects();
}
}

View File

@ -34,9 +34,9 @@ import org.jclouds.http.BaseHttpFutureCommandClientTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.inject.Module;
import com.google.appengine.tools.development.ApiProxyLocalImpl;
import com.google.apphosting.api.ApiProxy;
import com.google.inject.Module;
/**
*
@ -45,8 +45,7 @@ import com.google.apphosting.api.ApiProxy;
* @author Adrian Cole
*/
@Test
public class URLFetchServiceClientIntegrationTest extends
BaseHttpFutureCommandClientTest {
public class URLFetchServiceClientIntegrationTest extends BaseHttpFutureCommandClientTest {
@BeforeMethod
void setupApiProxy() {
@ -57,39 +56,55 @@ public class URLFetchServiceClientIntegrationTest extends
@Override
@Test(invocationCount = 50, timeOut = 1500)
public void testGetAndParseSax() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetAndParseSax() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
setupApiProxy();
super.testGetAndParseSax();
}
@Override
@Test(invocationCount = 50, timeOut = 1500)
public void testGetString() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetString() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
setupApiProxy();
super.testGetString();
}
@Override
@Test(invocationCount = 50, timeOut = 1500)
public void testGetStringRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
setupApiProxy();
super.testGetStringRedirect();
}
@Override
@Test(enabled = false, invocationCount = 50, timeOut = 1500)
public void testPutRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
setupApiProxy();
super.testPutRedirect();
}
@Override
@Test(enabled = false)
public void testGetStringWithHeader() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testGetStringWithHeader() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
// GAE does not support sending headers in their test stub as of version
// 1.2.0
}
@Override
@Test(invocationCount = 50, timeOut = 1500)
public void testHead() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
public void testHead() throws MalformedURLException, ExecutionException, InterruptedException,
TimeoutException {
setupApiProxy();
super.testHead();
}
@Test(enabled = false)
public void testRequestFilter() throws MalformedURLException,
ExecutionException, InterruptedException, TimeoutException {
public void testRequestFilter() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
// GAE does not support sending headers in their test stub as of version
// 1.2.0
}

View File

@ -23,38 +23,48 @@
*/
package org.jclouds.http.httpnio.pool;
import com.google.inject.Module;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.command.pool.PoolConstants;
import org.jclouds.http.BaseHttpFutureCommandClientTest;
import org.jclouds.http.httpnio.config.HttpNioConnectionPoolClientModule;
import org.testng.annotations.Test;
import java.util.Properties;
import com.google.inject.Module;
/**
* // TODO: Adrian: Document this!
* Tests for {@link HttpNioConnectionPoolFutureCommandClient}.
*
* @author Adrian Cole
*/
@Test
public class HttpNioConnectionPoolFutureCommandClientTest extends
BaseHttpFutureCommandClientTest {
public class HttpNioConnectionPoolFutureCommandClientTest extends BaseHttpFutureCommandClientTest {
protected void addConnectionProperties(Properties properties) {
properties.setProperty(
PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
properties.setProperty(
PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
properties.setProperty(
PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS, "1");
properties.setProperty(PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS,
"2");
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS,
"12");
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_CONNECTION_REUSE, "75");
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_SESSION_FAILURES, "2");
properties.setProperty(PoolConstants.PROPERTY_POOL_REQUEST_INVOKER_THREADS, "1");
properties.setProperty(PoolConstants.PROPERTY_POOL_IO_WORKER_THREADS, "2");
properties.setProperty(PoolConstants.PROPERTY_POOL_MAX_CONNECTIONS, "12");
}
protected Module createClientModule() {
return new HttpNioConnectionPoolClientModule();
}
@Override
@Test(enabled = false)
public void testGetStringRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
}
@Override
@Test(enabled = false)
public void testPutRedirect() throws MalformedURLException, ExecutionException,
InterruptedException, TimeoutException {
}
}