Skip to content

Commit

Permalink
Merge pull request #256 from raizo07/integration-test
Browse files Browse the repository at this point in the history
feat: github pipeline for running integration test
  • Loading branch information
djeck1432 authored Nov 26, 2024
2 parents c6bbe47 + 51f2718 commit 1da7014
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 6 deletions.
105 changes: 105 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Integration Tests

on:
push:
branches:
- main
pull_request:
branches:
- main

env:
DB_PORT: 5432
DB_NAME: spotnet
DB_USER: postgres
DB_PASSWORD: password
DB_HOST: db
STARKNET_NODE_URL: http://178.32.172.148:6060
REDIS_HOST: redis
REDIS_PORT: 6379
ENV_VERSION: DEV

jobs:
integration-tests:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Create .env file
run: |
cat << EOF > .env.dev
ENV_VERSION=DEV
STARKNET_NODE_URL=${{ env.STARKNET_NODE_URL }}
DB_USER=${{ env.DB_USER }}
DB_PASSWORD=${{ env.DB_PASSWORD }}
DB_NAME=${{ env.DB_NAME }}
DB_HOST=${{ env.DB_HOST }}
DB_PORT=${{ env.DB_PORT }}
REDIS_HOST=${{ env.REDIS_HOST }}
REDIS_PORT=${{ env.REDIS_PORT }}
EOF
- name: Build and Start Containers
run: |
docker compose -f docker-compose.dev.yaml up -d --build
echo "Waiting for containers to be ready..."
sleep 30
- name: Install Test Dependencies in Container
run: |
docker exec backend_dev pip install pytest pytest-cov
docker exec backend_dev pip freeze # Debug: show installed packages
- name: Wait for Backend Service
timeout-minutes: 5
run: |
while ! curl -s http://localhost:8000/health > /dev/null; do
echo "Waiting for backend service..."
sleep 10
# Check if the container is still running before logging
if ! docker ps | grep -q backend_dev; then
echo "Backend container is not running!"
docker compose -f docker-compose.dev.yaml logs backend_dev || true
exit 1
fi
# Log the backend service status for debugging purposes.
docker compose -f docker-compose.dev.yaml logs backend_dev || true
done
- name: Apply Migrations
run: |
docker exec backend_dev alembic -c web_app/alembic.ini upgrade head || {
echo "Migration failed. Showing backend logs:"
docker compose -f docker-compose.dev.yaml logs backend_dev || true
exit 1
}
- name: Run Integration Tests with Coverage
run: |
docker exec backend_dev bash -c "cd /app && python -m pytest web_app/test_integration/ -v"
- name: Clean Up
if: always()
run: |
docker compose -f docker-compose.dev.yaml logs > docker-logs.txt || true
docker compose -f docker-compose.dev.yaml down -v
- name: Upload Docker Logs on Failure
if: failure()
uses: actions/upload-artifact@v3
with:
name: docker-logs
path: docker-logs.txt
16 changes: 11 additions & 5 deletions docker-compose.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ services:
- app_network
depends_on:
- db
environment:
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=spotnet
- DB_USER=postgres
- DB_PASSWORD=password

db:
image: postgres:14
Expand All @@ -31,11 +37,11 @@ services:
POSTGRES_PASSWORD: password
volumes:
- postgres_data_dev:/var/lib/postgresql/data
- ./init-db:/docker-entrypoint-initdb.d # Automatically run initialization scripts
- ./init-db:/docker-entrypoint-initdb.d
networks:
- app_network
ports:
- "5432:5432"
- "${DB_PORT:-5432}:5432" # Use environment variable for port mapping
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
interval: 10s
Expand All @@ -48,13 +54,13 @@ services:
dockerfile: Dockerfile.dev
container_name: frontend_dev
volumes:
- ./frontend:/app # For live code updates during development
- ./frontend:/app
ports:
- "3000:80" # Serve the frontend on localhost:3000
- "3000:80"
networks:
- app_network
depends_on:
- backend

volumes:
postgres_data_dev:
postgres_data_dev:
Empty file added integration_tests/__init__.py
Empty file.
110 changes: 110 additions & 0 deletions integration_tests/test_position_creation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
Module: Position Creation Tests
This module contains integration tests for the creation and management
of user positions within the webapp
Key Components:
- **PositionDBConnector**: Manages database operations for positions.
- **DepositMixin**: Processes transaction data.
- **DashboardMixin**: Retrieves current token prices.
Test Class:
- **PositionCreationTest**: Validates position workflows:
1. Fetching transaction data.
2. Creating and verifying positions.
3. Updating position statuses.
"""
import asyncio
import pytest
from typing import Dict, Any
from datetime import datetime
from web_app.db.crud import PositionDBConnector, AirDropDBConnector
from web_app.contract_tools.mixins.dashboard import DashboardMixin
from web_app.db.models import Status

position_db = PositionDBConnector()
airdrop = AirDropDBConnector()


class TestPositionCreation:
"""
Integration test for creating and managing positions.
Steps:
1. Fetch transaction data using `DepositMixin.get_transaction_data`.
2. Create a position using `PositionDBConnector`.
3. Verify the created position's attributes.
4. Fetch current token prices using `DashboardMixin`.
5. Update position status and validate changes.
"""

form_data_1: Dict[str, Any] = {
"wallet_id": "0x011F0c180b9EbB2B3F9601c41d65AcA110E48aec0292c778f41Ae286C78Cc374",
"token_symbol": "STRK",
"amount": "2",
"multiplier": 1,
"borrowing_token": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
}

form_data_2: Dict[str, Any] = {
"wallet_id": "0x011F0c180b9EbB2B3F9601c41d65AcA110E48aec0292c778f41Ae286C78Cc374",
"token_symbol": "ETH",
"amount": "5",
"multiplier": 1,
"borrowing_token": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
}

form_data_3: Dict[str, Any] = {
"wallet_id": "0x011F0c180b9EbB2B3F9601c41d65AcA110E48aec0292c778f41Ae286C78Cc374",
"token_symbol": "USDC",
"amount": "1",
"multiplier": 1,
"borrowing_token": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
}

@pytest.mark.parametrize("form_data", [form_data_1, form_data_2, form_data_3])
def test_create_position(self, form_data: Dict[str, Any]) -> None:
"""
Args:
form_data (Dict[str, Any]): Position data.
Returns:
None
"""
wallet_id = form_data["wallet_id"]
token_symbol = form_data["token_symbol"]
amount = form_data["amount"]
multiplier = form_data["multiplier"]
borrowing_token = form_data["borrowing_token"]

existing_user = position_db.get_user_by_wallet_id(wallet_id)
if not existing_user:
position_db.create_user(wallet_id)

position = position_db.create_position(
wallet_id=wallet_id,
token_symbol=token_symbol,
amount=amount,
multiplier=multiplier,
)
assert (
position.status == Status.PENDING
), "Position status should be 'pending' upon creation"

current_prices = asyncio.run(DashboardMixin.get_current_prices())
assert (
position.token_symbol in current_prices
), "Token price missing in current prices"
position.start_price = current_prices[position.token_symbol]
position.created_at = datetime.utcnow()

print(
f"Position {position.id} created successfully with status '{position.status}'."
)

position_status = position_db.open_position(position.id, current_prices)
assert (
position_status == Status.OPENED
), "Position status should be 'opened' after updating"
print(f"Position {position.id} successfully opened.")

user = position_db.get_user_by_wallet_id(wallet_id)
airdrop.delete_all_users_airdrop(user.id)
position_db.delete_all_user_positions(user.id)
position_db.delete_user_by_wallet_id(wallet_id)
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ isort = "5.13.2"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
asyncio_mode = "strict"
asyncio_default_fixture_loop_scope = "function"

0 comments on commit 1da7014

Please sign in to comment.