#java #amazon-web-services #junit #gitlab-ci #localstack
# #java #amazon-веб-сервисы #junit #gitlab-ci #localstack
Вопрос:
У меня проблема с запуском тестов интеграции Java с LocalstackTestRunner
агентом Gitlab. Я взял пример с официального сайта localstack:
import cloud.localstack.LocalstackTestRunner;
import cloud.localstack.TestUtils;
import cloud.localstack.docker.annotation.LocalstackDockerProperties;
@RunWith(LocalstackTestRunner.class)
@LocalstackDockerProperties(services = { "s3", "sqs", "kinesis:77077" })
public class MyCloudAppTest {
@Test
public void testLocalS3API() {
AmazonS3 s3 = TestUtils.getClientS3();
List<Bucket> buckets = s3.listBuckets();
}
}
и запустите его с помощью gradle as gradle clean test
.
Если я запускаю его локально на своем Mac Book — все в порядке, но если он запускается на агенте Gitlab — возникает проблема:
com.amazonaws.SdkClientException: Unable to execute HTTP request: Connect to localhost.localstack.cloud:4566 [localhost.localstack.cloud/127.0.0.1] failed: Connection refused (Connection refused)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleRetryableException(AmazonHttpClient.java:1207)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1153)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
Моя работа в gitlab ci выглядит следующим образом:
Localstack_test:
stage: test
services:
- docker:dind
when: always
script:
- ./gradlew clean test --stacktrace
Случается, что клиент S3 не может подключиться localhost.localstack.cloud:4566
, потому что контейнер docker, созданный LocalstackTestRunner
docker, запускается в родительском docker:dind
контейнере, а клиент AmazonS3 не может получить к нему доступ. Я пробовал с другими сервисами AWS — результат тот же — клиент AWS не может получить доступ к конечной точке localstack.
Я нашел несколько обходных путей следующим образом:
- добавьте localstack как сервис в gitlab-ci
- добавьте к нему псевдоним
- выставить переменную env HOSTNAME_EXTERNAL=псевдоним
- Сделайте реализацию
IHostNameResolver
, чтобы вернуть мой псевдоним как HOSTNAME_EXTERNAL, указанный в gitlab-ci.
Что-то вроде этого:
Gitlab-ci:
Localstack_test:
stage: test
services:
- docker:dind
- name: localstack/localstack
alias: localstack-it
variables:
HOSTNAME_EXTERNAL: "localstack-it"
when: always
script:
- ./gradlew clean test --stacktrace |amp; tee -a ./gradle.log
Java IT тест:
@RunWith(LocalstackTestRunner.class)
@LocalstackDockerProperties(
services = { "s3", "sqs", "kinesis:77077" },
hostNameResolver = SystemEnvHostNameResolver.class
)
public class MyCloudAppTest {
@Test
public void testLocalS3API() {
AmazonS3 s3 = TestUtils.getClientS3();
List<Bucket> buckets = s3.listBuckets();
}
}
public class SystemEnvHostNameResolver implements IHostNameResolver {
private static final String HOSTNAME_EXTERNAL = "HOSTNAME_EXTERNAL";
@Override
public String getHostName() {
String external = System.getenv(HOSTNAME_EXTERNAL);
return !Strings.isNullOrEmpty(external) ?
external :
new LocalHostNameResolver().getHostName();
}
}
Это работает, но в результате запускаются 2 контейнера localstack Docker, а внутренний контейнер docker по-прежнему недоступен. Может быть, кто-нибудь знает лучшее решение?
STR:
- gradle-6.7
- облако.localstack: localstack-utils:0.2.5