Home > Software engineering >  Bug symfony docker and phpunit
Bug symfony docker and phpunit

Time:06-23

I have a problem for a week, my tests can not connect with the database. Indeed I have passed my environment under docker, my database connects perfectly but not the tests. Do you know why? My errors :

[critical] Uncaught PHP Exception Doctrine\DBAL\Exception\ConnectionException: "An exception occurred in the driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for database failed: Name or service not known" at /opt/project/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php line 103

Here are my files:

docker-compose.yml

version: '3.7'
services:
    database:
        image: 'mysql:5.7'
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_DATABASE: app
        ports:
            - '3306:3306'
        volumes:
            - db-data:/var/lib/mysql/data:rw

    app:
        image: peedro07/app:latest
        ports:
          - "8080:80"
        environment:
          DATABASE_URL: mysql://root:root@database:3306/app

volumes:
    db-data:

My Dockerfile which is build with the docker build command . -f chemin/Dockerfile -t peedro07/app

FROM php:8.1-apache

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN chmod  x /usr/local/bin/install-php-extensions && \
    install-php-extensions pdo_mysql intl

RUN curl -sSk https://getcomposer.org/installer | php -- --disable-tls && \
   mv composer.phar /usr/local/bin/composer


COPY . /var/www/

COPY ./docker/php/apache.conf /etc/apache2/sites-available/000-default.conf

RUN cd /var/www && \
    composer install

WORKDIR /var/www/

#ENTRYPOINT ["bash", "./docker/docker.sh"]

EXPOSE 80

My phpunit.xml.dist

<?xml version="1.0" encoding="UTF-8"?>

<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
         backupGlobals="false"
         colors="true"
         bootstrap="tests/bootstrap.php"
         convertDeprecationsToExceptions="false"
>
    <php>
        <env name="SYMFONY_DEPRECATIONS_HELPER" value="weak"/>
        <ini name="display_errors" value="1"/>
        <ini name="error_reporting" value="-1"/>
        <server name="APP_ENV" value="test" force="true"/>
        <server name="SHELL_VERBOSITY" value="-1"/>
        <server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
        <server name="SYMFONY_PHPUNIT_VERSION" value="9.5"/>
    </php>

    <testsuites>
        <testsuite name="Project Test Suite">
            <directory>tests</directory>
        </testsuite>
    </testsuites>

    <coverage processUncoveredFiles="true">
        <include>
            <directory suffix=".php">src</directory>
        </include>
    </coverage>

    <listeners>
        <listener />
    </listeners>

    <!-- Run `composer require symfony/panther` before enabling this extension -->
    <!--
    <extensions>
        <extension  />
    </extensions>
    -->

    <extensions>
        <extension />
    </extensions>
</phpunit>

In my .env :

DATABASE_URL="mysql://root:root@database:3306/app"

In my env.test

KERNEL_CLASS='App\Kernel'
APP_SECRET='$ecretf0rt3st'
SYMFONY_DEPRECATIONS_HELPER=999999
PANTHER_APP_ENV=panther
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
DATABASE_URL="mysql://root:root@database:3306/app"

CodePudding user response:

Symfony is usually adding a suffix to the database name in the test environment.

You can verify that with the php bin/console debug:config doctrine --env=test command and look for the doctrine.dbal.connections.dbname_suffix config.

Or you can look in one of these files depending on which version of Symfony you are using.

Older: config/packages/test/doctrine.yaml

doctrine:
    dbal:
        # "TEST_TOKEN" is typically set by ParaTest
        dbname: 'main_test%env(default::TEST_TOKEN)%'

Newer: config/packages/doctrine.yaml

when@test:
    doctrine:
        dbal:
            # "TEST_TOKEN" is typically set by ParaTest
            dbname_suffix: '_test%env(default::TEST_TOKEN)%'

This config is useful to make sure you are not testing on "real data" aka corrupting the prod database.

And the token might be useful should you have parallel testing.

What I would usually do is:

  1. Create the tests database with php bin/console doctrine:database:create --env=test
  2. Make sure my tests load fixtures to have a predictable dataset between each test
  3. Run my tests

CodePudding user response:

Thank you for your response. It was simply a docker problem. I had to add a volume to my service app. I then killed my containers, and restarted docker. After reading several documentations, I also noticed that the mysql 5.7 image had some configuration problems, so I switched to the mariadb image which works perfectly with mysql (even if I find this behavior a bit weird ...) Thanks to all :) My new docker-compose.yml :

database:
        image: 'mariadb'
        environment:
            MYSQL_ROOT_PASSWORD: root
            MYSQL_DATABASE: app
        command: ["mysqld", "--ignore-db-dir=lost found", "--explicit_defaults_for_timestamp"]
        restart: always
        ports:
            - '3306:3306'
        volumes:
            - db-data:/var/lib/mysql/data:rw

    app:
        image: peedro07/app:latest
        restart: always
        ports:
          - "8080:80"
        environment:
            DATABASE_URL: mysql://root:root@database:3306/app
        volumes:
            - app-data:/var/www
  • Related