Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCT-2154: update automated api e2e tests after migration to fastapi #554

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions backend/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 24 additions & 1 deletion backend/tests/api-e2e/test_api_allocations.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from fastapi.testclient import TestClient
import pytest
from flask import current_app as app

Expand All @@ -9,6 +10,7 @@
@pytest.mark.api
def test_allocations(
client: Client,
fastapi_client: TestClient,
deployer: UserAccount,
ua_alice: UserAccount,
ua_bob: UserAccount,
Expand All @@ -31,7 +33,28 @@ def test_allocations(
res = client.pending_snapshot()
assert res["epoch"] > 0

ua_alice.allocate(1000, alice_proposals)
ua_alice_nonce, _ = ua_alice._client.get_allocation_nonce(ua_alice.address)
signature = ua_alice._client.sign_operation(
ua_alice._account, 1000, alice_proposals, ua_alice_nonce
)
rv = fastapi_client.post(
"/allocations/allocate",
json={
"payload": {
"allocations": [
{"proposalAddress": address, "amount": 1000}
for address in alice_proposals
],
"nonce": ua_alice_nonce,
},
"userAddress": ua_alice.address,
"signature": signature,
"isManuallyEdited": False,
},
)
assert rv.status_code == 201

# ua_alice.allocate(1000, alice_proposals)
ua_bob.allocate(1000, alice_proposals[:1])

allocations, _ = client.get_epoch_allocations(STARTING_EPOCH)
Expand Down
21 changes: 19 additions & 2 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from http import HTTPStatus
from unittest.mock import MagicMock, Mock

from fastapi.testclient import TestClient
import gql
import pytest
from flask import current_app
Expand All @@ -19,6 +20,7 @@
from web3 import Web3

import logging
from v2.main import app as fastapi_app
from app import create_app
from app.engine.user.effective_deposit import DepositEvent, EventType, UserDeposit
from app.exceptions import ExternalApiException
Expand Down Expand Up @@ -416,6 +418,21 @@ def random_string() -> str:
return "".join(random.choices(characters, k=length_of_string))


@pytest.fixture
def fastapi_client(deployment) -> TestClient:
# take SQLALCHEMY_DATABASE_URI and use as DB_URI
os.environ["DB_URI"] = deployment.SQLALCHEMY_DATABASE_URI
os.environ["PROPOSALS_CONTRACT_ADDRESS"] = deployment.PROJECTS_CONTRACT_ADDRESS

for key in dir(deployment):
if key.isupper():
value = getattr(deployment, key)
if value is not None:
os.environ[key] = str(value)

return TestClient(fastapi_app)


@pytest.fixture
def flask_client(deployment) -> FlaskClient:
"""An application for the integration / API tests."""
Expand Down Expand Up @@ -656,12 +673,12 @@ def get_rewards_budget(self, address: str, epoch: int):

def get_user_rewards_in_upcoming_epoch(self, address: str):
rv = self._flask_client.get(f"/rewards/budget/{address}/upcoming")
current_app.logger.debug("get_user_rewards_in_upcoming_epoch :", rv.text)
current_app.logger.debug(f"get_user_rewards_in_upcoming_epoch :{rv.text}")
return json.loads(rv.text)

def get_user_rewards_in_epoch(self, address: str, epoch: int):
rv = self._flask_client.get(f"/rewards/budget/{address}/epoch/{epoch}")
current_app.logger.debug("get_rewards_budget :", rv.text)
current_app.logger.debug(f"get_rewards_budget :{rv.text}")
return json.loads(rv.text)

def get_total_users_rewards_in_epoch(self, epoch):
Expand Down
25 changes: 18 additions & 7 deletions backend/v2/core/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ class DatabaseSettings(OctantSettings):

@property
def sqlalchemy_database_uri(self) -> str:
return self.db_uri.replace("postgresql://", "postgresql+asyncpg://")
if "postgresql://" in self.db_uri:
return self.db_uri.replace("postgresql://", "postgresql+asyncpg://")

if "sqlite://" in self.db_uri:
return self.db_uri.replace("sqlite://", "sqlite+aiosqlite://")

raise ValueError("Unsupported database URI")


def get_database_settings() -> DatabaseSettings:
Expand All @@ -51,16 +57,21 @@ def get_database_settings() -> DatabaseSettings:
def get_sessionmaker(
settings: Annotated[DatabaseSettings, Depends(get_database_settings)]
) -> async_sessionmaker[AsyncSession]:
kw = {}
if "postgresql" in settings.sqlalchemy_database_uri:
kw = {
"pool_size": 100, # Initial pool size (default is 5)
"max_overflow": 10, # Extra connections if pool is exhausted
"pool_timeout": 30, # Timeout before giving up on a connection
"pool_recycle": 3600, # Recycle connections after 1 hour (for long-lived connections)
"pool_pre_ping": True, # Check if the connection is alive before using it
}

engine = create_async_engine(
settings.sqlalchemy_database_uri,
echo=False, # Disable SQL query logging (for performance)
pool_size=100, # Initial pool size (default is 5)
max_overflow=10, # Extra connections if pool is exhausted
pool_timeout=30, # Timeout before giving up on a connection
pool_recycle=3600, # Recycle connections after 1 hour (for long-lived connections)
pool_pre_ping=True, # Check if the connection is alive before using it
future=True, # Use the future-facing SQLAlchemy 2.0 style
# connect_args={"options": "-c timezone=utc"} # Ensures timezone is UTC
**kw,
)

sessionmaker = async_sessionmaker(
Expand Down