Недавно я пытался выяснить, как выполнить интеграционные тесты, используя TestContainers на Jenkins, где они запускаются внутри другого Docker образа, но безуспешно.
Версия TestContainers: 1.13 .0
Команда, которая выполняется на Jenkins, выглядит примерно так (я удалила некоторые переменные env и личные данные):
docker run --rm -v /home/jenkins/.m2:/root/.m2 -v /home/jenkins/.sbt:/root/.sbt -v /home/jenkins/.ivy2:/root/.ivy2 -v /home/jenkins/workspace/re_FC-5370-create-dummy-endpoint@2:/home/jenkins/workspace/re_FC-5370-create-dummy-endpoint@2 -w /home/jenkins/workspace/re_FC-5370-create-dummy-endpoint@2 -v /var/run/docker.sock:/var/run/docker.sock registry/build-java-app-image ./ci/test.sh
Итак, сокет открыт, $PWD
смонтирован и установлен как рабочее пространство, как описано здесь: https://www.testcontainers.org/supported_docker_environment/continuous_integration/dind_patterns/, но я все еще получаю ошибку.
Теперь есть два типа ошибок. Первый - NoRouteToHostException
, который происходит, если в test.sh
я просто запускаю ./gradlew test
с этой настройкой:
@Container
private static PostgreSQLContainer postgresqlContainer = new PostgreSQLContainer("postgres:12.2-alpine");
static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of(
"spring.datasource.url=" + postgresqlContainer.getJdbcUrl(),
"spring.datasource.username=" + postgresqlContainer.getUsername(),
"spring.datasource.password=" + postgresqlContainer.getPassword(),
"spring.datasource.driverClassName=" + postgresqlContainer.getDriverClassName()
).applyTo(configurableApplicationContext);
}
}
ПРИМЕЧАНИЕ: Это работает локально из терминала, простой запуск из IntelliJ и даже из Docker image.
Вторая ошибка возникает, если я пытаюсь настроить Docker сеть в test.sh
сценарии:
docker network create --driver bridge "build-$HOSTNAME"
docker network connect "build-$HOSTNAME" $outerContainerId
export dockerNetworkId=$(docker network ls --no-trunc --filter name="build-$HOSTNAME" --format "{{.ID}}")
Установка, которая использует открытый идентификатор сети:
private static final String networkId = System.getenv("dockerNetworkId");
@Container
private static PostgreSQLContainer postgresqlContainer = (PostgreSQLContainer)
new PostgreSQLContainer("postgres:12.2-alpine")
.withNetwork(Network.builder().id(networkId).build())
.withNetworkAliases("test-database-container");
static class Initializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues.of(
"spring.datasource.url=jdbc:postgresql://test-database-container:5432/test",
"spring.datasource.username=" + postgresqlContainer.getUsername(),
"spring.datasource.password=" + postgresqlContainer.getPassword(),
"spring.datasource.driverClassName=" + postgresqlContainer.getDriverClassName()
).applyTo(configurableApplicationContext);
}
}
Итак, я создал сеть, связал ее с сетью контейнера Jenkins и показал ее идентификатор, чтобы я мог получить его в тестах. В тестах я создал контейнер с этим идентификатором сети и дал ему имя, чтобы я мог ссылаться на него в URL.
Эта настройка дает мне UnknownHostException
с сообщением: test-database-container
, и я не могу понять из того, что беспокоит.
Я попробовал также некоторые другие варианты, где я бы настроил сеть, но использовал бы первый подход или не настроил бы сеть и использовал второй подход с Docker IP, что TestContainers является возвращая вместо сетевого псевдонима, но ничего не получалось. Я всегда получаю одно из этих двух исключений.