pytest-django icon indicating copy to clipboard operation
pytest-django copied to clipboard

DB fails to clean up after tests, says db is used by another user

Open ibolit opened this issue 6 years ago • 1 comments
trafficstars

This is basically a repost of my question from stackoverflow. I hope it will be more useful here.

I have a Django application, and I'm trying to test it using pytest and pytest-django. However, quite often, when the tests finish running, I get the error that the database failed to be deleted: DETAIL: There is 1 other session using the database.

Basically, the minimum test code that I could narrow it down to is:

@pytest.fixture
def make_bundle():
    a = MyUser.objects.create(key_id=uuid.uuid4())
    return a

class TestThings:
    def test_it(self, make_bundle):
        all_users = list(MyUser.objects.all())
        assert_that(all_users, has_length(1))

Every now and again the tests will fail with the above error. Is there something I am doing wrong? Or how can I fix this?

The database that I am using is PostgreSQL 9.6.

And here is the dirty fix I seem to have found for this:

def _destroy_test_db(self, test_database_name, verbosity):
    """
    Internal implementation - remove the test db tables.
    """
    # Remove the test database to clean up after
    # ourselves. Connect to the previous database (not the test database)
    # to do so, because it's not allowed to delete a database while being
    # connected to it.
    with self.connection._nodb_connection.cursor() as cursor:
        cursor.execute(
            "SELECT pg_terminate_backend(pg_stat_activity.pid) "
            "FROM pg_stat_activity "
            "WHERE pg_stat_activity.datname = '{}' "
                "AND pid <> pg_backend_pid();".format(test_database_name)
        )

        cursor.execute("DROP DATABASE %s"
                       % self.connection.ops.quote_name(test_database_name))


@pytest.fixture(autouse=True)
def patch_db_cleanup():
    creation.BaseDatabaseCreation._destroy_test_db = _destroy_test_db

Is there a better solution for the situation? Or is it a bug in pytest-django?

ibolit avatar Jan 28 '19 08:01 ibolit

i got the same error, after keyword interupt, i solve it by restart the PC and print "yes" when pytest ask again about deleting old test database

McDinii avatar Mar 27 '24 15:03 McDinii