|
8 | 8 | import com.amazonaws.services.kms.model.CreateKeyRequest;
|
9 | 9 | import com.amazonaws.services.kms.model.CreateKeyResult;
|
10 | 10 | import com.amazonaws.services.kms.model.Tag;
|
| 11 | +import com.amazonaws.services.lambda.AWSLambda; |
| 12 | +import com.amazonaws.services.lambda.AWSLambdaClientBuilder; |
| 13 | +import com.amazonaws.services.lambda.model.CreateFunctionRequest; |
| 14 | +import com.amazonaws.services.lambda.model.CreateFunctionResult; |
| 15 | +import com.amazonaws.services.lambda.model.FunctionCode; |
| 16 | +import com.amazonaws.services.lambda.model.GetFunctionRequest; |
| 17 | +import com.amazonaws.services.lambda.model.InvokeRequest; |
| 18 | +import com.amazonaws.services.lambda.model.InvokeResult; |
| 19 | +import com.amazonaws.services.lambda.model.Runtime; |
11 | 20 | import com.amazonaws.services.logs.AWSLogs;
|
12 | 21 | import com.amazonaws.services.logs.AWSLogsClientBuilder;
|
13 | 22 | import com.amazonaws.services.logs.model.CreateLogGroupRequest;
|
|
20 | 29 | import com.amazonaws.services.sqs.AmazonSQS;
|
21 | 30 | import com.amazonaws.services.sqs.AmazonSQSClientBuilder;
|
22 | 31 | import com.amazonaws.services.sqs.model.CreateQueueResult;
|
| 32 | +import com.amazonaws.waiters.WaiterParameters; |
| 33 | +import com.github.dockerjava.api.DockerClient; |
23 | 34 | import lombok.extern.slf4j.Slf4j;
|
24 | 35 | import org.apache.commons.io.IOUtils;
|
25 | 36 | import org.junit.ClassRule;
|
26 | 37 | import org.junit.Test;
|
27 | 38 | import org.junit.experimental.runners.Enclosed;
|
28 | 39 | import org.junit.runner.RunWith;
|
| 40 | +import org.testcontainers.DockerClientFactory; |
29 | 41 | import org.testcontainers.containers.Container;
|
30 | 42 | import org.testcontainers.containers.GenericContainer;
|
31 | 43 | import org.testcontainers.containers.Network;
|
|
36 | 48 | import software.amazon.awssdk.regions.Region;
|
37 | 49 | import software.amazon.awssdk.services.s3.S3Client;
|
38 | 50 |
|
| 51 | +import java.io.ByteArrayOutputStream; |
39 | 52 | import java.io.IOException;
|
40 | 53 | import java.net.URL;
|
| 54 | +import java.nio.ByteBuffer; |
41 | 55 | import java.nio.charset.StandardCharsets;
|
42 | 56 | import java.time.Instant;
|
43 | 57 | import java.time.temporal.ChronoUnit;
|
| 58 | +import java.util.Collection; |
| 59 | +import java.util.Collections; |
44 | 60 | import java.util.Date;
|
45 | 61 | import java.util.List;
|
| 62 | +import java.util.Map; |
46 | 63 | import java.util.Optional;
|
| 64 | +import java.util.zip.ZipEntry; |
| 65 | +import java.util.zip.ZipOutputStream; |
47 | 66 |
|
48 | 67 | import static org.assertj.core.api.Assertions.assertThat;
|
49 | 68 |
|
@@ -505,4 +524,90 @@ public void shouldBeAccessibleWithCredentials() throws IOException {
|
505 | 524 | assertThat(content).as("The object can be retrieved").isEqualTo("baz");
|
506 | 525 | }
|
507 | 526 | }
|
| 527 | + |
| 528 | + public static class LambdaContainerLabels { |
| 529 | + |
| 530 | + @ClassRule |
| 531 | + public static LocalStackContainer localstack = new LocalStackContainer( |
| 532 | + LocalstackTestImages.LOCALSTACK_2_3_IMAGE |
| 533 | + ); |
| 534 | + |
| 535 | + private static byte[] createLambdaHandlerZipFile() throws IOException { |
| 536 | + StringBuilder sb = new StringBuilder(); |
| 537 | + sb.append("def handler(event, context):\n"); |
| 538 | + sb.append(" return event"); |
| 539 | + |
| 540 | + ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); |
| 541 | + ZipOutputStream out = new ZipOutputStream(byteOutput); |
| 542 | + ZipEntry e = new ZipEntry("handler.py"); |
| 543 | + out.putNextEntry(e); |
| 544 | + |
| 545 | + byte[] data = sb.toString().getBytes(); |
| 546 | + out.write(data, 0, data.length); |
| 547 | + out.closeEntry(); |
| 548 | + out.close(); |
| 549 | + return byteOutput.toByteArray(); |
| 550 | + } |
| 551 | + |
| 552 | + @Test |
| 553 | + public void shouldLabelLambdaContainers() throws IOException { |
| 554 | + AWSLambda lambda = AWSLambdaClientBuilder |
| 555 | + .standard() |
| 556 | + .withEndpointConfiguration( |
| 557 | + new AwsClientBuilder.EndpointConfiguration( |
| 558 | + localstack.getEndpoint().toString(), |
| 559 | + localstack.getRegion() |
| 560 | + ) |
| 561 | + ) |
| 562 | + .withCredentials( |
| 563 | + new AWSStaticCredentialsProvider( |
| 564 | + new BasicAWSCredentials(localstack.getAccessKey(), localstack.getSecretKey()) |
| 565 | + ) |
| 566 | + ) |
| 567 | + .build(); |
| 568 | + |
| 569 | + // create function |
| 570 | + byte[] handlerFile = createLambdaHandlerZipFile(); |
| 571 | + CreateFunctionRequest createFunctionRequest = new CreateFunctionRequest() |
| 572 | + .withFunctionName("test-function") |
| 573 | + .withRuntime(Runtime.Python311) |
| 574 | + .withHandler("handler.handler") |
| 575 | + .withRole("arn:aws:iam::000000000000:role/test-role") |
| 576 | + .withCode(new FunctionCode().withZipFile(ByteBuffer.wrap(handlerFile))); |
| 577 | + CreateFunctionResult createFunctionResult = lambda.createFunction(createFunctionRequest); |
| 578 | + GetFunctionRequest getFunctionRequest = new GetFunctionRequest() |
| 579 | + .withFunctionName(createFunctionResult.getFunctionName()); |
| 580 | + lambda |
| 581 | + .waiters() |
| 582 | + .functionActiveV2() |
| 583 | + .run(new WaiterParameters<GetFunctionRequest>().withRequest(getFunctionRequest)); |
| 584 | + |
| 585 | + // invoke function once |
| 586 | + String payload = "{\"test\": \"payload\"}"; |
| 587 | + InvokeRequest invokeRequest = new InvokeRequest() |
| 588 | + .withFunctionName(createFunctionResult.getFunctionName()) |
| 589 | + .withPayload(payload); |
| 590 | + InvokeResult invokeResult = lambda.invoke(invokeRequest); |
| 591 | + assertThat(StandardCharsets.UTF_8.decode(invokeResult.getPayload()).toString()) |
| 592 | + .as("Invoke result not matching expected output") |
| 593 | + .isEqualTo(payload); |
| 594 | + |
| 595 | + // assert that the spawned lambda containers has the testcontainers labels set |
| 596 | + DockerClient dockerClient = DockerClientFactory.instance().client(); |
| 597 | + Collection<String> nameFilter = Collections.singleton(localstack.getContainerName().replace("_", "-")); |
| 598 | + com.github.dockerjava.api.model.Container lambdaContainer = dockerClient |
| 599 | + .listContainersCmd() |
| 600 | + .withNameFilter(nameFilter) |
| 601 | + .exec() |
| 602 | + .stream() |
| 603 | + .findFirst() |
| 604 | + .orElse(null); |
| 605 | + assertThat(lambdaContainer).as("Lambda container not found").isNotNull(); |
| 606 | + Map<String, String> labels = lambdaContainer.getLabels(); |
| 607 | + assertThat(labels.get("org.testcontainers")).as("TestContainers label not present").isEqualTo("true"); |
| 608 | + assertThat(labels.get("org.testcontainers.sessionId")) |
| 609 | + .as("TestContainers session id not present") |
| 610 | + .isNotNull(); |
| 611 | + } |
| 612 | + } |
508 | 613 | }
|
0 commit comments