Использование docker-образа с Testcontainers

183
07 марта 2019, 15:50

Всем привет. Для меня Testcontainers абсолютно новая тема, поэтому возник вопрос. У меня есть приложение на Spring/Hibernate У меня есть docker image (h2testbase) с кастомной mysql-базой (myTestDb) для тестов (она уже готовая с данными). Я запускаю этот образ в докере с -p 6161:3306. В папке test/resources у меня лежит application.properties со следующим содержанием

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:6161/myTestDb?allowPublicKeyRetrieval=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow&&useSSL=false
jdbc.username=root
jdbc.cred=admin
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.format_sql=true

Прогоняю тесты с помощью mvn test - все работает. Теперь я хочу запускать эти тесты с помощью Testcontainers. Добавил в pom

<dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>testcontainers</artifactId>
   <version>1.9.1</version>
</dependency>
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>mysql</artifactId>
    <version>1.9.1</version>
    <scope>test</scope>
</dependency>

Я наследовал класс MySQLContainer

public class TestMySQL extends MySQLContainer {
    public TestMySQL() {
        super();
    }
    public TestMySQL(String dockerImageName) {
        super(dockerImageName);
    }
    @Override
    public String getDriverClassName() {
        return "com.mysql.cj.jdbc.Driver";
    }
}

так как сам MySQLContainer использует com.mysql.jdbc.Driver и maven не принимает его как deprecated. В тесте я пишу

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {
        HibernateConfiguration.class,
        SecurityConfiguration.class,
        SecurityInitializer.class,
        ViewConfiguration.class,
        ViewInitializer.class})
@WebAppConfiguration
public class ControllerServiceJTest {
    @ClassRule
    public static TestMySQL  container
            = new TestMySQL("h2testbase");
    @Autowired
    ControllerService controllerService;
    @Test
    public void stationPagination() {
        Map<String, Object> pag = controllerService.stationPagination(4);
        Assert.assertTrue(((List<Station>)pag.get("stations")).size() == 8);
    }
    @Test
    public void trainPagination() {
        Map<String, Object> pag = controllerService.trainPagination(1);
        Assert.assertTrue(((List<Train>)pag.get("trains")).size() == 20);
    }
    @Test
    public void switchHelper() {
        Assert.assertTrue(controllerService.stationSwitchHelper("BLUE").equals(URLs.REDIRECT_DASHSTATION + "/2"));
    }
}

И тут у меня ступор. Если я запущу mvn test, то через docker ps я вижу, что контейнер стартует (но на какие то левые порты типа 328хх), причем запускается несколько инстансов, но через некоторое время maven выдает следующее

org.testcontainers.containers.ContainerLaunchException: Container startup failed
Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception
Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container
Caused by: org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
Caused by: java.util.concurrent.TimeoutException

Что делать дальше? Как указать создаваемому контейнеру на какой порт маппиться? Как передать ему параметры, которые прописаны в application.properties? Я не в состоянии найти ни одного примера кода, где использовался бы образ с готовой базой. Заранее спасибо.

Answer 1

Используйте метод withPortBindings и withExposedPorts при создании контейнера.

int hostPort = 6380;
int containerExposedPort = 6379;
Consumer<CreateContainerCmd> cmd = e -> e.withPortBindings(new PortBinding(Ports.Binding.bindPort(hostPort), new ExposedPort(containerExposedPort)));
GenericContainer redisContainer = new GenericContainer("redis:4.0.10")
                    .withExposedPorts(containerExposedPort)
                    .withCreateContainerCmdModifier(cmd);
READ ALSO
VenoBox - слишком большой margin-top, margin-bottom

VenoBox - слишком большой margin-top, margin-bottom

Сайт на WordPress, при открытии фотографии уvbox-content слишком большой margin-top и margin-bottom

151
Почему не работает плеер в v-for?

Почему не работает плеер в v-for?

Есть плеер с сервиса yohoho(не реклама)Беру их скрипт, добавляю в index

151
связать 2 текстовых поля через чистый js

связать 2 текстовых поля через чистый js

у меня такой вопрос, есть 2 поля которые нужно связать, оставляю код:

180
Не работает ng-include AngularJS

Не работает ng-include AngularJS

Установил xamppРазрабатываю проект на AngularJS

238