0

I'm currently building a multi-tenant application using stancl/tenancy (every tenant uses their own database) in my Laravel application.

Whenever I'm writing tests, tests fail a lot due to the error

Illuminate\Database\QueryException: SQLSTATE[55006]: Object in use: 7 FEHLER:  auf Datenbank »tenant_019949ce« wird von anderen Benutzern zugegriffen
DETAIL:  1 andere Sitzung verwendet die Datenbank. (Connection: tenant_host_connection, SQL: DROP DATABASE "tenant_019949ce")

which means the table is used by another user. Tables are created when a tenant is created and should be deleted if a tenant gets deleted but it always fails in tearDown method.

My tests extend TenancyTestCase class:

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

class TenancyTestCase extends BaseTestCase {

    use RefreshDatabase;

    private Tenant $tenant;

    protected function setUp(): void {
        parent::setUp();

        Config::set('tenancy.seeder_parameters.--class', TestDatabaseSeeder::class);

        $this->setupDefaultTenant();
        $this->forceRootUrl();

        $this->withoutVite();
    }

    private function setupDefaultTenant(): void {

        $this->tenant = Tenant::factory()->create();
        $this->tenant->domains()->save(Domain::factory([
            'domain' => 'tenant',
        ])->make());

        tenancy()->initialize($this->tenant);
    }

    private function forceRootUrl(): void {
        $parsed = parse_url(config('app.url'));
        $host = $parsed['host'] ?? 'localhost.test';
        $port = isset($parsed['port']) ? ':' . $parsed['port'] : '';

        URL::forceRootUrl('https://tenant.' . $host . $port);
    }

    public function tearDown(): void {
        tenancy()->end();
        $this->tenant->delete();

        parent::tearDown();
    }
}

I couldn't figure out why yet, any ideas on how to fix this?

My goal is to create a single database for each test and delete them if test is completed.

Thank you.


EDIT: If I comment Jobs\DeleteDatabase::class out, it works fine but the database will still persist which is not what I want. But tests are successful. So how to delete database correctly?

Events\TenantDeleted::class => [
    JobPipeline::make([
        Jobs\DeleteDatabase::class,
    ])->send(function(Events\TenantDeleted $event) {
        return $event->tenant;
    })->shouldBeQueued(true),
],

I also found out that every tenants database that is created DURING the test itself (not in setUp) get's handled and deleted correctly. But not the original one.

2
  • Can you confirm which database driver you’re using? The error message looks like PostgreSQL-specific behavior — in Postgres, a database can’t be dropped while any connection is still active. and also Are you sure the tenant connection is being closed before you call $this->tenant->delete()? It looks like tearDown() is trying to drop the tenant DB while PHPUnit (or Laravel’s connection pool) still has an open connection. Commented Sep 16 at 6:25
  • @S.Narthanan Yes, it's PostgreSQL 17.6.1. I can't explain why the connection is still available even if the test was completed. Commented Sep 17 at 18:19

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.