Как настроить тестовые контейнеры для запуска паралллера с помощью docker compose?

Вот файл docker-compose:

  app:
    image: myimage
    depends_on:
      - nsqd
      - localstack
    command: ["run.sh"]
    environment:
      - "DYNAMODB=http://localstack:4569"
    ports:
      - 8080:8080

  nsqd:
    image: nsqio/nsq
    command: /run
    ports:
      - "4150:4150"
      - "4151:4151"

  localstack:
    image: localstack/localstack:latest
    ports:
      - 4569:4569
    environment:
      SERVICES: dynamodb
      DATA_DIR: /tmp/localstack/data
      HOSTNAME: localstack

Этот файл компоновки запускается в тесте java junit перед запуском любого метода тестирования:

  @Before
  public void setUp() throws Exception {
        new DockerComposeContainer(new File("docker-compose.yaml"))
                .withExposedService("nsqd", 4150, Wait.forListeningPort())
                .withExposedService("localstack", 4569, Wait.forListeningPort())
                .withExposedService("app", 8080, Wait.forListeningPort())
                .start();
  }

Когда все методы тестирования запускаются один за другим, никаких проблем не возникает. Но когда я пытаюсь запустить более двух тестов одновременно, я получаю такие ошибки:

ERROR: for localstack  Cannot start service localstack: driver failed programming external connectivity on endpoint hwfdrbmwpwn1_localstack_1 (e33d2a3098e74b1b8d87e3e595d9d9504ccddd4fe9c0605b20ebd3f22f50daa5): Bind for 0.0.0.0:4569 failed: port is already allocated
ERROR: for nsqlookupd  Cannot start service nsqlookupd: driver failed programming external connectivity on endpoint hwfdrbmwpwn1_nsqlookupd_1 (fe62cec02a23a184d65b3f02776a14d77fdfbe639645ea0a11e07e8f11010e37): Bind for 0.0.0.0:4161 failed: port is already allocated

И этот порт отличается от функции withExposedService. С другой стороны, все службы из файла compose запущены в изолированной сети, поэтому конфликтов быть не должно, но они существуют. Может какие-нибудь бподы объяснить, что творится с портами? Какая дополнительная конфигурация должна быть предоставлена ​​тестовым контейнерам для запуска служб docker-compose несколько раз в одно и то же время?


person Cherry    schedule 07.08.2019    source источник


Ответы (2)


Порт, определенный с помощью withExposedService, относится к внутреннему виду контейнера. Testcontainers привяжет этот порт к случайному внешнему порту. Прочтите здесь:

https://www.testcontainers.org/features/networking

Вы также останавливаете свои контейнеры для сборки докеров перед каждым методом тестирования?

Я также предлагаю удалить сопоставление портов из вашего файла docker compose, поскольку это не требуется для testcontainers:

Обратите внимание, что необязательно определять порты, которые будут отображаться в файле YAML; это препятствовало бы повторному использованию / включению файла в других контекстах.

Взято с: https://www.testcontainers.org/modules/docker_compose/.

person jwi    schedule 14.08.2019
comment
Do you also stop your docker compose containers before each test method? - вот как это работает и чего следует избегать. Да start -> test -> stop работает. Но я хочу запустить несколько docker-compose со множеством случайных портов и вызывать методы тестирования параллельно, а не один за другим, и это проблема. - person Cherry; 05.09.2019
comment
Ммм, я не вижу в этом проблемы. Testcontainers сопоставляет ваш контейнер docker compose со случайными портами вашей хост-системы, поэтому параллельный запуск нескольких контейнеров docker compose не должен быть проблемой. - person jwi; 06.09.2019
comment
Mmh, I don't see the problem вы пробовали код? - person Cherry; 10.09.2019

Если я правильно понял вашу настройку, вы хотите запускать и останавливать контейнеры docker-compose для каждого теста и делать это с потенциально несколькими разными docker-compose-файлами в разных тестах (или разных тестах с одним и тем же файлом) одновременно.

Существует альтернативная библиотека, Docker-Compose-Rule of Palantir!.

На самом деле между этими двумя (testContainers и Palantir) происходит сотрудничество, поскольку testContainers гораздо более универсален, но библиотека Palantir была более глубокой с использованием docker-compose. Сотрудничество началось в 2018 году, но на данный момент библиотека все еще поддерживается, поэтому у нее все еще может быть преимущество специализации, которое решает вашу проблему.

person F. Meckel    schedule 03.04.2020