Невозможно запустить тесты для базы данных neo4j в GitLab CI docker -in- docker - PullRequest
0 голосов
/ 01 мая 2020

Проблема

Я пытаюсь запустить свои модульные тесты в GitLab CI. Для моей тестовой установки я использую docker -compose для запуска кластера базы данных из трех экземпляров neo4j, затем я запускаю тесты на хосте docker через localhost.

На моей машине это работает очень ну, поэтому я попытался сделать то же самое на GitLab CI. Сначала у меня были некоторые проблемы с получением docker -композиции для запуска внутри контейнера CI, но мне удалось заставить его работать со следующим .gitlab-ci.yaml:

image: "tiangolo/docker-with-compose:latest"

before_script:
    - apk add --update nodejs npm
    - npm install npm@latest -g
    - npm install

services:
  - docker:dind

run-test:
    script:
        - docker-compose up -d --build
        - npm test

Установлены зависимости, docker -compose успешно запускает базу данных, а npm test запускает мои модульные тесты. Все идет нормально. Но все тесты, которые используют соединение с базой данных в той или иной форме, терпят неудачу, потому что они не могут достичь его на локальном хосте: 7687 . Я получаю следующее сообщение об ошибке

Neo4jError: Could not perform discovery. No routing servers available. Known routing table: RoutingTable[database=default database, expirationTime=0, currentTime=1588275075260, routers=[], readers=[], writers=[]]

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

То, что я уже пробовал

Я подумал, что мои тесты запускаются до полного запуска базы данных, поэтому я добавил sleep 120 примерно так

run-test:
    script:
        - docker-compose up -d --build
        - sleep 120
        - npm test

Я даже измерил, сколько времени потребуется кластеру для запуска внутри контейнера CI, и правильно выбрал время ожидания, но, к счастью, тесты все равно не пройдены.

Затем я посмотрел на сети docker, чтобы посмотрим, что-то пошло не так

$ cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  docker 3590cde9c5df runner-k3xtxnwc-project-17881831-concurrent-0-6d9d78b64ad6df95-docker-0
172.17.0.3  runner-k3xtxnwc-project-17881831-concurrent-0

$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core1
172.19.0.2

$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core2
172.19.0.4

Но это выглядит хорошо для меня. Затем я попытался заменить localhost:7678 на docker:7678, 172.0.0.1 и даже $(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core1):7678. Но ни один из них не работает.

Попытка curl localhost:7474 (http-консоль neo4j) возвращает Failed to connect to localhost port 7474: Connection refused

РЕДАКТИРОВАТЬ:

My docker -compose.yaml

version: '3'
services:
        dbc1:
                build: ./database
                container_name: core1
                hostname: core1
                ports:
                        - 7474:7474
                        - 7687:7687
                environment: 
                        - NEO4J_dbms_mode=CORE
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
                        - NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
                        - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
                        - NEO4J_dbms_connector_bolt_advertised__address=localhost:7687
                        - NEO4J_dbms_connector_http_advertised__address=localhost:7474
                volumes:
                        - dbdata1:/data
                ulimits:
                        nofile:
                                soft: 40000
                                hard: 40000
        dbc2:
                build: ./database
                container_name: core2
                hostname: core2
                ports:
                        - 8474:7474
                        - 8687:7687
                environment: 
                        - NEO4J_dbms_mode=CORE
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
                        - NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
                        - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
                        - NEO4J_dbms_connector_bolt_advertised__address=localhost:8687
                        - NEO4J_dbms_connector_http_advertised__address=localhost:8474
                volumes:
                        - dbdata2:/data
                ulimits:
                        nofile:
                                soft: 40000
                                hard: 40000
        dbc3:
                build: ./database
                container_name: core3
                hostname: core3
                ports:
                        - 9474:7474
                        - 9687:7687
                environment: 
                        - NEO4J_dbms_mode=CORE
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
                        - NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
                        - NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
                        - NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
                        - NEO4J_dbms_connector_bolt_advertised__address=localhost:9687
                        - NEO4J_dbms_connector_http_advertised__address=localhost:9474
                volumes:
                        - dbdata3:/data
                ulimits:
                        nofile:
                                soft: 40000
                                hard: 40000
volumes:
        dbdata1:
                driver: local
        dbdata2:
                driver: local
        dbdata3:
                driver: local

Dockerfile моей базы данных (находится в ./database):

FROM graphfoundation/ongdb:3.6

RUN echo "* soft nofile 40000" >> /etc/security/limits.conf
RUN echo "* hard nofile 40000" >> /etc/security/limits.conf

## inject password change into startup script
# create alternative startup script
RUN echo "#!/bin/bash -eu" >> /docker-entrypoint-modified.sh 

# add command to change password
RUN echo "bin/neo4j-admin set-initial-password testpassword" >> /docker-entrypoint-modified.sh

# copy the contents of docker-entrypoint.sh, but skip the first line
RUN tail -n +2 /docker-entrypoint.sh >> /docker-entrypoint-modified.sh

# replace docker-entrypoint.sh with docker-entrypoint-modify
RUN cat /docker-entrypoint-modified.sh > /docker-entrypoint.sh


EXPOSE 7474 7473 7687

1 Ответ

0 голосов
/ 07 мая 2020

Оказывается, у меня были некоторые неправильные представления о docker -in- docker, я решил проблему, «перенаправив» localhost на службу docker -in- docker, изменив следующие строки в моем .gitlab-ci.yaml:

services:
  - docker:dind

до

services:
  - name: docker:dind
    alias: localhost
...