Skip to content

Commit

Permalink
Upgrade localstack and enable new services (#1504)
Browse files Browse the repository at this point in the history
* Add new services to the enum

Note: Some services need a newer Localstack version

* Upgrade Localstack and alter endpoint URL generation to be IP-only

Also extend basic tests to cover SQS

* Describe rationale for adding new Localstack tests (or not) (#1509)

* Update localstack to 0.9.4
  • Loading branch information
rnorth authored and bsideup committed Jul 16, 2019
1 parent 371b325 commit 041d508
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 78 deletions.
1 change: 1 addition & 0 deletions modules/localstack/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dependencies {

compileOnly 'com.amazonaws:aws-java-sdk-s3:1.11.479'
testCompile 'com.amazonaws:aws-java-sdk-s3:1.11.479'
testCompile 'com.amazonaws:aws-java-sdk-sqs:1.11.479'
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
*/
public class LocalStackContainer extends GenericContainer<LocalStackContainer> {

public static final String VERSION = "0.8.6";
public static final String VERSION = "0.9.4";

private final List<Service> services = new ArrayList<>();

Expand Down Expand Up @@ -82,20 +82,11 @@ public AwsClientBuilder.EndpointConfiguration getEndpointConfiguration(Service s
final String address = getContainerIpAddress();
String ipAddress = address;
try {
// resolve IP address and use that as the endpoint so that path-style access is automatically used for S3
ipAddress = InetAddress.getByName(address).getHostAddress();
} catch (UnknownHostException ignored) {

}
ipAddress = ipAddress + ".nip.io";
while (true) {
try {
//noinspection ResultOfMethodCallIgnored
InetAddress.getAllByName(ipAddress);
break;
} catch (UnknownHostException ignored) {

}
}

return new AwsClientBuilder.EndpointConfiguration(
"http://" +
Expand Down Expand Up @@ -123,23 +114,29 @@ public AWSCredentialsProvider getDefaultCredentialsProvider() {
@Getter
@FieldDefaults(makeFinal = true)
public enum Service {
API_GATEWAY("apigateway", 4567),
KINESIS("kinesis", 4568),
DYNAMODB("dynamodb", 4569),
DYNAMODB_STREAMS("dynamodbstreams", 4570),
API_GATEWAY("apigateway", 4567),
KINESIS("kinesis", 4568),
DYNAMODB("dynamodb", 4569),
DYNAMODB_STREAMS("dynamodbstreams", 4570),
// TODO: Clarify usage for ELASTICSEARCH and ELASTICSEARCH_SERVICE
// ELASTICSEARCH("es", 4571),
S3("s3", 4572),
FIREHOSE("firehose", 4573),
LAMBDA("lambda", 4574),
SNS("sns", 4575),
SQS("sqs", 4576),
REDSHIFT("redshift", 4577),
// ELASTICSEARCH_SERVICE("", 4578),
SES("ses", 4579),
ROUTE53("route53", 4580),
CLOUDFORMATION("cloudformation", 4581),
CLOUDWATCH("cloudwatch", 4582);
S3("s3", 4572),
FIREHOSE("firehose", 4573),
LAMBDA("lambda", 4574),
SNS("sns", 4575),
SQS("sqs", 4576),
REDSHIFT("redshift", 4577),
// ELASTICSEARCH_SERVICE("", 4578),
SES("ses", 4579),
ROUTE53("route53", 4580),
CLOUDFORMATION("cloudformation", 4581),
CLOUDWATCH("cloudwatch", 4582),
SSM("ssm", 4583),
SECRETSMANAGER("secretsmanager", 4584),
STEPFUNCTIONS("stepsfunctions", 4585),
CLOUDWATCHLOGS("cloudwatchlogs", 4586),
STS("sts", 4592),
IAM("iam", 4593);

String localStackName;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.testcontainers.containers.localstack;


import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
import com.amazonaws.services.sqs.model.CreateQueueResult;
import com.amazonaws.services.sqs.model.Message;
import org.apache.commons.io.IOUtils;
import org.junit.ClassRule;
import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Set;

import static java.util.stream.Collectors.toSet;
import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.S3;
import static org.testcontainers.containers.localstack.LocalStackContainer.Service.SQS;

/**
* The only tests that should go here are for those Localstack services that require special testcontainers code to work with them.
* For example, S3 needs a test to ensure special HTTP routing to the S3 container works.
*/
public class SimpleLocalstackTest {

private static final String BUCKET_1 = "bucket1";
private static final String BUCKET_2 = "bucket2";
private static final String ITEM_KEY = "bar";
private static final String DUMMY_CONTENT = "baz";

@ClassRule
public static LocalStackContainer localstack = new LocalStackContainer()
.withServices(S3, SQS);

@Test
public void simpleS3Test() throws IOException {
AmazonS3 s3 = AmazonS3ClientBuilder
.standard()
.withEndpointConfiguration(localstack.getEndpointConfiguration(S3))
.withCredentials(localstack.getDefaultCredentialsProvider())
.build();

s3.createBucket(BUCKET_1);
s3.putObject(BUCKET_1, ITEM_KEY, DUMMY_CONTENT);

s3.createBucket(BUCKET_2);
s3.putObject(BUCKET_2, ITEM_KEY, DUMMY_CONTENT);

final Set<String> bucketNames = s3.listBuckets().stream()
.map(Bucket::getName)
.collect(toSet());
assertTrue("The created buckets have the right name",
bucketNames.contains(BUCKET_1) && bucketNames.contains(BUCKET_2));

assertBucketContentsCorrect(s3, BUCKET_1);
assertBucketContentsCorrect(s3, BUCKET_2);
}

private void assertBucketContentsCorrect(AmazonS3 s3, String bucketName) throws IOException {
final ObjectListing objectListing1 = s3.listObjects(bucketName);
assertEquals("The created bucket has 1 item in it", 1, objectListing1.getObjectSummaries().size());

final S3Object object = s3.getObject(bucketName, ITEM_KEY);
final String content = IOUtils.toString(object.getObjectContent(), StandardCharsets.UTF_8);
assertEquals("The object can be retrieved", DUMMY_CONTENT, content);
}

@Test
public void simpleSQSTest() {
AmazonSQS sqs = AmazonSQSClientBuilder.standard()
.withEndpointConfiguration(localstack.getEndpointConfiguration(SQS))
.withCredentials(localstack.getDefaultCredentialsProvider())
.build();

CreateQueueResult queueResult = sqs.createQueue("baz");
String queueUrl = queueResult.getQueueUrl();

sqs.sendMessage(queueUrl, "ping");

final List<Message> messages = sqs.receiveMessage(queueUrl).getMessages();

assertTrue("the message queue contains a message", messages.size() > 0);
assertEquals("the first message is the one we sent", "ping", messages.get(0).getBody());
}
}

0 comments on commit 041d508

Please sign in to comment.