From 614cbb24c69f071388db4cba12201d1bdc10c3d8 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 21 Mar 2010 16:48:16 -0700 Subject: [PATCH] Issue 207: increased ferocity of tests to do concurrent 5MB downloads w/checksum on both http and blobstore level. --- aws/core/src/test/resources/log4j.xml | 4 +- .../internal/BaseBlobIntegrationTest.java | 90 ++++++++++++++++++ .../jclouds/encryption/EncryptionService.java | 3 +- .../internal/BaseEncryptionService.java | 12 ++- .../internal/JCEEncryptionService.java | 13 +-- ....java => BackoffLimitedRetryJavaTest.java} | 2 +- ...ommandExecutorServiceIntegrationTest.java} | 11 ++- .../java/org/jclouds/http/BaseJettyTest.java | 37 +++++++ .../http/IntegrationTestAsyncClient.java | 7 +- .../jclouds/http/IntegrationTestClient.java | 3 + ...ommandExecutorServiceIntegrationTest.java} | 2 +- core/src/test/resources/const.txt.gz | Bin 0 -> 14021 bytes ...pacheHCHttpCommandExecutorServiceTest.java | 4 +- .../BouncyCastleEncryptionService.java | 10 +- .../EnterpriseConfigurationModuleTest.java | 4 +- ...CommandExecutorServiceIntegrationTest.java | 11 ++- ...ackoffLimitedRetryJavaIntegrationTest.java | 4 +- ...formingHttpCommandExecutorServiceTest.java | 10 +- 18 files changed, 190 insertions(+), 37 deletions(-) rename core/src/test/java/org/jclouds/http/{BackoffLimitedRetryJavaIntegrationTest.java => BackoffLimitedRetryJavaTest.java} (98%) rename core/src/test/java/org/jclouds/http/{BaseHttpCommandExecutorServiceTest.java => BaseHttpCommandExecutorServiceIntegrationTest.java} (93%) rename core/src/test/java/org/jclouds/http/{JavaUrlHttpCommandExecutorServiceTest.java => JavaUrlHttpCommandExecutorServiceIntegrationTest.java} (94%) create mode 100644 core/src/test/resources/const.txt.gz diff --git a/aws/core/src/test/resources/log4j.xml b/aws/core/src/test/resources/log4j.xml index 7f04042ec6..ed303459db 100644 --- a/aws/core/src/test/resources/log4j.xml +++ b/aws/core/src/test/resources/log4j.xml @@ -138,13 +138,13 @@ - + + --> diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index ece89a8c1d..0ffed1d6b6 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -23,17 +23,21 @@ import static org.jclouds.blobstore.options.GetOptions.Builder.ifETagMatches; import static org.jclouds.blobstore.options.GetOptions.Builder.ifModifiedSince; import static org.jclouds.blobstore.options.GetOptions.Builder.ifUnmodifiedSince; import static org.jclouds.blobstore.options.GetOptions.Builder.range; +import static org.jclouds.concurrent.ConcurrentUtils.awaitCompletion; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Date; +import java.util.Map; import java.util.Set; +import java.util.zip.GZIPInputStream; import javax.ws.rs.core.MediaType; @@ -43,17 +47,103 @@ import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.util.internal.BlobStoreUtilsImpl; +import org.jclouds.encryption.EncryptionService; +import org.jclouds.encryption.EncryptionService.MD5InputStreamResult; import org.jclouds.encryption.internal.JCEEncryptionService; +import org.jclouds.http.BaseJettyTest; import org.jclouds.http.HttpResponseException; import org.jclouds.http.Payloads; +import org.jclouds.logging.Logger; import org.jclouds.util.Utils; +import org.testng.ITestContext; +import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.google.common.base.Function; +import com.google.common.collect.Maps; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.inject.Guice; + /** * @author Adrian Cole */ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { + private byte[] oneHundredOneConstitutions; + private EncryptionService encryptionService; + private byte[] oneHundredOneConstitutionsMD5; + private long oneHundredOneConstitutionsLength; + + @BeforeClass(groups = { "integration", "live" }) + @Override + public void setUpResourcesOnThisThread(ITestContext testContext) throws Exception { + encryptionService = Guice.createInjector().getInstance(EncryptionService.class); + MD5InputStreamResult result = encryptionService.generateMD5Result(getTestDataSupplier() + .getInput()); + oneHundredOneConstitutions = result.data; + oneHundredOneConstitutionsMD5 = result.md5; + oneHundredOneConstitutionsLength = result.length; + super.setUpResourcesOnThisThread(testContext); + } + + @SuppressWarnings("unchecked") + public static InputSupplier getTestDataSupplier() throws IOException { + byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class + .getResourceAsStream("/const.txt.gz"))); + InputSupplier constitutionSupplier = ByteStreams + .newInputStreamSupplier(oneConstitution); + + InputSupplier temp = ByteStreams.join(constitutionSupplier); + + for (int i = 0; i < 100; i++) { + temp = ByteStreams.join(temp, constitutionSupplier); + } + return temp; + } + + @Test(groups = { "integration", "live" }) + public void testBigFileGets() throws InterruptedException, IOException { + String containerName = getContainerName(); + try { + String key = "constitution.txt"; + + uploadConstitution(containerName, key); + Map> responses = Maps.newHashMap(); + for (int i = 0; i < 10; i++) { + + responses.put(i, Futures.compose(context.getAsyncBlobStore() + .getBlob(containerName, key), new Function() { + + @Override + public Void apply(Blob from) { + assertEquals(encryptionService.md5(from.getContent()), + oneHundredOneConstitutionsMD5); + return null; + } + + })); + } + Map exceptions = awaitCompletion(responses, exec, 30000l, + Logger.CONSOLE, "get constitution"); + assert exceptions.size() == 0 : exceptions; + + } finally { + returnContainer(containerName); + } + + } + + private void uploadConstitution(String containerName, String key) throws IOException { + Blob sourceObject = context.getBlobStore().newBlob(key); + sourceObject.getMetadata().setContentType("text/plain"); + sourceObject.getMetadata().setContentMD5(oneHundredOneConstitutionsMD5); + sourceObject.setContentLength(oneHundredOneConstitutionsLength); + sourceObject.setPayload(oneHundredOneConstitutions); + context.getBlobStore().putBlob(containerName, sourceObject); + } @Test(groups = { "integration", "live" }) public void testGetIfModifiedSince() throws InterruptedException { diff --git a/core/src/main/java/org/jclouds/encryption/EncryptionService.java b/core/src/main/java/org/jclouds/encryption/EncryptionService.java index 50fccfe921..d63e3ecb8f 100644 --- a/core/src/main/java/org/jclouds/encryption/EncryptionService.java +++ b/core/src/main/java/org/jclouds/encryption/EncryptionService.java @@ -21,7 +21,6 @@ package org.jclouds.encryption; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; @@ -57,7 +56,7 @@ public interface EncryptionService { byte[] md5(byte[] plainBytes); - byte[] md5(File toEncode); + byte[] md5(InputStream toEncode); String toBase64String(byte[] resBuf); diff --git a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java b/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java index 5430223e08..280d57509d 100755 --- a/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java +++ b/core/src/main/java/org/jclouds/encryption/internal/BaseEncryptionService.java @@ -21,6 +21,8 @@ package org.jclouds.encryption.internal; import static com.google.common.base.Preconditions.checkNotNull; import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; @@ -30,6 +32,8 @@ import java.security.NoSuchProviderException; import org.jclouds.encryption.EncryptionService; +import com.google.common.base.Throwables; + /** * * @author Adrian Cole @@ -90,9 +94,13 @@ public abstract class BaseEncryptionService implements EncryptionService { } else if (data instanceof String) { md5 = md5(((String) data).getBytes()); } else if (data instanceof File) { - md5 = md5(((File) data)); + try { + md5 = md5(new FileInputStream((File) data)); + } catch (FileNotFoundException e) { + Throwables.propagate(e); + } } else if (data instanceof InputStream) { - md5 = generateMD5Result(((InputStream) data)).md5; + md5 = md5(((InputStream) data)); } else { throw new UnsupportedOperationException("Content not supported " + data.getClass()); } diff --git a/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java b/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java index fa0d1740cc..26ffa1f8de 100644 --- a/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java +++ b/core/src/main/java/org/jclouds/encryption/internal/JCEEncryptionService.java @@ -18,8 +18,7 @@ */ package org.jclouds.encryption.internal; -import java.io.File; -import java.io.FileInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.security.InvalidKeyException; @@ -30,8 +29,6 @@ import java.security.NoSuchProviderException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; -import java.io.ByteArrayOutputStream; - import com.google.common.io.Closeables; /** @@ -78,15 +75,13 @@ public class JCEEncryptionService extends BaseEncryptionService { return eTag.digest(); } - public byte[] md5(File toEncode) { + public byte[] md5(InputStream toEncode) { MessageDigest eTag = getDigest(); byte[] buffer = new byte[1024]; int numRead = -1; - InputStream i = null; try { - i = new FileInputStream(toEncode); do { - numRead = i.read(buffer); + numRead = toEncode.read(buffer); if (numRead > 0) { eTag.update(buffer, 0, numRead); } @@ -94,7 +89,7 @@ public class JCEEncryptionService extends BaseEncryptionService { } catch (IOException e) { throw new RuntimeException(e); } finally { - Closeables.closeQuietly(i); + Closeables.closeQuietly(toEncode); } return eTag.digest(); } diff --git a/core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaIntegrationTest.java b/core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaTest.java similarity index 98% rename from core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaIntegrationTest.java rename to core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaTest.java index eacbbed20a..b4a1d8a6d9 100644 --- a/core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaIntegrationTest.java +++ b/core/src/test/java/org/jclouds/http/BackoffLimitedRetryJavaTest.java @@ -44,7 +44,7 @@ import com.google.inject.Module; * @author James Murty */ @Test(sequential = true) -public class BackoffLimitedRetryJavaIntegrationTest extends BaseJettyTest { +public class BackoffLimitedRetryJavaTest extends BaseJettyTest { private int beginToFailOnRequestNumber = 0; private int endFailuresOnRequestNumber = 0; private int requestCount = 0; diff --git a/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceTest.java b/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java similarity index 93% rename from core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceTest.java rename to core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java index be1941e580..cddb9b4e25 100644 --- a/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceTest.java +++ b/core/src/test/java/org/jclouds/http/BaseHttpCommandExecutorServiceIntegrationTest.java @@ -38,8 +38,8 @@ import com.google.common.collect.ImmutableMap; * * @author Adrian Cole */ -@Test(threadPoolSize = 10, sequential = true) -public abstract class BaseHttpCommandExecutorServiceTest extends BaseJettyTest { +@Test(threadPoolSize = 10, groups = "integration", sequential = true) +public abstract class BaseHttpCommandExecutorServiceIntegrationTest extends BaseJettyTest { @Test(invocationCount = 25, timeOut = 5000) public void testRequestFilter() throws MalformedURLException, ExecutionException, @@ -92,6 +92,13 @@ public abstract class BaseHttpCommandExecutorServiceTest extends BaseJettyTest { assertEquals(client.download("redirect").trim(), XML2); } + @Test(invocationCount = 100, timeOut = 5000) + public void testGetBigFile() throws MalformedURLException, ExecutionException, + InterruptedException, TimeoutException { + assertEquals(encryptionService.toBase64String(encryptionService.md5(client + .downloadStream("101constitutions"))), md5); + } + @Test(enabled = false, invocationCount = 25, timeOut = 5000) public void testGetStringPermanentRedirect() throws MalformedURLException, ExecutionException, InterruptedException, TimeoutException { diff --git a/core/src/test/java/org/jclouds/http/BaseJettyTest.java b/core/src/test/java/org/jclouds/http/BaseJettyTest.java index 77c2916e27..17f7886588 100644 --- a/core/src/test/java/org/jclouds/http/BaseJettyTest.java +++ b/core/src/test/java/org/jclouds/http/BaseJettyTest.java @@ -18,7 +18,9 @@ */ package org.jclouds.http; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URI; import java.util.List; import java.util.Map; @@ -26,6 +28,7 @@ import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.zip.GZIPInputStream; import javax.inject.Singleton; import javax.servlet.ServletException; @@ -35,6 +38,7 @@ import javax.ws.rs.core.HttpHeaders; import org.jclouds.PropertiesBuilder; import org.jclouds.concurrent.internal.SyncProxy; +import org.jclouds.encryption.EncryptionService; import org.jclouds.lifecycle.Closer; import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.RestClientFactory; @@ -53,7 +57,10 @@ import org.testng.annotations.Optional; import org.testng.annotations.Parameters; import com.google.common.collect.Maps; +import com.google.common.io.ByteStreams; +import com.google.common.io.InputSupplier; import com.google.inject.AbstractModule; +import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Provides; @@ -139,12 +146,22 @@ public abstract class BaseJettyTest { private Server server2; protected RestContext context; private int testPort; + protected EncryptionService encryptionService; + protected String md5; static final Pattern actionPattern = Pattern.compile("/objects/(.*)/action/([a-z]*);?(.*)"); @BeforeTest @Parameters( { "test-jetty-port" }) public void setUpJetty(@Optional("8123") final int testPort) throws Exception { this.testPort = testPort; + + final InputSupplier oneHundredOneConstitutions = getTestDataSupplier(); + + encryptionService = Guice.createInjector().getInstance(EncryptionService.class); + + md5 = encryptionService.md5Base64(ByteStreams.toByteArray(oneHundredOneConstitutions + .getInput())); + Handler server1Handler = new AbstractHandler() { public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { @@ -152,6 +169,11 @@ public abstract class BaseJettyTest { return; } else if (target.indexOf("redirect") > 0) { response.sendRedirect("http://localhost:" + (testPort + 1)); + } else if (target.indexOf("101constitutions") > 0) { + response.setContentType("text/plain"); + response.setHeader("Content-MD5", md5); + response.setStatus(HttpServletResponse.SC_OK); + ByteStreams.copy(oneHundredOneConstitutions.getInput(), response.getOutputStream()); } else if (request.getMethod().equals("PUT")) { if (request.getContentLength() > 0) { response.setStatus(HttpServletResponse.SC_OK); @@ -245,6 +267,21 @@ public abstract class BaseJettyTest { assert client.newStringBuffer() != null; } + @SuppressWarnings("unchecked") + public static InputSupplier getTestDataSupplier() throws IOException { + byte[] oneConstitution = ByteStreams.toByteArray(new GZIPInputStream(BaseJettyTest.class + .getResourceAsStream("/const.txt.gz"))); + InputSupplier constitutionSupplier = ByteStreams + .newInputStreamSupplier(oneConstitution); + + InputSupplier temp = ByteStreams.join(constitutionSupplier); + + for (int i = 0; i < 100; i++) { + temp = ByteStreams.join(temp, constitutionSupplier); + } + return temp; + } + public static RestContextBuilder newBuilder( final int testPort, final Properties properties, Module connectionModule) { return new IntegrationContextBuilder(properties, testPort).withModules(connectionModule); diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java index b7f63b0844..2fe82cc22a 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java @@ -18,6 +18,7 @@ */ package org.jclouds.http; +import java.io.InputStream; import java.util.Map; import javax.ws.rs.GET; @@ -62,6 +63,10 @@ public interface IntegrationTestAsyncClient { @Path("objects/{id}") ListenableFuture download(@PathParam("id") String id); + @GET + @Path("{path}") + ListenableFuture downloadStream(@PathParam("path") String path); + @GET @Path("{path}") ListenableFuture synch(@PathParam("path") String id); @@ -136,7 +141,7 @@ public interface IntegrationTestAsyncClient { @GET @Path("objects/{id}") ListenableFuture download(@PathParam("id") String id, @HeaderParam("test") String header); - + @GET @Path("objects/{id}") @XMLResponseParser(BarHandler.class) diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java index c026dc4e24..da2d6b31be 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestClient.java @@ -18,6 +18,7 @@ */ package org.jclouds.http; +import java.io.InputStream; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -38,6 +39,8 @@ public interface IntegrationTestClient { String download(String id); + InputStream downloadStream(String id); + String downloadException(String id, HttpRequestOptions options); String synchException(String id, String header); diff --git a/core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceTest.java b/core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceIntegrationTest.java similarity index 94% rename from core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceTest.java rename to core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceIntegrationTest.java index b22cf97abb..90857b1712 100644 --- a/core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceTest.java +++ b/core/src/test/java/org/jclouds/http/JavaUrlHttpCommandExecutorServiceIntegrationTest.java @@ -37,7 +37,7 @@ import com.google.inject.Module; * @author Adrian Cole */ @Test -public class JavaUrlHttpCommandExecutorServiceTest extends BaseHttpCommandExecutorServiceTest { +public class JavaUrlHttpCommandExecutorServiceIntegrationTest extends BaseHttpCommandExecutorServiceIntegrationTest { protected Module createConnectionModule() { return new JavaUrlHttpCommandExecutorServiceModule(); diff --git a/core/src/test/resources/const.txt.gz b/core/src/test/resources/const.txt.gz new file mode 100644 index 0000000000000000000000000000000000000000..973eaf5dbfe8758c2e5cfa5e1fa4a5372e6463a8 GIT binary patch literal 14021 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 0) { eTag.update(buffer, 0, numRead); } @@ -100,7 +96,7 @@ public class BouncyCastleEncryptionService extends BaseEncryptionService { } catch (IOException e) { throw new RuntimeException(e); } finally { - Closeables.closeQuietly(i); + Closeables.closeQuietly(toEncode); } eTag.doFinal(resBuf, 0); return resBuf; diff --git a/extensions/enterprise/src/test/java/org/jclouds/enterprise/config/EnterpriseConfigurationModuleTest.java b/extensions/enterprise/src/test/java/org/jclouds/enterprise/config/EnterpriseConfigurationModuleTest.java index 82bfbf5454..2b4fee41ab 100644 --- a/extensions/enterprise/src/test/java/org/jclouds/enterprise/config/EnterpriseConfigurationModuleTest.java +++ b/extensions/enterprise/src/test/java/org/jclouds/enterprise/config/EnterpriseConfigurationModuleTest.java @@ -25,7 +25,7 @@ import static org.jclouds.Constants.PROPERTY_USER_THREADS; import java.util.Properties; -import org.jclouds.http.BaseHttpCommandExecutorServiceTest; +import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest; import org.testng.annotations.Test; import com.google.inject.Module; @@ -36,7 +36,7 @@ import com.google.inject.Module; * @author Adrian Cole */ @Test -public class EnterpriseConfigurationModuleTest extends BaseHttpCommandExecutorServiceTest { +public class EnterpriseConfigurationModuleTest extends BaseHttpCommandExecutorServiceIntegrationTest { protected Module createConnectionModule() { return new EnterpriseConfigurationModule(); diff --git a/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java b/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java index 31e0fa8638..5711ca2602 100644 --- a/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java +++ b/extensions/gae/src/test/java/org/jclouds/gae/GaeHttpCommandExecutorServiceIntegrationTest.java @@ -28,7 +28,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; -import org.jclouds.http.BaseHttpCommandExecutorServiceTest; +import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest; import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -46,7 +46,7 @@ import com.google.inject.Module; */ @Test public class GaeHttpCommandExecutorServiceIntegrationTest extends - BaseHttpCommandExecutorServiceTest { + BaseHttpCommandExecutorServiceIntegrationTest { @Override @Test(invocationCount = 50, timeOut = 3000) @@ -248,4 +248,11 @@ public class GaeHttpCommandExecutorServiceIntegrationTest extends protected void addConnectionProperties(Properties props) { } + @Override + @Test(invocationCount = 50, timeOut = 3000) + public void testGetBigFile() throws MalformedURLException, ExecutionException, + InterruptedException, TimeoutException { + // disabled since test data is too big + } + } \ No newline at end of file diff --git a/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioBackoffLimitedRetryJavaIntegrationTest.java b/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioBackoffLimitedRetryJavaIntegrationTest.java index 7cd9605541..d299bdc0ff 100644 --- a/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioBackoffLimitedRetryJavaIntegrationTest.java +++ b/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioBackoffLimitedRetryJavaIntegrationTest.java @@ -18,7 +18,7 @@ */ package org.jclouds.http.httpnio.pool; -import org.jclouds.http.BackoffLimitedRetryJavaIntegrationTest; +import org.jclouds.http.BackoffLimitedRetryJavaTest; import org.jclouds.http.handlers.BackoffLimitedRetryHandler; import org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule; import org.testng.annotations.Test; @@ -35,7 +35,7 @@ import com.google.inject.Module; */ @Test(sequential = true) public class NioBackoffLimitedRetryJavaIntegrationTest extends - BackoffLimitedRetryJavaIntegrationTest { + BackoffLimitedRetryJavaTest { protected Module createConnectionModule() { return new NioTransformingHttpCommandExecutorServiceModule(); diff --git a/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioTransformingHttpCommandExecutorServiceTest.java b/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioTransformingHttpCommandExecutorServiceTest.java index b4e15b561a..6ca25208b8 100644 --- a/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioTransformingHttpCommandExecutorServiceTest.java +++ b/extensions/httpnio/src/test/java/org/jclouds/http/httpnio/pool/NioTransformingHttpCommandExecutorServiceTest.java @@ -27,7 +27,7 @@ import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -import org.jclouds.http.BaseHttpCommandExecutorServiceTest; +import org.jclouds.http.BaseHttpCommandExecutorServiceIntegrationTest; import org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule; import org.testng.annotations.Test; @@ -40,7 +40,7 @@ import com.google.inject.Module; */ @Test(threadPoolSize = 10, sequential = true) public class NioTransformingHttpCommandExecutorServiceTest extends - BaseHttpCommandExecutorServiceTest { + BaseHttpCommandExecutorServiceIntegrationTest { @Override @Test(enabled = false) @@ -66,4 +66,10 @@ public class NioTransformingHttpCommandExecutorServiceTest extends props.setProperty(PROPERTY_USER_THREADS, 0 + ""); } + @Override + @Test(enabled = false) + public void testGetBigFile() throws MalformedURLException, ExecutionException, + InterruptedException, TimeoutException { + // disabled since test data is too big + } } \ No newline at end of file