Не удается запустить localstack в Gitlab runner с помощью LocalstackTestRunner

#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