Skip to content

Commit

Permalink
Read replica usage in tests - tweaks (#16029)
Browse files Browse the repository at this point in the history
* Refactor DB replica connection test_options

* Setup test databases explicitly

* Refactor FakeDbReplicaConnection and wrapp cursor creation with allow_writer

* Add comment to conftest.py
  • Loading branch information
przlada committed May 22, 2024
1 parent e9db8e0 commit d0ab3ca
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 18 deletions.
11 changes: 9 additions & 2 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@

from saleor.tests.utils import prepare_test_db_connections

django.test.TransactionTestCase.databases = "__all__"
django.test.TestCase.databases = "__all__"
TEST_DATABASES = {
settings.DATABASE_CONNECTION_DEFAULT_NAME,
settings.DATABASE_CONNECTION_REPLICA_NAME,
}
# Here, we trick Django test cases into using multiple databases.
# Thanks to this, we do not have to mark all tests
# with @pytest.mark.django_db(databases=['default', 'replica'])
django.test.TransactionTestCase.databases = TEST_DATABASES
django.test.TestCase.databases = TEST_DATABASES

prepare_test_db_connections()

Expand Down
4 changes: 1 addition & 3 deletions saleor/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,9 @@ def get_url_from_env(name, *, schemes=None) -> Optional[str]:
# and we need to update docs.
# default="postgres://saleor_read_only:saleor@localhost:5432/saleor",
conn_max_age=DB_CONN_MAX_AGE,
test_options={"MIRROR": DATABASE_CONNECTION_DEFAULT_NAME},
),
}
DATABASES[DATABASE_CONNECTION_REPLICA_NAME]["TEST"] = {
"MIRROR": DATABASE_CONNECTION_DEFAULT_NAME
}

DATABASE_ROUTERS = ["saleor.core.db_routers.PrimaryReplicaRouter"]

Expand Down
29 changes: 16 additions & 13 deletions saleor/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,35 @@
from django.conf import settings
from django.db import connections, transaction

from ..core.db.connection import allow_writer

class TestDBConnectionWrapper:
def __init__(self, conn, default_conn):
self._wrapped_conn = conn
self._default_conn = default_conn

class FakeDbReplicaConnection:
def __init__(self, replica_conn):
self.replica_conn = replica_conn
self.writer_conn = connections[settings.DATABASE_CONNECTION_DEFAULT_NAME]

def cursor(self, *args, **kwargs):
cursor = self._default_conn.cursor(*args, **kwargs)
cursor.db = self
with allow_writer():
cursor = self.writer_conn.cursor(*args, **kwargs)
cursor.db = self
return cursor

def chunked_cursor(self, *args, **kwargs):
cursor = self._default_conn.chunked_cursor(*args, **kwargs)
cursor.db = self
with allow_writer():
cursor = self.writer_conn.chunked_cursor(*args, **kwargs)
cursor.db = self
return cursor

def __getattr__(self, attr):
if attr in ["alias", "settings_dict"]:
return getattr(self._wrapped_conn, attr)
return getattr(self._default_conn, attr)
if attr == "alias":
return getattr(self.replica_conn, attr)
return getattr(self.writer_conn, attr)


def prepare_test_db_connections():
replica = settings.DATABASE_CONNECTION_REPLICA_NAME
default_conn = connections[settings.DATABASE_CONNECTION_DEFAULT_NAME]
connections[replica] = TestDBConnectionWrapper(connections[replica], default_conn) # type: ignore
connections[replica] = FakeDbReplicaConnection(connections[replica]) # type: ignore


def flush_post_commit_hooks():
Expand Down

0 comments on commit d0ab3ca

Please sign in to comment.