From 23d44c1d0db15af14602c1de83450c3698375f2f Mon Sep 17 00:00:00 2001 From: ErickSkrauch Date: Fri, 15 Jul 2016 01:03:13 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D0=BE?= =?UTF-8?q?=D0=B5=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BE?= =?UTF-8?q?=D1=82=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?,=20=D1=83=D0=BF=D1=80=D0=BE=D1=89=D0=B5=D0=BD=D1=8B=20=D0=B1?= =?UTF-8?q?=D0=B8=D0=BB=D0=B4=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B5=D0=B9=D0=BD=D0=B5=D1=80=D0=BE=D0=B2=20MariaD?= =?UTF-8?q?B=20=D0=B8=20RabbitMQ,=20=D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0?= =?UTF-8?q?=D0=BD=D1=8B=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B1=D1=8B=D1=81=D1=82=D1=80=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BE=D0=BD=D0=B0=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +- composer.json | 3 - docker-compose.yml | 18 +- docker/mariadb/Dockerfile | 10 - docker/mariadb/init.sh | 34 --- docker/mariadb/run.sh | 9 - docker/rabbitmq/Dockerfile | 5 - docker/rabbitmq/init.sh | 44 ---- docker/rabbitmq/run.sh | 8 - docker/wait-for-it.sh | 202 +++++++++--------- .../docker/common/config/main-local.php | 4 +- tests/README.md | 58 ----- tests/codeception/api/_bootstrap.php | 2 - tests/codeception/api/functional.suite.yml | 6 +- tests/codeception/config/config.php | 10 +- tests/codeception/console/_bootstrap.php | 1 + tests/docker-compose.yml | 30 +++ tests/php.sh | 8 + tests/run-tests.sh | 6 + 19 files changed, 166 insertions(+), 299 deletions(-) delete mode 100644 docker/mariadb/init.sh delete mode 100644 docker/mariadb/run.sh delete mode 100644 docker/rabbitmq/init.sh delete mode 100644 docker/rabbitmq/run.sh delete mode 100644 tests/README.md create mode 100644 tests/docker-compose.yml create mode 100755 tests/php.sh create mode 100755 tests/run-tests.sh diff --git a/README.md b/README.md index 1f2257d..4c3cd23 100644 --- a/README.md +++ b/README.md @@ -62,10 +62,5 @@ docker-compose restart ## Тестирование php бэкэнда ```sh -# Прежде чем тестировать, необходимо накатить миграции -docker exec -it app php tests/codeception/bin/yii migrate --interactive=0 -# Собрать все тестовые окружения -docker exec -it app ./vendor/bin/codecept build -c tests -# И запустить собственно процесс тестирования -docker exec -it app ./vendor/bin/codecept run -c tests +./tests/run-tests.sh ``` diff --git a/composer.json b/composer.json index 513b521..46ae60d 100644 --- a/composer.json +++ b/composer.json @@ -46,9 +46,6 @@ } ], "scripts": { - "build-tests" : "cd tests && codecept build", - "test" : "codecept run -c tests", - "test-api" : "codecept run -c tests/codeception/api", "phploc" : "phploc ./api ./common ./console" } } diff --git a/docker-compose.yml b/docker-compose.yml index 3c4a249..4e848ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,8 +2,6 @@ version: '2' services: app: build: . - expose: - - "9000" links: - db - redis @@ -13,9 +11,6 @@ services: volumes: - ./:/var/www/html/ env_file: .env - environment: - ENABLE_ENV_FILE: 1 - ENABLE_LOCALCONF: 1 web: build: ./docker/nginx @@ -47,14 +42,24 @@ services: db: build: ./docker/mariadb + environment: + MYSQL_ROOT_PASSWORD: "" + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_DATABASE: "ely_accounts" + MYSQL_USER: "ely_accounts_user" + MYSQL_PASSWORD: "ely_accounts_password" redis: image: redis:3.0 rabbitmq: build: ./docker/rabbitmq + environment: + RABBITMQ_DEFAULT_USER: "ely-accounts-app" + RABBITMQ_DEFAULT_PASS: "app-password" + RABBITMQ_DEFAULT_VHOST: "/account.ely.by" ports: - - "15672:15672" + - "15672:15672" # Manager interface phpmyadmin: build: ./docker/phpmyadmin @@ -62,7 +67,6 @@ services: - PMA_ARBITRARY=1 - PMA_USER=root - PMA_PASSWORD= - restart: always ports: - "8181:80" links: diff --git a/docker/mariadb/Dockerfile b/docker/mariadb/Dockerfile index a203ef6..ae236a8 100644 --- a/docker/mariadb/Dockerfile +++ b/docker/mariadb/Dockerfile @@ -1,13 +1,3 @@ FROM mariadb:10.0 COPY mariadb.cnf /etc/mysql/conf.d - -# Add script to create default users / vhosts -ADD init.sh /init.sh -ADD run.sh /run.sh - -# Run rabbitmq, execute init configuration and then shutdown -RUN chmod +x /init.sh /run.sh \ - && /init.sh - -ENTRYPOINT "/run.sh" diff --git a/docker/mariadb/init.sh b/docker/mariadb/init.sh deleted file mode 100644 index 9628fa5..0000000 --- a/docker/mariadb/init.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash - -# Копипаста. Я не знаю, что тут происходит - -set -e -set -x - -mysql_install_db - -# Start the MySQL daemon in the background. -/usr/sbin/mysqld & -mysql_pid=$! - -until mysqladmin ping &>/dev/null; do - echo -n "."; sleep 0.2 -done - -# Конец рандомной копипасты - -# Устаналиваем беспарольный доступ для рута -mysql -e "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '' WITH GRANT OPTION" - -# Создаём базу данных для приложения и для тестов -mysql -e "CREATE DATABASE IF NOT EXISTS ely_accounts CHARACTER SET utf8 COLLATE utf8_general_ci" -mysql -e "CREATE DATABASE IF NOT EXISTS ely_accounts_test CHARACTER SET utf8 COLLATE utf8_general_ci" - -# Tell the MySQL daemon to shutdown. -mysqladmin shutdown - -# Wait for the MySQL daemon to exit. -wait $mysql_pid - -# Сохраняем состояние базы данных -tar czvf default_mysql.tar.gz /var/lib/mysql diff --git a/docker/mariadb/run.sh b/docker/mariadb/run.sh deleted file mode 100644 index c8dffad..0000000 --- a/docker/mariadb/run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -set -e -set -x - -# first, if the /var/lib/mysql directory is empty, unpack it from our predefined db -[ "$(ls -A /var/lib/mysql)" ] && echo "Running with existing database in /var/lib/mysql" || ( echo 'Populate initial db'; tar xpzvf default_mysql.tar.gz ) - -/usr/sbin/mysqld diff --git a/docker/rabbitmq/Dockerfile b/docker/rabbitmq/Dockerfile index 6d18711..27005d8 100644 --- a/docker/rabbitmq/Dockerfile +++ b/docker/rabbitmq/Dockerfile @@ -3,8 +3,3 @@ FROM rabbitmq:3.6 RUN rabbitmq-plugins enable rabbitmq_management \ && rabbitmq-plugins enable rabbitmq_web_stomp \ && rabbitmq-plugins enable rabbitmq_mqtt - -# Add script to create default users / vhosts -ADD init.sh /init.sh - -RUN chmod +x /init.sh diff --git a/docker/rabbitmq/init.sh b/docker/rabbitmq/init.sh deleted file mode 100644 index ec7be76..0000000 --- a/docker/rabbitmq/init.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh - -#( sleep 10 ; \ -# -## Create users -#rabbitmqctl add_user ely-accounts-app app-password ; \ -#rabbitmqctl add_user ely-accounts-tester tester-password ; \ -# -## Set user rights -#rabbitmqctl set_user_tags ely-accounts-app administrator ; \ -#rabbitmqctl set_user_tags ely-accounts-tester administrator ; \ -# -## Create vhosts -#rabbitmqctl add_vhost /account.ely.by ; \ -#rabbitmqctl add_vhost /account.ely.by/tests ; \ -# -## Set vhost permissions -#rabbitmqctl set_permissions -p /account.ely.by ely-accounts-app ".*" ".*" ".*" ; \ -#rabbitmqctl set_permissions -p /account.ely.by/tests ely-accounts-tester ".*" ".*" ".*" ; \ -#) & -#rabbitmq-server $@ - -#service rabbitmq-server start - -# Create users -rabbitmqctl add_user ely-accounts-app app-password -rabbitmqctl add_user ely-accounts-tester tester-password - -# Set user rights -rabbitmqctl set_user_tags ely-accounts-app administrator -rabbitmqctl set_user_tags ely-accounts-tester administrator - -# Create vhosts -rabbitmqctl add_vhost /account.ely.by -rabbitmqctl add_vhost /account.ely.by/tests - -# Set vhost permissions -rabbitmqctl set_permissions -p /account.ely.by ely-accounts-app ".*" ".*" ".*" -rabbitmqctl set_permissions -p /account.ely.by/tests ely-accounts-tester ".*" ".*" ".*" - -#service rabbitmq-server stop - -# Сохраняем состояние рэбита -#tar czvf default_rabbitmq.tar.gz /var/lib/rabbitmq/mnesia diff --git a/docker/rabbitmq/run.sh b/docker/rabbitmq/run.sh deleted file mode 100644 index 324fcf2..0000000 --- a/docker/rabbitmq/run.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash - -set -e -set -x - -[ "$(ls -A /var/lib/rabbitmq/mnesia)" ] && echo "Running with existing rabbitmq in /var/lib/rabbitmq" || ( echo 'Populate initial rabbitmq'; tar xpzvf default_rabbitmq.tar.gz ) - -rabbitmq-server diff --git a/docker/wait-for-it.sh b/docker/wait-for-it.sh index eca6c3b..172bfff 100755 --- a/docker/wait-for-it.sh +++ b/docker/wait-for-it.sh @@ -1,18 +1,15 @@ #!/usr/bin/env bash # Use this script to test if a given TCP host/port are available +# https://github.com/jlordiales/wait-for-it (fork of original source) cmdname=$(basename $0) echoerr() { if [[ $QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } -usage() -{ +usage() { cat << USAGE >&2 Usage: $cmdname host:port [-s] [-t timeout] [-- command args] - -h HOST | --host=HOST Host or IP under test - -p PORT | --port=PORT TCP port under test - Alternatively, you specify the host and port as host:port -s | --strict Only execute subcommand if the test succeeds -q | --quiet Don't output any status messages -t TIMEOUT | --timeout=TIMEOUT @@ -22,21 +19,22 @@ USAGE exit 1 } -wait_for() -{ +wait_for() { + local wait_host=$1 + local wait_port=$2 if [[ $TIMEOUT -gt 0 ]]; then - echoerr "$cmdname: waiting $TIMEOUT seconds for $HOST:$PORT" + echoerr "$cmdname: waiting $TIMEOUT seconds for $wait_host:$wait_port" else - echoerr "$cmdname: waiting for $HOST:$PORT without a timeout" + echoerr "$cmdname: waiting for $wait_host:$wait_port without a timeout" fi - start_ts=$(date +%s) + local start_ts=$(date +%s) while : do - (echo > /dev/tcp/$HOST/$PORT) >/dev/null 2>&1 - result=$? + (echo > /dev/tcp/$wait_host/$wait_port) >/dev/null 2>&1 + local result=$? if [[ $result -eq 0 ]]; then - end_ts=$(date +%s) - echoerr "$cmdname: $HOST:$PORT is available after $((end_ts - start_ts)) seconds" + local end_ts=$(date +%s) + echoerr "$cmdname: $wait_host:$wait_port is available after $((end_ts - start_ts)) seconds" break fi sleep 1 @@ -44,111 +42,109 @@ wait_for() return $result } -wait_for_wrapper() -{ +wait_for_wrapper() { + local wait_host=$1 + local wait_port=$2 # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 if [[ $QUIET -eq 1 ]]; then - timeout $TIMEOUT $0 --quiet --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + timeout $TIMEOUT $0 $wait_host:$wait_port --quiet --child --timeout=$TIMEOUT & else - timeout $TIMEOUT $0 --child --host=$HOST --port=$PORT --timeout=$TIMEOUT & + timeout $TIMEOUT $0 $wait_host:$wait_port --child --timeout=$TIMEOUT & fi PID=$! trap "kill -INT -$PID" INT wait $PID RESULT=$? if [[ $RESULT -ne 0 ]]; then - echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $HOST:$PORT" + echoerr "$cmdname: timeout occurred after waiting $TIMEOUT seconds for $wait_host:$wait_port" fi return $RESULT } -# process arguments -while [[ $# -gt 0 ]] -do - case "$1" in - *:* ) - hostport=(${1//:/ }) - HOST=${hostport[0]} - PORT=${hostport[1]} - shift 1 - ;; - --child) - CHILD=1 - shift 1 - ;; - -q | --quiet) - QUIET=1 - shift 1 - ;; - -s | --strict) - STRICT=1 - shift 1 - ;; - -h) - HOST="$2" - if [[ $HOST == "" ]]; then break; fi - shift 2 - ;; - --host=*) - HOST="${1#*=}" - shift 1 - ;; - -p) - PORT="$2" - if [[ $PORT == "" ]]; then break; fi - shift 2 - ;; - --port=*) - PORT="${1#*=}" - shift 1 - ;; - -t) - TIMEOUT="$2" - if [[ $TIMEOUT == "" ]]; then break; fi - shift 2 - ;; - --timeout=*) - TIMEOUT="${1#*=}" - shift 1 - ;; - --) - shift - CLI="$@" - break - ;; - --help) - usage - ;; - *) - echoerr "Unknown argument: $1" - usage - ;; - esac -done +parse_arguments() { + local index=0 + while [[ $# -gt 0 ]] + do + case "$1" in + *:* ) + hostport=(${1//:/ }) + HOST[$index]=${hostport[0]} + PORT[$index]=${hostport[1]} + shift 1 + ;; + --child) + CHILD=1 + shift 1 + ;; + -q | --quiet) + QUIET=1 + shift 1 + ;; + -s | --strict) + STRICT=1 + shift 1 + ;; + -t) + TIMEOUT="$2" + if [[ $TIMEOUT == "" ]]; then break; fi + shift 2 + ;; + --timeout=*) + TIMEOUT="${1#*=}" + shift 1 + ;; + --) + shift + CLI="$@" + break + ;; + --help) + usage + ;; + *) + echoerr "Unknown argument: $1" + usage + ;; + esac + let index+=1 + done + if [[ ${#HOST[@]} -eq 0 || ${#PORT[@]} -eq 0 ]]; then + echoerr "Error: you need to provide a host and port to test." + usage + fi +} -if [[ "$HOST" == "" || "$PORT" == "" ]]; then - echoerr "Error: you need to provide a host and port to test." - usage -fi +iterate_hosts() { + local result=0 + local index=0 + local wait_function=$1 + while [[ $result -eq 0 && $index -lt ${#HOST[@]} ]]; do + ($wait_function ${HOST[$index]} ${PORT[$index]}) + result=$? + let index+=1 + done + echo $result +} -TIMEOUT=${TIMEOUT:-15} -STRICT=${STRICT:-0} -CHILD=${CHILD:-0} -QUIET=${QUIET:-0} +wait_for_services() { + TIMEOUT=${TIMEOUT:-15} + STRICT=${STRICT:-0} + CHILD=${CHILD:-0} + QUIET=${QUIET:-0} -if [[ $CHILD -gt 0 ]]; then - wait_for - RESULT=$? - exit $RESULT -else - if [[ $TIMEOUT -gt 0 ]]; then - wait_for_wrapper - RESULT=$? - else - wait_for - RESULT=$? - fi -fi + if [[ $CHILD -gt 0 ]]; then + exit $(iterate_hosts wait_for) + else + if [[ $TIMEOUT -gt 0 ]]; then + RESULT=$(iterate_hosts wait_for_wrapper) + else + RESULT=$(iterate_hosts wait_for) + fi + fi +} + +parse_arguments "$@" +wait_for_services if [[ $CLI != "" ]]; then if [[ $RESULT -ne 0 && $STRICT -eq 1 ]]; then diff --git a/environments/docker/common/config/main-local.php b/environments/docker/common/config/main-local.php index 57ca3c0..2a1c61d 100644 --- a/environments/docker/common/config/main-local.php +++ b/environments/docker/common/config/main-local.php @@ -3,8 +3,8 @@ return [ 'components' => [ 'db' => [ 'dsn' => 'mysql:host=db;dbname=ely_accounts', - 'username' => 'root', - 'password' => '', + 'username' => 'ely_accounts_user', + 'password' => 'ely_accounts_password', ], 'mailer' => [ 'useFileTransport' => true, diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index ad7f016..0000000 --- a/tests/README.md +++ /dev/null @@ -1,58 +0,0 @@ -This directory contains various tests for the advanced applications. - -Tests in `codeception` directory are developed with [Codeception PHP Testing Framework](http://codeception.com/). - -After creating and setting up the advanced application, follow these steps to prepare for the tests: - -1. Install Codeception if it's not yet installed: - - ``` - composer global require "codeception/codeception=2.0.*" "codeception/specify=*" "codeception/verify=*" - ``` - - If you've never used Composer for global packages run `composer global status`. It should output: - - ``` - Changed current directory to - ``` - - Then add `/vendor/bin` to you `PATH` environment variable. Now you're able to use `codecept` from command - line globally. - -2. Install faker extension by running the following from template root directory where `composer.json` is: - - ``` - composer require --dev yiisoft/yii2-faker:* - ``` - -3. Create `yii2_advanced_tests` database then update it by applying migrations: - - ``` - codeception/bin/yii migrate - ``` - -4. In order to be able to run acceptance tests you need to start a webserver. The simplest way is to use PHP built in - webserver. In the root directory where `common`, `frontend` etc. are execute the following: - - ``` - php -S localhost:8080 - ``` - -5. Now you can run the tests with the following commands, assuming you are in the `tests/codeception` directory: - - ``` - # frontend tests - cd frontend - codecept build - codecept run - - # backend tests - - cd backend - codecept build - codecept run - - # etc. - ``` - - If you already have run `codecept build` for each application, you can skip that step and run all tests by a single `codecept run`. diff --git a/tests/codeception/api/_bootstrap.php b/tests/codeception/api/_bootstrap.php index 2344a50..f637ca1 100644 --- a/tests/codeception/api/_bootstrap.php +++ b/tests/codeception/api/_bootstrap.php @@ -21,6 +21,4 @@ $_SERVER['SERVER_NAME'] = parse_url(\Codeception\Configuration::config()['confi $_SERVER['SERVER_PORT'] = parse_url(\Codeception\Configuration::config()['config']['test_entry_url'], PHP_URL_PORT) ?: '80'; Yii::setAlias('@tests', dirname(dirname(__DIR__))); - -// disable deep cloning of properties inside specify block \Codeception\Specify\Config::setDeepClone(false); diff --git a/tests/codeception/api/functional.suite.yml b/tests/codeception/api/functional.suite.yml index eb80cc5..49ff5d6 100644 --- a/tests/codeception/api/functional.suite.yml +++ b/tests/codeception/api/functional.suite.yml @@ -12,11 +12,11 @@ modules: Yii2: configFile: '../config/api/functional.php' Redis: - host: redis + host: testredis port: 6379 - database: 1 + database: 0 AMQP: - host: rabbitmq + host: testrabbit port: 5672 username: 'ely-accounts-tester' password: 'tester-password' diff --git a/tests/codeception/config/config.php b/tests/codeception/config/config.php index c6ea34b..c9038e1 100644 --- a/tests/codeception/config/config.php +++ b/tests/codeception/config/config.php @@ -1,7 +1,4 @@ 'en-US', 'controllerMap' => [ @@ -14,7 +11,9 @@ return [ ], 'components' => [ 'db' => [ - 'dsn' => 'mysql:host=db;dbname=ely_accounts_test', + 'dsn' => 'mysql:host=testdb;dbname=ely_accounts_test', + 'username' => 'ely_accounts_tester', + 'password' => 'ely_accounts_tester_password', ], 'mailer' => [ 'useFileTransport' => true, @@ -23,9 +22,10 @@ return [ 'showScriptName' => true, ], 'redis' => [ - 'database' => 1, + 'hostname' => 'testredis', ], 'amqp' => [ + 'host' => 'testrabbit', 'user' => 'ely-accounts-tester', 'password' => 'tester-password', 'vhost' => '/account.ely.by/tests', diff --git a/tests/codeception/console/_bootstrap.php b/tests/codeception/console/_bootstrap.php index 7500628..d906568 100644 --- a/tests/codeception/console/_bootstrap.php +++ b/tests/codeception/console/_bootstrap.php @@ -14,3 +14,4 @@ $_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['SERVER_PORT'] = '80'; Yii::setAlias('@tests', dirname(dirname(__DIR__))); +\Codeception\Specify\Config::setDeepClone(false); diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 100644 index 0000000..3b01b9e --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1,30 @@ +version: '2' +services: + testphp: + build: ./.. + links: + - testdb + - testredis + - testrabbit + volumes: + - ./../:/var/www/html/ + env_file: ./../.env + + testdb: + build: ./../docker/mariadb + environment: + MYSQL_ROOT_PASSWORD: "" + MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_DATABASE: "ely_accounts_test" + MYSQL_USER: "ely_accounts_tester" + MYSQL_PASSWORD: "ely_accounts_tester_password" + + testredis: + image: redis:3.0 + + testrabbit: + build: ./../docker/rabbitmq + environment: + RABBITMQ_DEFAULT_USER: "ely-accounts-tester" + RABBITMQ_DEFAULT_PASS: "tester-password" + RABBITMQ_DEFAULT_VHOST: "/account.ely.by/tests" diff --git a/tests/php.sh b/tests/php.sh new file mode 100755 index 0000000..c16b585 --- /dev/null +++ b/tests/php.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +cd "$(dirname "$0")" + +./../vendor/bin/codecept build + +./../docker/wait-for-it.sh testdb:3306 testrabbit:5672 -- \ +php codeception/bin/yii migrate/up --interactive=0 && ./../vendor/bin/codecept run diff --git a/tests/run-tests.sh b/tests/run-tests.sh new file mode 100755 index 0000000..bc0e9b6 --- /dev/null +++ b/tests/run-tests.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +cd "$(dirname "$0")" + +docker-compose run --rm testphp ./tests/php.sh +docker-compose stop # docker не останавливает зависимые контейнеры после завершения работы главного процесса