Skip to content

Commit

Permalink
tools: Fix broken integration tests and run them on merges to main (#791
Browse files Browse the repository at this point in the history
)

Fix broken integration tests and run them on merges to main
  • Loading branch information
malexw authored Oct 3, 2024
1 parent 5ffff04 commit b2099b7
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 7 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/backend_integration_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Backend integration tests

on:
push:
branches: [main]
merge_group: {}

jobs:
pytest:
permissions: write-all
environment: development
runs-on: ubuntu-latest

steps:
- name: Checkout repo
uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
virtualenvs-path: .venv
installer-parallel: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --with dev --no-interaction --no-root
- name: Setup test DB container
run: make test-db
- name: Test with pytest
if: github.actor != 'dependabot[bot]'
run: |
make run-integration-tests
env:
PYTHONPATH: src
- name: Upload coverage reports to Codecov
uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage.xml
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ run-community-tests:

.PHONY: run-integration-tests
run-integration-tests:
docker compose run --build backend poetry run pytest src/backend/tests/integration/$(file)
docker compose run --build backend poetry run pytest -c src/backend/pytest_integration.ini src/backend/tests/integration/$(file)

run-tests: run-unit-tests

Expand Down
3 changes: 3 additions & 0 deletions src/backend/pytest_integration.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[pytest]
env =
DATABASE_URL=postgresql://postgres:postgres@db:5432/postgres
11 changes: 11 additions & 0 deletions src/backend/services/request_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
from backend.model_deployments.utils import class_name_validator
from backend.services.agent import validate_agent_exists
from backend.services.auth.utils import get_header_user_id
from backend.services.logger.utils import LoggerFactory

logger = LoggerFactory().get_logger()


def validate_deployment_model(deployment: str, model: str, session: DBSessionDep):
Expand Down Expand Up @@ -92,12 +95,14 @@ def validate_user_header(session: DBSessionDep, request: Request):

user_id = get_header_user_id(request)
if not user_id:
logger.error(event="User-Id required in request headers.")
raise HTTPException(
status_code=401, detail="User-Id required in request headers."
)

user = user_crud.get_user(session, user_id)
if not user:
logger.error(event="User not found.", user_id=user_id)
raise HTTPException(status_code=401, detail="User not found.")


Expand Down Expand Up @@ -291,15 +296,18 @@ async def validate_update_agent_request(session: DBSessionDep, request: Request)
user_id = get_header_user_id(request)
agent_id = request.path_params.get("agent_id")
if not agent_id:
logger.error(event="Agent ID is required.")
raise HTTPException(status_code=400, detail="Agent ID is required.")

agent = agent_crud.get_agent_by_id(session, agent_id, user_id)
if not agent:
logger.error(event="Agent not found", agent_id=agent_id)
raise HTTPException(
status_code=404, detail=f"Agent with ID {agent_id} not found."
)

if agent.user_id != user_id:
logger.error(event="Agent does not belong to user.", agent_user_id=agent.user_id, user_id=user_id)
raise HTTPException(
status_code=401, detail=f"Agent with ID {agent_id} does not belong to user."
)
Expand All @@ -310,16 +318,19 @@ async def validate_update_agent_request(session: DBSessionDep, request: Request)
if tools:
for tool in tools:
if tool not in AVAILABLE_TOOLS:
logger.error(event="Tool not found.", tool=tool)
raise HTTPException(status_code=404, detail=f"Tool {tool} not found.")

model, deployment = body.get("model"), body.get("deployment")
# Model and deployment must be updated together to ensure compatibility
if not model and deployment:
logger.error(event="If updating an agent's deployment type, the model must also be provided.")
raise HTTPException(
status_code=400,
detail="If updating an agent's deployment type, the model must also be provided.",
)
elif model and not deployment:
logger.error(event="If updating an agent's model, the deployment must also be provided.")
raise HTTPException(
status_code=400,
detail="If updating an agent's model, the deployment must also be provided.",
Expand Down
Empty file.
Empty file.
5 changes: 2 additions & 3 deletions src/backend/tests/integration/routers/test_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,15 @@ def test_create_agent_missing_non_required_fields(
assert agent.temperature == 0.3
assert agent.model == request_json["model"]


def test_update_agent(session_client: TestClient, session: Session, user) -> None:
agent = get_factory("Agent", session).create(
name="test agent",
version=1,
description="test description",
preamble="test preamble",
temperature=0.5,
model="command-r-plus",
deployment=ModelDeploymentName.CoherePlatform,
user_id=user.id,
user=user,
)

request_json = {
Expand Down
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from fastapi import HTTPException, Request
from sqlalchemy.orm import Session

from backend.database_models.user import User
from backend.services.auth.request_validators import validate_authorization


Expand All @@ -12,13 +13,20 @@ def test_validate_authorization_with_valid_request():
request.headers.get.return_value = "Bearer fake_token"
session = Mock(spec=Session)
session.query.return_value.filter.return_value.first.return_value = None
mock_user = Mock(spec=User)
mock_user.id = "user-name"
mock_user.active = True

with patch(
"backend.services.auth.jwt.JWTService.decode_jwt",
return_value={"context": "test_context", "jti": "test_jti"},
return_value={"context": {"id": "user-name"}, "jti": "test_jti"},
):
result = validate_authorization(request, session=session)
assert isinstance(result, dict)
with patch(
"backend.crud.user.get_user",
return_value=mock_user,
):
result = validate_authorization(request, session=session)
assert isinstance(result, dict)


def test_validate_authorization_no_auth_header():
Expand Down
1 change: 1 addition & 0 deletions src/backend/tools/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def delete_tool_auth(self, session: DBSessionDep, user_id: str) -> bool:
)
raise


class ToolAuthException(Exception):
def __init__(self, message, tool_id: str):
self.message = message
Expand Down

0 comments on commit b2099b7

Please sign in to comment.