Issue 64: convert base integration test and all map tests to use eventually consistent bucket operation assertions

git-svn-id: http://jclouds.googlecode.com/svn/trunk@1439 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2009-06-17 22:53:51 +00:00
parent b6f129eaa4
commit b858ec002e
4 changed files with 406 additions and 293 deletions

View File

@ -47,11 +47,11 @@ import com.google.common.collect.ImmutableSet;
@Test @Test
public abstract class BaseS3MapIntegrationTest<T> extends S3IntegrationTest { public abstract class BaseS3MapIntegrationTest<T> extends S3IntegrationTest {
public abstract void testPutAll(); public abstract void testPutAll() throws InterruptedException;
public abstract void testEntrySet() throws IOException; public abstract void testEntrySet() throws IOException, InterruptedException;
public abstract void testValues() throws IOException; public abstract void testValues() throws IOException, InterruptedException;
protected BaseS3Map<T> map; protected BaseS3Map<T> map;
protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple", "two", "bear", protected Map<String, String> fiveStrings = ImmutableMap.of("one", "apple", "two", "bear",
@ -94,54 +94,119 @@ public abstract class BaseS3MapIntegrationTest<T> extends S3IntegrationTest {
protected abstract BaseS3Map<T> createMap(S3Context context, String bucket); protected abstract BaseS3Map<T> createMap(S3Context context, String bucket);
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testClear() { public void testClear() throws InterruptedException {
map.clear(); map.clear();
assertEquals(map.size(), 0); assertEventuallyMapSize(0);
putString("one", "apple"); putString("one", "apple");
assertEquals(map.size(), 1); assertEventuallyMapSize(1);
map.clear(); map.clear();
assertEquals(map.size(), 0); assertEventuallyMapSize(0);
} }
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public abstract void testRemove() throws IOException; public abstract void testRemove() throws IOException, InterruptedException;
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testKeySet() { public void testKeySet() throws InterruptedException {
assertEquals(map.keySet().size(), 0); assertEventuallyKeySize(0);
putString("one", "two"); putString("one", "two");
assertEquals(map.keySet(), ImmutableSet.of("one")); assertEventuallyKeySize(1);
assertEventuallyKeySetEquals(ImmutableSet.of("one"));
}
protected void assertEventuallyKeySetEquals(final Object toEqual) throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assertEquals(map.keySet(), toEqual);
}
});
}
protected void assertEventuallyKeySize(final int size) throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assertEquals(map.keySet().size(), size);
}
});
} }
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testContainsKey() { public void testContainsKey() throws InterruptedException {
assert !map.containsKey("one"); assertEventuallyDoesntContainKey();
putString("one", "apple"); putString("one", "apple");
assert map.containsKey("one"); assertEventuallyContainsKey();
}
protected void assertEventuallyContainsKey() throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assert map.containsKey("one");
}
});
}
protected void assertEventuallyDoesntContainKey() throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assert !map.containsKey("one");
}
});
} }
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testIsEmpty() { public void testIsEmpty() throws InterruptedException {
assert map.isEmpty(); assertEventuallyEmpty();
putString("one", "apple"); putString("one", "apple");
assert !map.isEmpty(); assertEventuallyNotEmpty();
}
protected void assertEventuallyNotEmpty() throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assert !map.isEmpty();
}
});
}
protected void assertEventuallyEmpty() throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assert map.isEmpty();
}
});
} }
abstract protected void putString(String key, String value); abstract protected void putString(String key, String value);
protected void fourLeftRemovingOne() { protected void fourLeftRemovingOne() throws InterruptedException {
map.remove("one"); map.remove("one");
assertEquals(map.size(), 4); assertEventuallyMapSize(4);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>(ImmutableSet.of("two", assertEventuallyKeySetEquals(new TreeSet<String>(ImmutableSet.of("two", "three", "four",
"three", "four", "five"))); "five")));
}
protected void assertEventuallyMapSize(final int size) throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assertEquals(map.size(), size);
}
});
} }
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public abstract void testPut() throws IOException; public abstract void testPut() throws IOException, InterruptedException;
@Test(groups = { "integration", "live" }) @Test(groups = { "integration", "live" })
public void testGetBucket() { public void testGetBucket() throws InterruptedException {
assertEquals(map.getBucket().getName(), bucketName); assertEventuallyBucketNameCorrect();
}
protected void assertEventuallyBucketNameCorrect() throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
assertEquals(map.getBucket().getName(), bucketName);
}
});
} }
} }

View File

@ -23,19 +23,20 @@
*/ */
package org.jclouds.aws.s3; package org.jclouds.aws.s3;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.util.Utils;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.util.Utils;
import org.testng.annotations.Test;
/** /**
* Tests to cover @{link LiveS3ObjectMap} * Tests to cover @{link LiveS3ObjectMap}
@ -44,167 +45,162 @@ import java.util.TreeSet;
*/ */
@Test(testName = "s3.S3InputStreamMapIntegrationTest") @Test(testName = "s3.S3InputStreamMapIntegrationTest")
public class S3InputStreamMapIntegrationTest extends BaseS3MapIntegrationTest<InputStream> { public class S3InputStreamMapIntegrationTest extends BaseS3MapIntegrationTest<InputStream> {
S3InputStreamMap map = null; S3InputStreamMap map = null;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) { protected BaseS3Map<InputStream> createMap(S3Context context, String bucket) {
map = context.createInputStreamMap(bucket); map = context.createInputStreamMap(bucket);
return (BaseS3Map<InputStream>) map; return (BaseS3Map<InputStream>) map;
} }
@Override @Override
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testValues() throws IOException { public void testValues() throws IOException {
map.putAll(this.fiveInputs); map.putAll(this.fiveInputs);
Collection<InputStream> values = map.values(); Collection<InputStream> values = map.values();
assertEquals(values.size(), 5); assertEquals(values.size(), 5);
Set<String> valuesAsString = new HashSet<String>(); Set<String> valuesAsString = new HashSet<String>();
for (InputStream stream : values) { for (InputStream stream : values) {
valuesAsString.add(Utils.toStringAndClose(stream)); valuesAsString.add(Utils.toStringAndClose(stream));
} }
valuesAsString.removeAll(fiveStrings.values()); valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0; assert valuesAsString.size() == 0;
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testRemove() throws IOException { public void testRemove() throws IOException, InterruptedException {
putString("one", "two"); putString("one", "two");
InputStream old = map.remove("one"); InputStream old = map.remove("one");
assertEquals(Utils.toStringAndClose(old), "two"); assertEquals(Utils.toStringAndClose(old), "two");
old = map.remove("one"); old = map.remove("one");
assert old == null; assert old == null;
old = map.get("one"); old = map.get("one");
assert old == null; assert old == null;
assertEquals(map.keySet().size(), 0); assertEventuallyKeySize(0);
} }
@Override @Override
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testEntrySet() throws IOException { public void testEntrySet() throws IOException, InterruptedException {
map.putAllStrings(this.fiveStrings); map.putAllStrings(this.fiveStrings);
Set<Entry<String, InputStream>> entries = map.entrySet(); Set<Entry<String, InputStream>> entries = map.entrySet();
assertEquals(entries.size(), 5); assertEquals(entries.size(), 5);
for (Entry<String, InputStream> entry : entries) { for (Entry<String, InputStream> entry : entries) {
assertEquals(IOUtils.toString(entry.getValue()), fiveStrings assertEquals(IOUtils.toString(entry.getValue()), fiveStrings.get(entry.getKey()));
.get(entry.getKey())); entry.setValue(IOUtils.toInputStream(""));
entry.setValue(IOUtils.toInputStream("")); }
} assertEventuallyMapSize(5);
assertEquals(map.size(), 5); for (InputStream value : map.values()) {
for (InputStream value : map.values()) { assertEquals(IOUtils.toString(value), "");
assertEquals(IOUtils.toString(value), ""); }
} }
}
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testContainsStringValue() { public void testContainsStringValue() {
map.putString("one", "apple"); map.putString("one", "apple");
assert map.containsValue(fiveStrings.get("one")); assert map.containsValue(fiveStrings.get("one"));
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testContainsFileValue() { public void testContainsFileValue() {
map.putString("one", "apple"); map.putString("one", "apple");
assert map.containsValue(fiveFiles.get("one")); assert map.containsValue(fiveFiles.get("one"));
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testContainsInputStreamValue() { public void testContainsInputStreamValue() {
map.putString("one", "apple"); map.putString("one", "apple");
assert map.containsValue(this.fiveInputs.get("one")); assert map.containsValue(this.fiveInputs.get("one"));
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testContainsBytesValue() { public void testContainsBytesValue() {
map.putString("one", "apple"); map.putString("one", "apple");
assert map.containsValue(this.fiveBytes.get("one")); assert map.containsValue(this.fiveBytes.get("one"));
} }
@Override @Override
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutAll() { public void testPutAll() throws InterruptedException {
map.putAll(this.fiveInputs); map.putAll(this.fiveInputs);
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>( assertEventuallyKeySetEquals(new TreeSet<String>(fiveInputs.keySet()));
fiveInputs.keySet())); fourLeftRemovingOne();
fourLeftRemovingOne(); }
}
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutAllBytes() { public void testPutAllBytes() throws InterruptedException {
map.putAllBytes(this.fiveBytes); map.putAllBytes(this.fiveBytes);
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>( assertEventuallyKeySetEquals(new TreeSet<String>(fiveBytes.keySet()));
fiveBytes.keySet())); fourLeftRemovingOne();
fourLeftRemovingOne(); }
}
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutAllFiles() { public void testPutAllFiles() throws InterruptedException {
map.putAllFiles(this.fiveFiles); map.putAllFiles(this.fiveFiles);
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>( assertEventuallyKeySetEquals(new TreeSet<String>(fiveFiles.keySet()));
fiveFiles.keySet())); fourLeftRemovingOne();
fourLeftRemovingOne(); }
}
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutAllStrings() { public void testPutAllStrings() throws InterruptedException {
map.putAllStrings(this.fiveStrings); map.putAllStrings(this.fiveStrings);
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>( assertEventuallyKeySetEquals(new TreeSet<String>(fiveStrings.keySet()));
fiveStrings.keySet())); fourLeftRemovingOne();
fourLeftRemovingOne(); }
}
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutString() throws IOException { public void testPutString() throws IOException, InterruptedException {
InputStream old = map.putString("one", "apple"); InputStream old = map.putString("one", "apple");
getOneReturnsAppleAndOldValueIsNull(old); getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putString("one", "bear"); InputStream apple = map.putString("one", "bear");
getOneReturnsBearAndOldValueIsApple(apple); getOneReturnsBearAndOldValueIsApple(apple);
} }
void getOneReturnsAppleAndOldValueIsNull(InputStream old) void getOneReturnsAppleAndOldValueIsNull(InputStream old) throws IOException,
throws IOException { InterruptedException {
assert old == null; assert old == null;
assertEquals(Utils.toStringAndClose(map.get("one")), "apple"); assertEquals(Utils.toStringAndClose(map.get("one")), "apple");
assertEquals(map.size(), 1); assertEventuallyMapSize(1);
} }
void getOneReturnsBearAndOldValueIsApple(InputStream oldValue) void getOneReturnsBearAndOldValueIsApple(InputStream oldValue) throws IOException,
throws IOException { InterruptedException {
assertEquals(Utils.toStringAndClose(map.get("one")), "bear"); assertEquals(Utils.toStringAndClose(map.get("one")), "bear");
assertEquals(Utils.toStringAndClose(oldValue), "apple"); assertEquals(Utils.toStringAndClose(oldValue), "apple");
assertEquals(map.size(), 1); assertEventuallyMapSize(1);
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutFile() throws IOException { public void testPutFile() throws IOException, InterruptedException {
InputStream old = map.putFile("one", fiveFiles.get("one")); InputStream old = map.putFile("one", fiveFiles.get("one"));
getOneReturnsAppleAndOldValueIsNull(old); getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putFile("one", fiveFiles.get("two")); InputStream apple = map.putFile("one", fiveFiles.get("two"));
getOneReturnsBearAndOldValueIsApple(apple); getOneReturnsBearAndOldValueIsApple(apple);
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutBytes() throws IOException { public void testPutBytes() throws IOException, InterruptedException {
InputStream old = map.putBytes("one", "apple".getBytes()); InputStream old = map.putBytes("one", "apple".getBytes());
getOneReturnsAppleAndOldValueIsNull(old); getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.putBytes("one", "bear".getBytes()); InputStream apple = map.putBytes("one", "bear".getBytes());
getOneReturnsBearAndOldValueIsApple(apple); getOneReturnsBearAndOldValueIsApple(apple);
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPut() throws IOException { public void testPut() throws IOException, InterruptedException {
InputStream old = map.put("one", IOUtils.toInputStream("apple")); InputStream old = map.put("one", IOUtils.toInputStream("apple"));
getOneReturnsAppleAndOldValueIsNull(old); getOneReturnsAppleAndOldValueIsNull(old);
InputStream apple = map.put("one", IOUtils.toInputStream("bear")); InputStream apple = map.put("one", IOUtils.toInputStream("bear"));
getOneReturnsBearAndOldValueIsApple(apple); getOneReturnsBearAndOldValueIsApple(apple);
} }
@Override @Override
protected void putString(String key, String value) { protected void putString(String key, String value) {
map.putString(key, value); map.putString(key, value);
} }
} }

View File

@ -49,6 +49,7 @@ import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.reference.S3Constants; import org.jclouds.aws.s3.reference.S3Constants;
import org.jclouds.aws.s3.util.S3Utils; import org.jclouds.aws.s3.util.S3Utils;
import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule; import org.jclouds.http.config.JavaUrlHttpFutureCommandClientModule;
import org.jclouds.util.Utils;
import org.testng.ITestContext; import org.testng.ITestContext;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
@ -61,6 +62,28 @@ import com.google.inject.Module;
public class S3IntegrationTest { public class S3IntegrationTest {
protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>"; protected static final String TEST_STRING = "<apples><apple name=\"fuji\"></apple> </apples>";
public static long INCONSISTENCY_WINDOW = 1000;
/**
*
* Due to eventual consistency, the size of the bucket and hence the size of the map may not
* return correctly immediately. Hence, we will try up to the inconsistency window to see if the
* assertion completes.
*/
protected void assertEventually(Runnable assertion) throws InterruptedException {
AssertionError error = null;
for (int i = 0; i < 5; i++) {
try {
assertion.run();
return;
} catch (AssertionError e) {
error = e;
}
Thread.sleep(INCONSISTENCY_WINDOW / 5);
}
if (error != null)
throw error;
}
protected byte[] goodMd5; protected byte[] goodMd5;
protected byte[] badMd5; protected byte[] badMd5;
@ -70,8 +93,20 @@ public class S3IntegrationTest {
ExecutionException, TimeoutException { ExecutionException, TimeoutException {
deleteBucket(sourceBucket); deleteBucket(sourceBucket);
client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS); client.putBucketIfNotExists(sourceBucket).get(10, TimeUnit.SECONDS);
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS).getContents().size(), assertEventuallyBucketEmpty(sourceBucket);
0, "bucket " + sourceBucket + "wasn't empty"); }
protected void assertEventuallyBucketEmpty(final String bucketName) throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
try {
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents()
.size(), 0, "bucket " + bucketName + "wasn't empty");
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
} }
protected void addObjectToBucket(String sourceBucket, String key) throws InterruptedException, protected void addObjectToBucket(String sourceBucket, String key) throws InterruptedException,
@ -89,14 +124,27 @@ public class S3IntegrationTest {
protected S3Object validateContent(String sourceBucket, String key) throws InterruptedException, protected S3Object validateContent(String sourceBucket, String key) throws InterruptedException,
ExecutionException, TimeoutException, IOException { ExecutionException, TimeoutException, IOException {
assertEquals(client.listBucket(sourceBucket).get(10, TimeUnit.SECONDS).getContents().size(), assertEventuallyBucketSize(sourceBucket, 1);
1);
S3Object newObject = client.getObject(sourceBucket, key).get(10, TimeUnit.SECONDS); S3Object newObject = client.getObject(sourceBucket, key).get(10, TimeUnit.SECONDS);
assert newObject != S3Object.NOT_FOUND; assert newObject != S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING); assertEquals(S3Utils.getContentAsStringAndClose(newObject), TEST_STRING);
return newObject; return newObject;
} }
protected void assertEventuallyBucketSize(final String bucketName, final int count)
throws InterruptedException {
assertEventually(new Runnable() {
public void run() {
try {
assertEquals(client.listBucket(bucketName).get(10, TimeUnit.SECONDS).getContents()
.size(), count);
} catch (Exception e) {
Utils.<RuntimeException> rethrowIfRuntimeOrSameType(e);
}
}
});
}
@BeforeClass(groups = { "integration", "live" }) @BeforeClass(groups = { "integration", "live" })
protected void enableDebug() { protected void enableDebug() {
if (debugEnabled()) { if (debugEnabled()) {

View File

@ -23,17 +23,23 @@
*/ */
package org.jclouds.aws.s3; package org.jclouds.aws.s3;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.jclouds.aws.s3.domain.S3Object; import org.jclouds.aws.s3.domain.S3Object;
import org.jclouds.aws.s3.internal.BaseS3Map; import org.jclouds.aws.s3.internal.BaseS3Map;
import org.jclouds.aws.s3.util.S3Utils; import org.jclouds.aws.s3.util.S3Utils;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
/** /**
* Tests to cover @{link LiveS3ObjectMap} * Tests to cover @{link LiveS3ObjectMap}
* *
@ -41,126 +47,124 @@ import java.util.Map.Entry;
*/ */
@Test(testName = "s3.S3ObjectMapIntegrationTest") @Test(testName = "s3.S3ObjectMapIntegrationTest")
public class S3ObjectMapIntegrationTest extends BaseS3MapIntegrationTest<S3Object> { public class S3ObjectMapIntegrationTest extends BaseS3MapIntegrationTest<S3Object> {
S3ObjectMap map = null; S3ObjectMap map = null;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) { protected BaseS3Map<S3Object> createMap(S3Context context, String bucket) {
map = context.createS3ObjectMap(bucket); map = context.createS3ObjectMap(bucket);
return (BaseS3Map<S3Object>) map; return (BaseS3Map<S3Object>) map;
} }
@Override @Override
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testValues() throws IOException { public void testValues() throws IOException, InterruptedException {
putFiveStrings(); putFiveStrings();
Collection<S3Object> values = map.values(); Collection<S3Object> values = map.values();
assertEquals(values.size(), 5); assertEventuallyMapSize(5);
Set<String> valuesAsString = new HashSet<String>(); Set<String> valuesAsString = new HashSet<String>();
for (S3Object object : values) { for (S3Object object : values) {
valuesAsString.add(S3Utils.getContentAsStringAndClose(object)); valuesAsString.add(S3Utils.getContentAsStringAndClose(object));
} }
valuesAsString.removeAll(fiveStrings.values()); valuesAsString.removeAll(fiveStrings.values());
assert valuesAsString.size() == 0; assert valuesAsString.size() == 0;
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testRemove() throws IOException { public void testRemove() throws IOException, InterruptedException {
putString("one", "two"); putString("one", "two");
S3Object old = map.remove("one"); S3Object old = map.remove("one");
assertEquals(S3Utils.getContentAsStringAndClose(old), "two"); assertEquals(S3Utils.getContentAsStringAndClose(old), "two");
old = map.remove("one"); old = map.remove("one");
assert old == S3Object.NOT_FOUND; assert old == S3Object.NOT_FOUND;
old = map.get("one"); old = map.get("one");
assert old == S3Object.NOT_FOUND; assert old == S3Object.NOT_FOUND;
assertEquals(map.keySet().size(), 0); assertEventuallyKeySize(0);
} }
@Override @Override
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testEntrySet() throws IOException { public void testEntrySet() throws IOException, InterruptedException {
putFiveStrings(); putFiveStrings();
Set<Entry<String, S3Object>> entries = map.entrySet(); Set<Entry<String, S3Object>> entries = map.entrySet();
assertEquals(entries.size(), 5); assertEquals(entries.size(), 5);
for (Entry<String, S3Object> entry : entries) { for (Entry<String, S3Object> entry : entries) {
assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()), assertEquals(S3Utils.getContentAsStringAndClose(entry.getValue()), fiveStrings.get(entry
fiveStrings.get(entry.getKey())); .getKey()));
S3Object value = entry.getValue(); S3Object value = entry.getValue();
value.setData(""); value.setData("");
value.generateMd5(); value.generateMd5();
entry.setValue(value); entry.setValue(value);
} }
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
for (S3Object value : map.values()) { for (S3Object value : map.values()) {
assertEquals(S3Utils.getContentAsStringAndClose(value), ""); assertEquals(S3Utils.getContentAsStringAndClose(value), "");
} }
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testContains() { public void testContains() {
putString("one", "apple"); putString("one", "apple");
S3Object object = new S3Object("one"); S3Object object = new S3Object("one");
object.setData("apple"); object.setData("apple");
assert map.containsValue(object); assert map.containsValue(object);
} }
void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException { void getOneReturnsAppleAndOldValueIsNull(S3Object old) throws IOException, InterruptedException {
assert old == S3Object.NOT_FOUND; assert old == S3Object.NOT_FOUND;
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "apple");
"apple"); assertEventuallyMapSize(1);
assert map.size() == 1; }
}
void getOneReturnsBearAndOldValueIsApple(S3Object oldValue) void getOneReturnsBearAndOldValueIsApple(S3Object oldValue) throws IOException,
throws IOException { InterruptedException {
assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear"); assertEquals(S3Utils.getContentAsStringAndClose(map.get("one")), "bear");
assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple"); assertEquals(S3Utils.getContentAsStringAndClose(oldValue), "apple");
assert map.size() == 1; assertEventuallyMapSize(1);
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPut() throws IOException { public void testPut() throws IOException, InterruptedException {
S3Object object = new S3Object("one"); S3Object object = new S3Object("one");
object.setData(IOUtils.toInputStream("apple")); object.setData(IOUtils.toInputStream("apple"));
object.generateMd5(); object.generateMd5();
S3Object old = map.put(object.getKey(), object); S3Object old = map.put(object.getKey(), object);
getOneReturnsAppleAndOldValueIsNull(old); getOneReturnsAppleAndOldValueIsNull(old);
object.setData(IOUtils.toInputStream("bear")); object.setData(IOUtils.toInputStream("bear"));
object.generateMd5(); object.generateMd5();
S3Object apple = map.put(object.getKey(), object); S3Object apple = map.put(object.getKey(), object);
getOneReturnsBearAndOldValueIsApple(apple); getOneReturnsBearAndOldValueIsApple(apple);
} }
@Test(groups = {"integration", "live"}) @Test(groups = { "integration", "live" })
public void testPutAll() { public void testPutAll() throws InterruptedException {
Map<String, S3Object> newMap = new HashMap<String, S3Object>(); Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (String key : fiveInputs.keySet()) { for (String key : fiveInputs.keySet()) {
S3Object object = new S3Object(key); S3Object object = new S3Object(key);
object.setData(fiveInputs.get(key)); object.setData(fiveInputs.get(key));
object.getMetadata().setSize(fiveBytes.get(key).length); object.getMetadata().setSize(fiveBytes.get(key).length);
newMap.put(key, object); newMap.put(key, object);
} }
map.putAll(newMap); map.putAll(newMap);
assertEquals(map.size(), 5); assertEventuallyMapSize(5);
assertEquals(new TreeSet<String>(map.keySet()), new TreeSet<String>( assertEventuallyKeySetEquals(new TreeSet<String>(fiveInputs.keySet()));
fiveInputs.keySet())); fourLeftRemovingOne();
fourLeftRemovingOne(); }
}
@Override @Override
protected void putString(String key, String value) { protected void putString(String key, String value) {
S3Object object = new S3Object(key); S3Object object = new S3Object(key);
object.setData(value); object.setData(value);
map.put(key, object); map.put(key, object);
} }
protected void putFiveStrings() { protected void putFiveStrings() {
Map<String, S3Object> newMap = new HashMap<String, S3Object>(); Map<String, S3Object> newMap = new HashMap<String, S3Object>();
for (Map.Entry<String, String> entry : fiveStrings.entrySet()) { for (Map.Entry<String, String> entry : fiveStrings.entrySet()) {
S3Object object = new S3Object(entry.getKey()); S3Object object = new S3Object(entry.getKey());
object.setData(entry.getValue()); object.setData(entry.getValue());
newMap.put(entry.getKey(), object); newMap.put(entry.getKey(), object);
} }
map.putAll(newMap); map.putAll(newMap);
} }
} }