Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
OCT-2154: update automated api e2e tests after migration to fastapi (#…
Browse files Browse the repository at this point in the history
…554)

## Description
Adding tests of fastapi routes for allocation and project rewards
adam-gf authored Dec 2, 2024
1 parent 9fa14ce commit 1c895c7
Showing 4 changed files with 86 additions and 10 deletions.
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

@@ -9,6 +10,7 @@
@pytest.mark.api
def test_allocations(
client: Client,
fastapi_client: TestClient,
deployer: UserAccount,
ua_alice: UserAccount,
ua_bob: UserAccount,
@@ -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)
21 changes: 19 additions & 2 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -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
@@ -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
@@ -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."""
@@ -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):
25 changes: 18 additions & 7 deletions backend/v2/core/dependencies.py
Original file line number Diff line number Diff line change
@@ -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:
@@ -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(

0 comments on commit 1c895c7

Please sign in to comment.