ckalita's avatar

No able to run parallel testing: sail test --parallel

I can run artisan test and I can run sail test without a problem. However, sail test --parallel throws Access Violation error:

Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'sail'@'%' to database 'homestead_test_4' (SQL: drop database if exists homestead_test_4)

The app runs in docker container on Mysql 5.7 (I tried mySql 8.0 to the same result).

Any idea what I may be doing wrong or how to fix it?

0 likes
9 replies
ckalita's avatar

These are the steps, from scratch:

  • Docker 4.0.1 in Windows 10 is running
  • Ubuntu 20.04 is in WSL2 mode
  • within ~ run curl -s https://laravel.build/example-app | bash
  • cd example-app
  • sail up -d
  • sail test --parallel is successful (after Running tests in parallel requires "brianium/paratest". Do you wish to install it as a dev dependency? - yes):
Time: 00:00.418, Memory: 20.00 MB
OK (2 tests, 2 assertions)

But then:

  • nano tests\Features\ExampleTest.php to import use RefreshDatabase;
namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic test example.
     *
     * @return void
     */
    public function test_example()
    {
        $response = $this->get('/');

        $response->assertStatus(200);
    }
}

There was 1 error:

  1. Tests\Feature\ExampleTest::test_example Illuminate\Database\QueryException: SQLSTATE[42000]: Syntax error or access violation: 1044 Access denied for user 'sail'@'%' to database 'example_app_test_2' (SQL: drop database if exists example_app_test_2)

What am I missing?

frankielee's avatar

@ckalita the database is created manually? or generated when the sail up -d is used?

Make sure the user 'sail'@'% have been granted the correct privileges

Example

GRANT ALL PRIVILEGES ON  `example_app_test_2`.* TO 'sail'@'%';

ckalita's avatar

@frankielee the ...test_2 database should be created by paratest, as far as I understand:

Laravel automatically handles creating and migrating a test database for each parallel process that is running your tests.

So should be working out of the box, no?

frankielee's avatar

@ckalita Login into the container CLI, try to manually create a database using the account. Maybe the account doesn't have permission to create/drop the new database?

ckalita's avatar
ckalita
OP
Best Answer
Level 2

Maybe I am doing something wrong, but to boil it down: mySQL user that is created as container goes up is only granted access to the DB that is created (well, duh).

So what I ended up doing is add an extra step for testing mysql container, to provide access to all DBs, automating solution @frankielee suggested with

  1. a file in docker/mysql.testing/init/01-database.sql
GRANT ALL PRIVILEGES ON *.* TO 'sail'@'%';

(assumes your DB_USER is .env is sail)

and 2. mapping it to a volume in mysql.testing container in docker-compose.yml:

    mysql.testing:
        tmpfs: '/var/lib/mysql'
        image: 'mysql:5.7'
        ports:
            - '${FORWARD_DB_PORT:-53306}:3306'
        environment:
            MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
            MYSQL_DATABASE: '${DB_DATABASE}'
            MYSQL_USER: '${DB_USERNAME}'
            MYSQL_PASSWORD: '${DB_PASSWORD}'
            MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
        volumes:
            - "./docker/mysql.testing/init:/docker-entrypoint-initdb.d"
        networks:
            - sail
        healthcheck:
          test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"]
          retries: 3
          timeout: 5s

Notice that the the container side of DB port is mapped to 53306 - to avoid conflict with regular mySQL db.

Since no one else seems to be having the problem, I doubt anyone will find this post useful, but just in case, a note of caution: remember that volumes need to be recreated, so sail down -v is needed

Ta-da for now

4 likes
Akecel's avatar

You just saved my day ! What a strange issue...

Please or to participate in this conversation.