-
Notifications
You must be signed in to change notification settings - Fork 39
Adding integration tests #351
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
Conversation
- Created .gitignore to exclude unnecessary files and directories from version control. - Added .python-version to specify the Python version for the integration tests. - Introduced pyproject.toml for project metadata and dependency management, including required packages for development. - Configured pytest with pytest.ini to define test discovery patterns. - Implemented a basic test case in test_basic.py to validate the testing framework setup. - Generated uv.lock to lock dependencies for consistent environments.
- Added build-system section to specify setuptools and wheel as requirements for building the project, ensuring compatibility and proper packaging.
- Introduced a build-system section specifying setuptools and wheel as requirements for building the project, ensuring proper packaging and compatibility.
- Added new dependencies `exospherehost` and `state-manager` to the `pyproject.toml` for improved integration testing. - Configured dependency groups and specified paths for local development. - Updated `uv.lock` to include new package versions and their metadata, ensuring consistent environments and access to the latest features.
- Introduced UvicornTestServer class for running a uvicorn server in a background thread, allowing for real HTTP endpoint testing without blocking. - Added pytest fixture `running_server` for session-scoped server management, ensuring isolation between tests. - Created README.md with detailed instructions on integration testing approaches and usage examples. - Removed outdated test_basic.py file and added test_health.py to validate the health endpoint using the new server setup.
- Created a new GitHub Actions workflow for running integration tests, triggered on pushes to the main branch. - Configured MongoDB service for test environment setup, including health checks and initialization parameters. - Set up Python environment and installed development dependencies using Uvicorn. - Implemented steps to run integration tests with pytest, ensuring proper environment variable configuration for database access and API keys. - Removed release trigger from the publish-state-manager workflow to streamline the process.
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Caution Review failedThe pull request is closed. 📝 WalkthroughSummary by CodeRabbit
WalkthroughAdds a GitHub Actions integration-tests workflow with a MongoDB service, creates an integration-tests Python project (pytest, aiohttp), introduces a UvicornTestServer and session fixture to run the FastAPI app in a background thread, adds a /health integration test, and updates build-system entries and a publish workflow trigger. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Pytest as pytest
participant Fixture as running_server (fixture)
participant UTS as UvicornTestServer
participant Uvicorn as uvicorn.Server
participant App as FastAPI app
Pytest->>Fixture: request session fixture
Fixture->>UTS: create(app) and start()
UTS->>Uvicorn: serve() in background thread
Uvicorn-->>UTS: server running
UTS->>UTS: wait until socket reachable
Pytest->>App: HTTP GET /health
App-->>Pytest: 200 {"message":"OK"}
Pytest-->>Fixture: session teardown
Fixture->>UTS: stop() -> signal exit, join thread
sequenceDiagram
autonumber
actor GH as GitHub Actions
participant Job as job: test (ubuntu-latest)
participant Svc as Service: MongoDB (mongo:7)
participant Steps as Steps
GH->>Job: on push to main (paths)
Job->>Svc: start mongo:7 (port 27017) + healthcheck
Job->>Steps: checkout, setup Python 3.12, setup uv
Steps->>Steps: uv sync --group dev (integration-tests)
Steps->>Steps: uv run pytest (env: MONGO_URI, DB name, secrets)
Steps-->>GH: test results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @NiveditJain, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request establishes a dedicated and robust framework for integration testing of Uvicorn applications. It solves the common problem of uvicorn.run() blocking test execution by introducing a custom test server class that allows for proper lifecycle management of Uvicorn instances within tests. This enables reliable and isolated testing against real HTTP endpoints, significantly improving the quality and maintainability of the test suite.
Highlights
- New Integration Test Framework: Introduced a new
integration-testsdirectory to house robust integration tests for Uvicorn-based applications, addressing the limitations ofuvicorn.run(). - UvicornTestServer Class: Implemented a
UvicornTestServerclass inconftest.pythat provides a non-blocking, thread-based mechanism to start, manage, and gracefully stop Uvicorn servers for testing purposes, including automatic port detection and health checking. - Pytest Integration and Examples: Provided comprehensive examples in
README.mdandtest_health.pydemonstrating how to use theUvicornTestServerwith Pytest fixtures (session-scoped and function-scoped) and manual server management for various testing scenarios. - Build System Configuration Updates: Updated
pyproject.tomlfiles inpython-sdkandstate-managerto explicitly include the[build-system]section, ensuring proper build configuration.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a robust framework for integration testing by adding a UvicornTestServer class to run the FastAPI application in a background thread. This allows tests to make real HTTP requests to the server. The changes include the server helper, a session-scoped pytest fixture, an example test for the /health endpoint, and all necessary configuration files. My review identifies a critical issue that makes the tests unrunnable, and also focuses on improving the accuracy of the documentation and fixture descriptions to ensure clarity and prevent misuse, as well as tidying up project metadata.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 19
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
state-manager/pyproject.toml (2)
11-21: Move testing-only dependency out of runtime.
pytest-covshould not be a runtime dependency; place it under the dev group.dependencies = [ "beanie>=2.0.0", - "cryptography>=45.0.5", + "cryptography>=45.0.5", "fastapi>=0.116.1", "httpx>=0.28.1", "json-schema-to-pydantic>=0.4.1", - "pytest-cov>=6.2.1", "python-dotenv>=1.1.1", "structlog>=25.4.0", "uvicorn>=0.35.0", ] @@ dev = [ "ruff>=0.12.5", "pytest>=8.0.0", "pytest-asyncio>=0.24.0", + "pytest-cov>=6.2.1", "asgi-lifespan>=2.1.0", ]
10-10: Align minimum Python version to 3.13 across CI and pyproject.
Update CI workflows in.github/workflows/{test-state-manager.yml,release-state-manager.yml}to usepython-version: '3.13'then bump
- requires-python = ">=3.12" + requires-python = ">=3.13"in
state-manager/pyproject.toml.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
integration-tests/uv.lockis excluded by!**/*.lock
📒 Files selected for processing (11)
.github/workflows/integration-tests.yml(1 hunks).github/workflows/publish-state-mangaer.yml(0 hunks)integration-tests/.gitignore(1 hunks)integration-tests/.python-version(1 hunks)integration-tests/README.md(1 hunks)integration-tests/conftest.py(1 hunks)integration-tests/pyproject.toml(1 hunks)integration-tests/pytest.ini(1 hunks)integration-tests/test_health.py(1 hunks)python-sdk/pyproject.toml(1 hunks)state-manager/pyproject.toml(1 hunks)
💤 Files with no reviewable changes (1)
- .github/workflows/publish-state-mangaer.yml
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-02T12:43:35.075Z
Learnt from: NiveditJain
PR: exospherehost/exospherehost#130
File: .github/workflows/ci.yml:22-22
Timestamp: 2025-08-02T12:43:35.075Z
Learning: The exospherehost project requires Python versions > 3.12 for the CI workflow, meaning Python 3.13 or higher should be used despite potential stability concerns with pre-release versions.
Applied to files:
python-sdk/pyproject.toml
🧬 Code graph analysis (1)
integration-tests/test_health.py (1)
integration-tests/conftest.py (2)
running_server(99-107)base_url(93-95)
🪛 Gitleaks (8.27.2)
.github/workflows/integration-tests.yml
56-56: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 Checkov (3.2.334)
.github/workflows/integration-tests.yml
[MEDIUM] 52-53: Basic Auth Credentials
(CKV_SECRET_4)
[LOW] 56-57: Base64 High Entropy String
(CKV_SECRET_6)
🪛 YAMLlint (1.37.1)
.github/workflows/integration-tests.yml
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 7-7: wrong indentation: expected 12 but found 10
(indentation)
[error] 17-17: wrong indentation: expected 16 but found 14
(indentation)
[error] 19-19: wrong indentation: expected 18 but found 16
(indentation)
[error] 26-26: wrong indentation: expected 18 but found 16
(indentation)
[error] 31-31: wrong indentation: expected 12 but found 8
(indentation)
[error] 37-37: wrong indentation: expected 14 but found 12
(indentation)
[error] 42-42: wrong indentation: expected 14 but found 12
(indentation)
[error] 52-52: wrong indentation: expected 14 but found 12
(indentation)
[error] 58-58: no new line character at the end of file
(new-line-at-end-of-file)
🪛 LanguageTool
integration-tests/README.md
[grammar] ~1-~1: Use correct spacing
Context: ... Integration Testing with Uvicorn Server This directory contains examples of how ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: ...endpoints that you can send requests to. ## 🚨 The Problem with uvicorn.run() The...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: There might be a mistake here.
Context: ...nd requests to. ## 🚨 The Problem with uvicorn.run() The original code had this issue: ```py...
(QB_NEW_EN)
[grammar] ~7-~7: Use correct spacing
Context: ...un() The original code had this issue: ```python @pytest.mark.asyncio async def test_basic(): uvicorn.run(app, host="127.0.0.1", port=8000) # ❌ This blocks forever! async with ClientSession() as session: # ❌ This never executes # ... test code that never runs ``` **Problem**:uvicorn.run()` is a blocking...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~17-~17: Use correct spacing
Context: ... your test code after it never executes. ## ✅ Proper Solutions ### 1. UvicornTestSe...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~19-~19: Use correct spacing
Context: ...t never executes. ## ✅ Proper Solutions ### 1. UvicornTestServer Class (Recommended)...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~21-~21: Use correct spacing
Context: ...1. UvicornTestServer Class (Recommended) The UvicornTestServer class in `test_b...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: Use correct spacing
Context: ...n way to start and stop uvicorn servers: python from test_basic import UvicornTestServer # Create and start server server = UvicornTestServer(app, host="127.0.0.1", port=8000) server.start() # Make HTTP requests async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: assert response.status == 200 # Stop server server.stop() Features: - ✅ Automatic port detection...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~41-~41: There might be a mistake here.
Context: ...op server server.stop() ``` Features: - ✅ Automatic port detection (avoids confl...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...omatic port detection (avoids conflicts) - ✅ Proper startup/shutdown lifecycle - ✅ ...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...s) - ✅ Proper startup/shutdown lifecycle - ✅ Thread-based server execution - ✅ Wait...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...ecycle - ✅ Thread-based server execution - ✅ Waits for server to be ready - ✅ Grace...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...ecution - ✅ Waits for server to be ready - ✅ Graceful cleanup ### 2. Pytest Fixtur...
(QB_NEW_EN)
[grammar] ~46-~46: Use correct spacing
Context: ... server to be ready - ✅ Graceful cleanup ### 2. Pytest Fixtures Use pytest fixtures ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~48-~48: Use correct spacing
Context: ...Graceful cleanup ### 2. Pytest Fixtures Use pytest fixtures for automatic server...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~50-~50: Use correct spacing
Context: ...ixtures for automatic server management: python @pytest.fixture(scope="session") def running_server(): """Server shared across all tests in the session.""" server = UvicornTestServer(app) server.start() yield server server.stop() @pytest.fixture(scope="function") def fresh_server(): """Fresh server for each test.""" server = UvicornTestServer(app) server.start() yield server server.stop() ### 3. Manual Server Management For full co...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~70-~70: Use correct spacing
Context: ...p() ``` ### 3. Manual Server Management For full control over server lifecycle: ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~72-~72: Use correct spacing
Context: ... For full control over server lifecycle: python @pytest.mark.asyncio async def test_manual_server(): server = UvicornTestServer(app) try: server.start() # Your test code here async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: assert response.status == 200 finally: server.stop() # Always cleanup ## 🏃♂️ Running the Examples ### Install ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~89-~89: There might be a mistake here.
Context: ...eanup ## 🏃♂️ Running the Examples ### Install Dependencies bash cd integra...
(QB_NEW_EN)
[grammar] ~91-~91: Use correct spacing
Context: ...g the Examples ### Install Dependencies bash cd integration-tests uv sync ### Run Tests ```bash # Run all tests uv ru...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~98-~98: Use correct spacing
Context: ...gration-tests uv sync ### Run Tests bash # Run all tests uv run python -m pytest test_basic.py -v # Run specific test uv run python -m pytest test_basic.py::test_basic_with_session_server -v -s # Run with output uv run python -m pytest test_basic.py -v -s ### Run Demo Server bash # Start a serve...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~111-~111: Use correct spacing
Context: ..._basic.py -v -s ### Run Demo Server bash # Start a server you can send requests to uv run python demo_server.py Then in another terminal:bash curl h...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~118-~118: Use correct spacing
Context: ...server.py Then in another terminal:bash curl http://127.0.0.1:8000/health curl http://127.0.0.1:8000/test ``` ## 📁 File Overview - test_basic.py ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~124-~124: There might be a problem here.
Context: ...0.0.1:8000/test ``` ## 📁 File Overview - test_basic.py - Main test file with UvicornTestServer ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~126-~126: Use correct spacing
Context: ...ith UvicornTestServer class and examples - test_server_examples.py - Comprehensive examples of different te...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~127-~127: Use correct spacing
Context: ...examples of different testing approaches - demo_server.py - Simple script to run a server manually...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~128-~128: Use correct spacing
Context: ...- Simple script to run a server manually - pyproject.toml - Project dependencies ## 🎯 When to Us...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~129-~129: Use correct spacing
Context: ...pyproject.toml`** - Project dependencies ## 🎯 When to Use Each Approach ### Sessio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~131-~131: There might be a mistake here.
Context: ...dencies ## 🎯 When to Use Each Approach ### Session-Scoped Server (running_server ...
(QB_NEW_EN)
[grammar] ~133-~133: There might be a mistake here.
Context: ...Scoped Server (running_server fixture) - ✅ Fast test execution (server starts onc...
(QB_NEW_EN)
[grammar] ~134-~134: There might be a mistake here.
Context: ...Fast test execution (server starts once) - ✅ Good for multiple tests that don't int...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ... for multiple tests that don't interfere - ❌ Tests share state - Use for: Most ...
(QB_NEW_EN)
[grammar] ~136-~136: There might be a mistake here.
Context: ...at don't interfere - ❌ Tests share state - Use for: Most integration tests ### F...
(QB_NEW_EN)
[grammar] ~137-~137: Use correct spacing
Context: ...te - Use for: Most integration tests ### Function-Scoped Server (fresh_server f...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~139-~139: There might be a mistake here.
Context: ...n-Scoped Server (fresh_server fixture) - ✅ Complete isolation between tests - ✅ C...
(QB_NEW_EN)
[grammar] ~140-~140: There might be a mistake here.
Context: ...) - ✅ Complete isolation between tests - ✅ Clean state for each test - ❌ Slower (...
(QB_NEW_EN)
[grammar] ~141-~141: There might be a mistake here.
Context: ...ween tests - ✅ Clean state for each test - ❌ Slower (starts server for each test) -...
(QB_NEW_EN)
[grammar] ~142-~142: There might be a mistake here.
Context: ...- ❌ Slower (starts server for each test) - Use for: Tests that modify server stat...
(QB_NEW_EN)
[grammar] ~143-~143: Use correct spacing
Context: ...se for**: Tests that modify server state ### Manual Server Management - ✅ Full contro...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~145-~145: There might be a mistake here.
Context: ...rver state ### Manual Server Management - ✅ Full control over lifecycle - ✅ Can te...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ...nagement - ✅ Full control over lifecycle - ✅ Can test server startup/shutdown - ❌ M...
(QB_NEW_EN)
[grammar] ~147-~147: There might be a mistake here.
Context: ...cle - ✅ Can test server startup/shutdown - ❌ More verbose - Use for: Complex sc...
(QB_NEW_EN)
[grammar] ~148-~148: There might be a mistake here.
Context: ...server startup/shutdown - ❌ More verbose - Use for: Complex scenarios, debugging ...
(QB_NEW_EN)
[grammar] ~149-~149: Use correct spacing
Context: ...Use for*: Complex scenarios, debugging ### Demo Server Script - ✅ Perfect for devel...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~151-~151: There might be a mistake here.
Context: ...arios, debugging ### Demo Server Script - ✅ Perfect for development and debugging ...
(QB_NEW_EN)
[grammar] ~152-~152: There might be a mistake here.
Context: ... ✅ Perfect for development and debugging - ✅ Can send real HTTP requests - ✅ Easy t...
(QB_NEW_EN)
[grammar] ~153-~153: There might be a mistake here.
Context: ...ebugging - ✅ Can send real HTTP requests - ✅ Easy to test endpoints manually - **Us...
(QB_NEW_EN)
[grammar] ~154-~154: There might be a mistake here.
Context: ...ests - ✅ Easy to test endpoints manually - Use for: Development, manual testing ...
(QB_NEW_EN)
[grammar] ~155-~155: Use correct spacing
Context: ...Use for: Development, manual testing ## 🔧 Key Features of UvicornTestServer 1....
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: There might be a mistake here.
Context: ... ## 🔧 Key Features of UvicornTestServer 1. Automatic Port Detection: Finds free p...
(QB_NEW_EN)
[grammar] ~159-~159: There might be a mistake here.
Context: ...n**: Finds free ports to avoid conflicts 2. Proper Lifecycle: Clean startup and sh...
(QB_NEW_EN_OTHER)
[grammar] ~164-~164: There might be a mistake here.
Context: ...ng**: Robust error handling and timeouts ## 🚀 Making HTTP Requests Once you have a...
(QB_NEW_EN_OTHER)
[grammar] ~166-~166: There might be a mistake here.
Context: ...and timeouts ## 🚀 Making HTTP Requests Once you have a running server, you can ...
(QB_NEW_EN)
[grammar] ~168-~168: There might be a mistake here.
Context: ...a running server, you can make requests using: ### With aiohttp (async) ```python async wit...
(QB_NEW_EN_OTHER)
[grammar] ~170-~170: Use correct spacing
Context: ...equests using: ### With aiohttp (async) python async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: data = await response.json() assert data["message"] == "OK" ### With httpx (async) ```python async with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~178-~178: Use correct spacing
Context: ...ge"] == "OK" ### With httpx (async)python async with httpx.AsyncClient() as client: response = await client.get(f"{server.base_url}/health") assert response.status_code == 200 ### With curl (command line)bash curl ht...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~185-~185: Use correct spacing
Context: ...== 200 ### With curl (command line)bash curl http://127.0.0.1:8000/health curl -X POST http://127.0.0.1:8000/api/data -H "Content-Type: application/json" -d '{"key": "value"}' ### With requests (sync)python import re...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~191-~191: Use correct spacing
Context: ... "value"}' ### With requests (sync)python import requests response = requests.get(f"{server.base_url}/health") assert response.status_code == 200 ``` ## 🎉 Success! Now you have a proper way t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~198-~198: There might be a mistake here.
Context: ...e.status_code == 200 ``` ## 🎉 Success! Now you have a proper way to run uvicorn...
(QB_NEW_EN)
[grammar] ~200-~200: There might be a mistake here.
Context: ...rn servers for integration testing that: - ✅ Actually starts and stops properly - ✅...
(QB_NEW_EN)
[grammar] ~201-~201: There might be a mistake here.
Context: ...: - ✅ Actually starts and stops properly - ✅ Provides real HTTP endpoints - ✅ Handl...
(QB_NEW_EN)
[grammar] ~202-~202: There might be a mistake here.
Context: ...roperly - ✅ Provides real HTTP endpoints - ✅ Handles cleanup automatically - ✅ Avoi...
(QB_NEW_EN)
[grammar] ~203-~203: There might be a mistake here.
Context: ...points - ✅ Handles cleanup automatically - ✅ Avoids port conflicts - ✅ Works reliab...
(QB_NEW_EN)
[grammar] ~204-~204: There might be a mistake here.
Context: ... automatically - ✅ Avoids port conflicts - ✅ Works reliably in CI/CD No more block...
(QB_NEW_EN)
[grammar] ~205-~205: Use correct spacing
Context: ...rt conflicts - ✅ Works reliably in CI/CD No more blocking uvicorn.run() calls o...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🪛 markdownlint-cli2 (0.17.2)
integration-tests/README.md
42-42: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
119-119: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
133-133: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
134-134: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
139-139: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
140-140: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
145-145: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
146-146: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
151-151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
152-152: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
170-170: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
171-171: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
178-178: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
179-179: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
185-185: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
186-186: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
191-191: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
192-192: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
201-201: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
207-207: Trailing spaces
Expected: 0 or 2; Actual: 1
(MD009, no-trailing-spaces)
207-207: Files should end with a single newline character
(MD047, single-trailing-newline)
🔇 Additional comments (8)
python-sdk/pyproject.toml (4)
1-3: Build backend config looks good.
12-15: Dependency versions verified. Bothaiohttp>=3.12.15andpydantic>=2.11.7exist on PyPI, so no further changes are needed.
32-34: Validate dynamic version attribute path
exospherehost._version.versionwasn’t found in python-sdk/exospherehost/_version.py; ensure that module exports aversionsymbol or updateattrto the correct identifier (e.g.,__version__).
10-10: Keep Python requirement at ≥3.12
All CI workflows explicitly pin to Python 3.12, so the existingrequires-python = ">=3.12"aligns with current pipelines.Likely an incorrect or invalid review comment.
state-manager/pyproject.toml (2)
1-3: Build backend config looks good.
11-21: Pinned dependency versions confirmed
All specified versions in state-manager/pyproject.toml (lines 11–21) exist on PyPI—no resolver failures expected.integration-tests/pyproject.toml (1)
20-22: Verify local source names match package namesEnsure the installed project names exactly match these keys; otherwise uv won’t map to local paths.
- Confirm
python-sdk/pyproject.tomlexposesname = "exospherehost"andstate-manager/pyproject.tomlexposesname = "state-manager".integration-tests/conftest.py (1)
6-6: Import path may fail in CI due to working-directory; set PYTHONPATH or install the appThe workflow sets
working-directory: integration-tests, sofrom app.main import appwon’t resolve unlessapp/is importable from that directory.Options:
- Add
PYTHONPATH: ${{ github.workspace }}to the test step env.- Or install the top-level package before running tests.
Also applies to: 30-36, 98-106
| @@ -0,0 +1,58 @@ | |||
| name: Integration Tests for Exosphere | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Set minimal permissions for the workflow (defense-in-depth)
Not required but recommended.
name: Integration Tests for Exosphere
+permissions:
+ contents: read📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| name: Integration Tests for Exosphere | |
| name: Integration Tests for Exosphere | |
| permissions: | |
| contents: read |
🤖 Prompt for AI Agents
.github/workflows/integration-tests.yml lines 1-1: the workflow currently has no
explicit permissions declared; add a minimal permissions block scoped to only
the token scopes the job requires (e.g., read-only for contents, packages,
pull-requests, or write only if the workflow needs to create status/comments)
instead of leaving defaults. Update the workflow YAML to include a top-level
permissions mapping with the least-privilege scopes required by the integration
tests and narrow any job-level or step-level permissions further if possible.
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - 'integration-tests/**' | ||
| - 'state-manager/**' | ||
| - 'python-sdk/**' | ||
| - '.github/workflows/integration-tests.yml' | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Quote “on” and fix indentation to satisfy yamllint and avoid parse surprises
YAML treats on as a boolean unless quoted. Also several blocks are indented inconsistently.
-name: Integration Tests for Exosphere
-
-on:
- push:
- branches: [main]
- paths:
- - 'integration-tests/**'
- - 'state-manager/**'
- - 'python-sdk/**'
- - '.github/workflows/integration-tests.yml'
+name: Integration Tests for Exosphere
+
+'on':
+ push:
+ branches: [main]
+ paths:
+ - integration-tests/**
+ - state-manager/**
+ - python-sdk/**
+ - .github/workflows/integration-tests.yml📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'integration-tests/**' | |
| - 'state-manager/**' | |
| - 'python-sdk/**' | |
| - '.github/workflows/integration-tests.yml' | |
| name: Integration Tests for Exosphere | |
| 'on': | |
| push: | |
| branches: [main] | |
| paths: | |
| - integration-tests/** | |
| - state-manager/** | |
| - python-sdk/** | |
| - .github/workflows/integration-tests.yml |
🧰 Tools
🪛 YAMLlint (1.37.1)
[warning] 3-3: truthy value should be one of [false, true]
(truthy)
[error] 7-7: wrong indentation: expected 12 but found 10
(indentation)
🤖 Prompt for AI Agents
.github/workflows/integration-tests.yml lines 3-11: the YAML key on must be
quoted and the nested blocks need consistent indentation to satisfy yamllint and
avoid parsing surprises; update the file to quote "on" (e.g. "on":) and
re-indent the following block using a consistent 2-space indentation for push,
branches, paths and each path item so sequences and mappings align properly.
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| services: | ||
| mongodb: | ||
| image: mongo:7 | ||
| ports: | ||
| - 27017:27017 | ||
| options: >- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Tighten job config: timeout, consistent indentation, and uv install groups
- Add a timeout to avoid hung CI.
- Use
uv sync --all-groups(or plainuv sync) becausedependency-groups.devis empty;--group devmay exclude core deps depending on uv config. - Fix indentation to two spaces consistently.
jobs:
- test:
- runs-on: ubuntu-latest
- services:
- mongodb:
- image: mongo:7
- ports:
- - 27017:27017
+ test:
+ runs-on: ubuntu-latest
+ timeout-minutes: 20
+ services:
+ mongodb:
+ image: mongo:7
+ ports:
+ - 27017:27017
...
- steps:
- - name: Checkout code
- uses: actions/checkout@v4
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
...
- - name: Install dev dependencies with uv
+ - name: Install dependencies with uv
working-directory: integration-tests
run: |
- uv sync --group dev
+ uv sync --all-groupsIf you intend to install only the default group (not dev), use just uv sync. Please confirm your intended uv behavior.
Also applies to: 30-58
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== First 100 lines of .github/workflows/integration-tests.yml =="
sed -n '1,100p' .github/workflows/integration-tests.yml
echo
echo "== uv sync occurrences =="
grep -n "uv sync" .github/workflows/integration-tests.yml || trueLength of output: 2064
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== dependency-groups occurrences =="
grep -R "dependency-groups" -n . || true
echo
echo "== pyproject.toml files =="
find . -type f | grep pyproject.toml || echo "none"
echo
echo "== setup.cfg for dependency-groups =="
grep -R "dependency_groups" -n . || trueLength of output: 734
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== List of workflow files =="
ls .github/workflows
for f in .github/workflows/*.yml; do
echo
echo "== $f first 5 lines =="
sed -n '1,5p' "$f"
done
echo
echo "== integration-tests pyproject.toml [dependency-groups] section =="
grep -n '^\[dependency-groups\]' -n integration-tests/pyproject.toml
sed -n '1,50p' integration-tests/pyproject.tomlLength of output: 6290
Tighten integration-tests workflow: add timeout, fix indentation, and adjust uv invocation
- Under the
testjob, adddirectly beneathtimeout-minutes: 20
runs-on: ubuntu-latestto prevent CI hangs. - Reformat
.github/workflows/integration-tests.ymlto use 2-space indentation consistently. - In the “Install dependencies with uv” step, change
to
uv sync --group dev
(or simplyuv sync --all-groups
uv syncif you only intend to install the default group), since[dependency-groups].dev = []inintegration-tests/pyproject.toml. Confirm which groups you mean to install.
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 17-17: wrong indentation: expected 16 but found 14
(indentation)
[error] 19-19: wrong indentation: expected 18 but found 16
(indentation)
🤖 Prompt for AI Agents
.github/workflows/integration-tests.yml lines 12-20: the workflow needs a job
timeout, consistent 2-space indentation, and the uv invocation adjusted; add
"timeout-minutes: 20" directly beneath "runs-on: ubuntu-latest", reformat the
surrounding YAML to use 2-space indentation everywhere in this file, and in the
"Install dependencies with uv" step replace "uv sync --group dev" with "uv sync
--all-groups" (or "uv sync" if you intend only the default group) — verify which
dependency groups you want installed and update the command accordingly.
| --health-cmd "mongosh --eval 'db.runCommand(\"ping\")'" | ||
| --health-interval 10s | ||
| --health-timeout 5s | ||
| --health-retries 5 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix MongoDB healthcheck: wrong command and missing auth cause unhealthy service
db.runCommand("ping") is invalid and the check doesn’t authenticate against the root user you create, so the service may never become healthy.
Apply:
- options: >-
- --health-cmd "mongosh --eval 'db.runCommand(\"ping\")'"
+ options: >-
+ --health-cmd "mongosh --username admin --password password --authenticationDatabase admin --quiet --eval 'db.adminCommand({ ping: 1 }).ok'"
--health-interval 10s
--health-timeout 5s
--health-retries 5📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| --health-cmd "mongosh --eval 'db.runCommand(\"ping\")'" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| options: >- | |
| --health-cmd "mongosh --username admin --password password --authenticationDatabase admin --quiet --eval 'db.adminCommand({ ping: 1 }).ok'" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 |
🤖 Prompt for AI Agents
.github/workflows/integration-tests.yml around lines 21-24: the healthcheck uses
an invalid db.runCommand("ping") and doesn’t authenticate the root user, so
container stays unhealthy; change the command to authenticate against the admin
user and call adminCommand({ping:1}) instead, e.g. invoke mongosh with the root
username/password from the environment (MONGO_INITDB_ROOT_USERNAME /
MONGO_INITDB_ROOT_PASSWORD) and --authenticationDatabase admin and run --eval
'db.adminCommand({ping:1})' so the healthcheck can succeed.
| MONGO_URI: mongodb://admin:password@localhost:27017 | ||
| MONGO_DATABASE_NAME: integration_tests | ||
| STATE_MANAGER_SECRET: test-secret-key | ||
| EXOSPHERE_API_KEY: test-secret-key | ||
| SECRETS_ENCRYPTION_KEY: YTzpUlBGLSwm-3yKJRJTZnb0_aQuQQHyz64s8qAERVU= | ||
| run: | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not commit secrets to the repo; use GitHub Secrets and add authSource to URI
Hard-coded API keys and encryption keys will be leaked to forks and logs. Also add authSource=admin to the URI since you create the root user in admin.
- MONGO_URI: mongodb://admin:password@localhost:27017
+ MONGO_URI: mongodb://admin:password@127.0.0.1:27017/?authSource=admin
MONGO_DATABASE_NAME: integration_tests
- STATE_MANAGER_SECRET: test-secret-key
- EXOSPHERE_API_KEY: test-secret-key
- SECRETS_ENCRYPTION_KEY: YTzpUlBGLSwm-3yKJRJTZnb0_aQuQQHyz64s8qAERVU=
+ STATE_MANAGER_SECRET: ${{ secrets.STATE_MANAGER_SECRET }}
+ EXOSPHERE_API_KEY: ${{ secrets.EXOSPHERE_API_KEY }}
+ SECRETS_ENCRYPTION_KEY: ${{ secrets.SECRETS_ENCRYPTION_KEY }}If you intentionally use throwaway defaults for local runs, write them to a .env during CI instead of committing them:
- name: Run integration tests
working-directory: integration-tests
env:
- MONGO_URI: mongodb://admin:password@127.0.0.1:27017/?authSource=admin
- MONGO_DATABASE_NAME: integration_tests
- STATE_MANAGER_SECRET: ${{ secrets.STATE_MANAGER_SECRET }}
- EXOSPHERE_API_KEY: ${{ secrets.EXOSPHERE_API_KEY }}
- SECRETS_ENCRYPTION_KEY: ${{ secrets.SECRETS_ENCRYPTION_KEY }}
+ MONGO_URI: mongodb://admin:password@127.0.0.1:27017/?authSource=admin
+ MONGO_DATABASE_NAME: integration_tests
+ STATE_MANAGER_SECRET: ${{ secrets.STATE_MANAGER_SECRET }}
+ EXOSPHERE_API_KEY: ${{ secrets.EXOSPHERE_API_KEY }}
+ SECRETS_ENCRYPTION_KEY: ${{ secrets.SECRETS_ENCRYPTION_KEY }}
run: |
- uv run pytest
+ : "${STATE_MANAGER_SECRET:=test-secret-key}"
+ : "${EXOSPHERE_API_KEY:=test-secret-key}"
+ : "${SECRETS_ENCRYPTION_KEY:=insecure-test-key}"
+ uv run pytest🧰 Tools
🪛 Gitleaks (8.27.2)
56-56: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 Checkov (3.2.334)
[MEDIUM] 52-53: Basic Auth Credentials
(CKV_SECRET_4)
[LOW] 56-57: Base64 High Entropy String
(CKV_SECRET_6)
🪛 YAMLlint (1.37.1)
[error] 52-52: wrong indentation: expected 14 but found 12
(indentation)
| python_files = test_*.py | ||
| python_classes = Test* | ||
| python_functions = test_* | ||
| asyncio_mode = auto |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Tighten asyncio checks to catch leaks/misuse.
If using pytest-asyncio ≥ 0.24, prefer strict mode.
-asyncio_mode = auto
+asyncio_mode = strict🤖 Prompt for AI Agents
In integration-tests/pytest.ini at line 5, the asyncio_mode is set to "auto";
change it to "strict" to enable stricter asyncio checks (asyncio_mode = strict)
and update test dependencies to ensure pytest-asyncio is pinned to >=0.24 (e.g.,
in requirements-dev or pyproject) so the strict mode is supported; after the
change, run the test suite to verify no new failures and adjust any tests that
relied on the more permissive behavior.
| # Integration Testing with Uvicorn Server | ||
|
|
||
| This directory contains examples of how to properly run and stop uvicorn servers for integration testing. Unlike the problematic approach of using `uvicorn.run()` (which blocks forever), these examples show you how to create real HTTP endpoints that you can send requests to. | ||
|
|
||
| ## 🚨 The Problem with `uvicorn.run()` | ||
|
|
||
| The original code had this issue: | ||
|
|
||
| ```python | ||
| @pytest.mark.asyncio | ||
| async def test_basic(): | ||
| uvicorn.run(app, host="127.0.0.1", port=8000) # ❌ This blocks forever! | ||
| async with ClientSession() as session: # ❌ This never executes | ||
| # ... test code that never runs | ||
| ``` | ||
|
|
||
| **Problem**: `uvicorn.run()` is a blocking call that never returns, so your test code after it never executes. | ||
|
|
||
| ## ✅ Proper Solutions | ||
|
|
||
| ### 1. UvicornTestServer Class (Recommended) | ||
|
|
||
| The `UvicornTestServer` class in `test_basic.py` provides a clean way to start and stop uvicorn servers: | ||
|
|
||
| ```python | ||
| from test_basic import UvicornTestServer | ||
|
|
||
| # Create and start server | ||
| server = UvicornTestServer(app, host="127.0.0.1", port=8000) | ||
| server.start() | ||
|
|
||
| # Make HTTP requests | ||
| async with ClientSession() as session: | ||
| async with session.get(f"{server.base_url}/health") as response: | ||
| assert response.status == 200 | ||
|
|
||
| # Stop server | ||
| server.stop() | ||
| ``` | ||
|
|
||
| **Features:** | ||
| - ✅ Automatic port detection (avoids conflicts) | ||
| - ✅ Proper startup/shutdown lifecycle | ||
| - ✅ Thread-based server execution | ||
| - ✅ Waits for server to be ready | ||
| - ✅ Graceful cleanup | ||
|
|
||
| ### 2. Pytest Fixtures | ||
|
|
||
| Use pytest fixtures for automatic server management: | ||
|
|
||
| ```python | ||
| @pytest.fixture(scope="session") | ||
| def running_server(): | ||
| """Server shared across all tests in the session.""" | ||
| server = UvicornTestServer(app) | ||
| server.start() | ||
| yield server | ||
| server.stop() | ||
|
|
||
| @pytest.fixture(scope="function") | ||
| def fresh_server(): | ||
| """Fresh server for each test.""" | ||
| server = UvicornTestServer(app) | ||
| server.start() | ||
| yield server | ||
| server.stop() | ||
| ``` | ||
|
|
||
| ### 3. Manual Server Management | ||
|
|
||
| For full control over server lifecycle: | ||
|
|
||
| ```python | ||
| @pytest.mark.asyncio | ||
| async def test_manual_server(): | ||
| server = UvicornTestServer(app) | ||
|
|
||
| try: | ||
| server.start() | ||
| # Your test code here | ||
| async with ClientSession() as session: | ||
| async with session.get(f"{server.base_url}/health") as response: | ||
| assert response.status == 200 | ||
| finally: | ||
| server.stop() # Always cleanup | ||
| ``` | ||
|
|
||
| ## 🏃♂️ Running the Examples | ||
|
|
||
| ### Install Dependencies | ||
|
|
||
| ```bash | ||
| cd integration-tests | ||
| uv sync | ||
| ``` | ||
|
|
||
| ### Run Tests | ||
|
|
||
| ```bash | ||
| # Run all tests | ||
| uv run python -m pytest test_basic.py -v | ||
|
|
||
| # Run specific test | ||
| uv run python -m pytest test_basic.py::test_basic_with_session_server -v -s | ||
|
|
||
| # Run with output | ||
| uv run python -m pytest test_basic.py -v -s | ||
| ``` | ||
|
|
||
| ### Run Demo Server | ||
|
|
||
| ```bash | ||
| # Start a server you can send requests to | ||
| uv run python demo_server.py | ||
| ``` | ||
|
|
||
| Then in another terminal: | ||
| ```bash | ||
| curl http://127.0.0.1:8000/health | ||
| curl http://127.0.0.1:8000/test | ||
| ``` | ||
|
|
||
| ## 📁 File Overview | ||
|
|
||
| - **`test_basic.py`** - Main test file with UvicornTestServer class and examples | ||
| - **`test_server_examples.py`** - Comprehensive examples of different testing approaches | ||
| - **`demo_server.py`** - Simple script to run a server manually | ||
| - **`pyproject.toml`** - Project dependencies | ||
|
|
||
| ## 🎯 When to Use Each Approach | ||
|
|
||
| ### Session-Scoped Server (`running_server` fixture) | ||
| - ✅ Fast test execution (server starts once) | ||
| - ✅ Good for multiple tests that don't interfere | ||
| - ❌ Tests share state | ||
| - **Use for**: Most integration tests | ||
|
|
||
| ### Function-Scoped Server (`fresh_server` fixture) | ||
| - ✅ Complete isolation between tests | ||
| - ✅ Clean state for each test | ||
| - ❌ Slower (starts server for each test) | ||
| - **Use for**: Tests that modify server state | ||
|
|
||
| ### Manual Server Management | ||
| - ✅ Full control over lifecycle | ||
| - ✅ Can test server startup/shutdown | ||
| - ❌ More verbose | ||
| - **Use for**: Complex scenarios, debugging | ||
|
|
||
| ### Demo Server Script | ||
| - ✅ Perfect for development and debugging | ||
| - ✅ Can send real HTTP requests | ||
| - ✅ Easy to test endpoints manually | ||
| - **Use for**: Development, manual testing | ||
|
|
||
| ## 🔧 Key Features of UvicornTestServer | ||
|
|
||
| 1. **Automatic Port Detection**: Finds free ports to avoid conflicts | ||
| 2. **Proper Lifecycle**: Clean startup and shutdown | ||
| 3. **Thread Safety**: Runs server in background thread | ||
| 4. **Health Checking**: Waits for server to be ready | ||
| 5. **Graceful Shutdown**: Proper cleanup on exit | ||
| 6. **Error Handling**: Robust error handling and timeouts | ||
|
|
||
| ## 🚀 Making HTTP Requests | ||
|
|
||
| Once you have a running server, you can make requests using: | ||
|
|
||
| ### With aiohttp (async) | ||
| ```python | ||
| async with ClientSession() as session: | ||
| async with session.get(f"{server.base_url}/health") as response: | ||
| data = await response.json() | ||
| assert data["message"] == "OK" | ||
| ``` | ||
|
|
||
| ### With httpx (async) | ||
| ```python | ||
| async with httpx.AsyncClient() as client: | ||
| response = await client.get(f"{server.base_url}/health") | ||
| assert response.status_code == 200 | ||
| ``` | ||
|
|
||
| ### With curl (command line) | ||
| ```bash | ||
| curl http://127.0.0.1:8000/health | ||
| curl -X POST http://127.0.0.1:8000/api/data -H "Content-Type: application/json" -d '{"key": "value"}' | ||
| ``` | ||
|
|
||
| ### With requests (sync) | ||
| ```python | ||
| import requests | ||
| response = requests.get(f"{server.base_url}/health") | ||
| assert response.status_code == 200 | ||
| ``` | ||
|
|
||
| ## 🎉 Success! | ||
|
|
||
| Now you have a proper way to run uvicorn servers for integration testing that: | ||
| - ✅ Actually starts and stops properly | ||
| - ✅ Provides real HTTP endpoints | ||
| - ✅ Handles cleanup automatically | ||
| - ✅ Avoids port conflicts | ||
| - ✅ Works reliably in CI/CD | ||
|
|
||
| No more blocking `uvicorn.run()` calls or tests that never execute! No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Fix markdown spacing and trailing newline to satisfy markdownlint
Add blank lines around headings, lists, and fenced blocks; remove trailing spaces; end file with a newline.
If you want, I can run a pass and push a formatted version.
🧰 Tools
🪛 LanguageTool
[grammar] ~1-~1: Use correct spacing
Context: ... Integration Testing with Uvicorn Server This directory contains examples of how ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: ...endpoints that you can send requests to. ## 🚨 The Problem with uvicorn.run() The...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~5-~5: There might be a mistake here.
Context: ...nd requests to. ## 🚨 The Problem with uvicorn.run() The original code had this issue: ```py...
(QB_NEW_EN)
[grammar] ~7-~7: Use correct spacing
Context: ...un() The original code had this issue: ```python @pytest.mark.asyncio async def test_basic(): uvicorn.run(app, host="127.0.0.1", port=8000) # ❌ This blocks forever! async with ClientSession() as session: # ❌ This never executes # ... test code that never runs ``` **Problem**:uvicorn.run()` is a blocking...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~17-~17: Use correct spacing
Context: ... your test code after it never executes. ## ✅ Proper Solutions ### 1. UvicornTestSe...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~19-~19: Use correct spacing
Context: ...t never executes. ## ✅ Proper Solutions ### 1. UvicornTestServer Class (Recommended)...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~21-~21: Use correct spacing
Context: ...1. UvicornTestServer Class (Recommended) The UvicornTestServer class in `test_b...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~23-~23: Use correct spacing
Context: ...n way to start and stop uvicorn servers: python from test_basic import UvicornTestServer # Create and start server server = UvicornTestServer(app, host="127.0.0.1", port=8000) server.start() # Make HTTP requests async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: assert response.status == 200 # Stop server server.stop() Features: - ✅ Automatic port detection...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~41-~41: There might be a mistake here.
Context: ...op server server.stop() ``` Features: - ✅ Automatic port detection (avoids confl...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ...omatic port detection (avoids conflicts) - ✅ Proper startup/shutdown lifecycle - ✅ ...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ...s) - ✅ Proper startup/shutdown lifecycle - ✅ Thread-based server execution - ✅ Wait...
(QB_NEW_EN)
[grammar] ~44-~44: There might be a mistake here.
Context: ...ecycle - ✅ Thread-based server execution - ✅ Waits for server to be ready - ✅ Grace...
(QB_NEW_EN)
[grammar] ~45-~45: There might be a mistake here.
Context: ...ecution - ✅ Waits for server to be ready - ✅ Graceful cleanup ### 2. Pytest Fixtur...
(QB_NEW_EN)
[grammar] ~46-~46: Use correct spacing
Context: ... server to be ready - ✅ Graceful cleanup ### 2. Pytest Fixtures Use pytest fixtures ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~48-~48: Use correct spacing
Context: ...Graceful cleanup ### 2. Pytest Fixtures Use pytest fixtures for automatic server...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~50-~50: Use correct spacing
Context: ...ixtures for automatic server management: python @pytest.fixture(scope="session") def running_server(): """Server shared across all tests in the session.""" server = UvicornTestServer(app) server.start() yield server server.stop() @pytest.fixture(scope="function") def fresh_server(): """Fresh server for each test.""" server = UvicornTestServer(app) server.start() yield server server.stop() ### 3. Manual Server Management For full co...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~70-~70: Use correct spacing
Context: ...p() ``` ### 3. Manual Server Management For full control over server lifecycle: ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~72-~72: Use correct spacing
Context: ... For full control over server lifecycle: python @pytest.mark.asyncio async def test_manual_server(): server = UvicornTestServer(app) try: server.start() # Your test code here async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: assert response.status == 200 finally: server.stop() # Always cleanup ## 🏃♂️ Running the Examples ### Install ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~89-~89: There might be a mistake here.
Context: ...eanup ## 🏃♂️ Running the Examples ### Install Dependencies bash cd integra...
(QB_NEW_EN)
[grammar] ~91-~91: Use correct spacing
Context: ...g the Examples ### Install Dependencies bash cd integration-tests uv sync ### Run Tests ```bash # Run all tests uv ru...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~98-~98: Use correct spacing
Context: ...gration-tests uv sync ### Run Tests bash # Run all tests uv run python -m pytest test_basic.py -v # Run specific test uv run python -m pytest test_basic.py::test_basic_with_session_server -v -s # Run with output uv run python -m pytest test_basic.py -v -s ### Run Demo Server bash # Start a serve...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~111-~111: Use correct spacing
Context: ..._basic.py -v -s ### Run Demo Server bash # Start a server you can send requests to uv run python demo_server.py Then in another terminal:bash curl h...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~118-~118: Use correct spacing
Context: ...server.py Then in another terminal:bash curl http://127.0.0.1:8000/health curl http://127.0.0.1:8000/test ``` ## 📁 File Overview - test_basic.py ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~124-~124: There might be a problem here.
Context: ...0.0.1:8000/test ``` ## 📁 File Overview - test_basic.py - Main test file with UvicornTestServer ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~126-~126: Use correct spacing
Context: ...ith UvicornTestServer class and examples - test_server_examples.py - Comprehensive examples of different te...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~127-~127: Use correct spacing
Context: ...examples of different testing approaches - demo_server.py - Simple script to run a server manually...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~128-~128: Use correct spacing
Context: ...- Simple script to run a server manually - pyproject.toml - Project dependencies ## 🎯 When to Us...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~129-~129: Use correct spacing
Context: ...pyproject.toml`** - Project dependencies ## 🎯 When to Use Each Approach ### Sessio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~131-~131: There might be a mistake here.
Context: ...dencies ## 🎯 When to Use Each Approach ### Session-Scoped Server (running_server ...
(QB_NEW_EN)
[grammar] ~133-~133: There might be a mistake here.
Context: ...Scoped Server (running_server fixture) - ✅ Fast test execution (server starts onc...
(QB_NEW_EN)
[grammar] ~134-~134: There might be a mistake here.
Context: ...Fast test execution (server starts once) - ✅ Good for multiple tests that don't int...
(QB_NEW_EN)
[grammar] ~135-~135: There might be a mistake here.
Context: ... for multiple tests that don't interfere - ❌ Tests share state - Use for: Most ...
(QB_NEW_EN)
[grammar] ~136-~136: There might be a mistake here.
Context: ...at don't interfere - ❌ Tests share state - Use for: Most integration tests ### F...
(QB_NEW_EN)
[grammar] ~137-~137: Use correct spacing
Context: ...te - Use for: Most integration tests ### Function-Scoped Server (fresh_server f...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~139-~139: There might be a mistake here.
Context: ...n-Scoped Server (fresh_server fixture) - ✅ Complete isolation between tests - ✅ C...
(QB_NEW_EN)
[grammar] ~140-~140: There might be a mistake here.
Context: ...) - ✅ Complete isolation between tests - ✅ Clean state for each test - ❌ Slower (...
(QB_NEW_EN)
[grammar] ~141-~141: There might be a mistake here.
Context: ...ween tests - ✅ Clean state for each test - ❌ Slower (starts server for each test) -...
(QB_NEW_EN)
[grammar] ~142-~142: There might be a mistake here.
Context: ...- ❌ Slower (starts server for each test) - Use for: Tests that modify server stat...
(QB_NEW_EN)
[grammar] ~143-~143: Use correct spacing
Context: ...se for**: Tests that modify server state ### Manual Server Management - ✅ Full contro...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~145-~145: There might be a mistake here.
Context: ...rver state ### Manual Server Management - ✅ Full control over lifecycle - ✅ Can te...
(QB_NEW_EN)
[grammar] ~146-~146: There might be a mistake here.
Context: ...nagement - ✅ Full control over lifecycle - ✅ Can test server startup/shutdown - ❌ M...
(QB_NEW_EN)
[grammar] ~147-~147: There might be a mistake here.
Context: ...cle - ✅ Can test server startup/shutdown - ❌ More verbose - Use for: Complex sc...
(QB_NEW_EN)
[grammar] ~148-~148: There might be a mistake here.
Context: ...server startup/shutdown - ❌ More verbose - Use for: Complex scenarios, debugging ...
(QB_NEW_EN)
[grammar] ~149-~149: Use correct spacing
Context: ...Use for*: Complex scenarios, debugging ### Demo Server Script - ✅ Perfect for devel...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~151-~151: There might be a mistake here.
Context: ...arios, debugging ### Demo Server Script - ✅ Perfect for development and debugging ...
(QB_NEW_EN)
[grammar] ~152-~152: There might be a mistake here.
Context: ... ✅ Perfect for development and debugging - ✅ Can send real HTTP requests - ✅ Easy t...
(QB_NEW_EN)
[grammar] ~153-~153: There might be a mistake here.
Context: ...ebugging - ✅ Can send real HTTP requests - ✅ Easy to test endpoints manually - **Us...
(QB_NEW_EN)
[grammar] ~154-~154: There might be a mistake here.
Context: ...ests - ✅ Easy to test endpoints manually - Use for: Development, manual testing ...
(QB_NEW_EN)
[grammar] ~155-~155: Use correct spacing
Context: ...Use for: Development, manual testing ## 🔧 Key Features of UvicornTestServer 1....
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: There might be a mistake here.
Context: ... ## 🔧 Key Features of UvicornTestServer 1. Automatic Port Detection: Finds free p...
(QB_NEW_EN)
[grammar] ~159-~159: There might be a mistake here.
Context: ...n**: Finds free ports to avoid conflicts 2. Proper Lifecycle: Clean startup and sh...
(QB_NEW_EN_OTHER)
[grammar] ~164-~164: There might be a mistake here.
Context: ...ng**: Robust error handling and timeouts ## 🚀 Making HTTP Requests Once you have a...
(QB_NEW_EN_OTHER)
[grammar] ~166-~166: There might be a mistake here.
Context: ...and timeouts ## 🚀 Making HTTP Requests Once you have a running server, you can ...
(QB_NEW_EN)
[grammar] ~168-~168: There might be a mistake here.
Context: ...a running server, you can make requests using: ### With aiohttp (async) ```python async wit...
(QB_NEW_EN_OTHER)
[grammar] ~170-~170: Use correct spacing
Context: ...equests using: ### With aiohttp (async) python async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: data = await response.json() assert data["message"] == "OK" ### With httpx (async) ```python async with ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~178-~178: Use correct spacing
Context: ...ge"] == "OK" ### With httpx (async)python async with httpx.AsyncClient() as client: response = await client.get(f"{server.base_url}/health") assert response.status_code == 200 ### With curl (command line)bash curl ht...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~185-~185: Use correct spacing
Context: ...== 200 ### With curl (command line)bash curl http://127.0.0.1:8000/health curl -X POST http://127.0.0.1:8000/api/data -H "Content-Type: application/json" -d '{"key": "value"}' ### With requests (sync)python import re...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~191-~191: Use correct spacing
Context: ... "value"}' ### With requests (sync)python import requests response = requests.get(f"{server.base_url}/health") assert response.status_code == 200 ``` ## 🎉 Success! Now you have a proper way t...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~198-~198: There might be a mistake here.
Context: ...e.status_code == 200 ``` ## 🎉 Success! Now you have a proper way to run uvicorn...
(QB_NEW_EN)
[grammar] ~200-~200: There might be a mistake here.
Context: ...rn servers for integration testing that: - ✅ Actually starts and stops properly - ✅...
(QB_NEW_EN)
[grammar] ~201-~201: There might be a mistake here.
Context: ...: - ✅ Actually starts and stops properly - ✅ Provides real HTTP endpoints - ✅ Handl...
(QB_NEW_EN)
[grammar] ~202-~202: There might be a mistake here.
Context: ...roperly - ✅ Provides real HTTP endpoints - ✅ Handles cleanup automatically - ✅ Avoi...
(QB_NEW_EN)
[grammar] ~203-~203: There might be a mistake here.
Context: ...points - ✅ Handles cleanup automatically - ✅ Avoids port conflicts - ✅ Works reliab...
(QB_NEW_EN)
[grammar] ~204-~204: There might be a mistake here.
Context: ... automatically - ✅ Avoids port conflicts - ✅ Works reliably in CI/CD No more block...
(QB_NEW_EN)
[grammar] ~205-~205: Use correct spacing
Context: ...rt conflicts - ✅ Works reliably in CI/CD No more blocking uvicorn.run() calls o...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🪛 markdownlint-cli2 (0.17.2)
42-42: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
119-119: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
133-133: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
134-134: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
139-139: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
140-140: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
145-145: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
146-146: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
151-151: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
152-152: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
170-170: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
171-171: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
178-178: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
179-179: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
185-185: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
186-186: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
191-191: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below
(MD022, blanks-around-headings)
192-192: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
201-201: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
207-207: Trailing spaces
Expected: 0 or 2; Actual: 1
(MD009, no-trailing-spaces)
207-207: Files should end with a single newline character
(MD047, single-trailing-newline)
🤖 Prompt for AI Agents
In integration-tests/README.md lines 1 to 207, the file fails markdownlint
rules: missing blank lines before/after headings, lists and fenced code blocks,
contains trailing spaces, and lacks a final newline. Fix by inserting a single
blank line above and below each top-level heading, subheading, list block, and
fenced code block; remove any trailing spaces at end of lines; ensure the file
ends with exactly one newline character; then run markdownlint or a formatter to
verify compliance.
| The `UvicornTestServer` class in `test_basic.py` provides a clean way to start and stop uvicorn servers: | ||
|
|
||
| ```python | ||
| from test_basic import UvicornTestServer | ||
|
|
||
| # Create and start server | ||
| server = UvicornTestServer(app, host="127.0.0.1", port=8000) | ||
| server.start() | ||
|
|
||
| # Make HTTP requests | ||
| async with ClientSession() as session: | ||
| async with session.get(f"{server.base_url}/health") as response: | ||
| assert response.status == 200 | ||
|
|
||
| # Stop server | ||
| server.stop() | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File references don’t match the repo (class now lives in conftest.py)
You reference UvicornTestServer in test_basic.py, but the implementation is in integration-tests/conftest.py. Update paths to avoid confusing contributors.
-from test_basic import UvicornTestServer
+from conftest import UvicornTestServer📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The `UvicornTestServer` class in `test_basic.py` provides a clean way to start and stop uvicorn servers: | |
| ```python | |
| from test_basic import UvicornTestServer | |
| # Create and start server | |
| server = UvicornTestServer(app, host="127.0.0.1", port=8000) | |
| server.start() | |
| # Make HTTP requests | |
| async with ClientSession() as session: | |
| async with session.get(f"{server.base_url}/health") as response: | |
| assert response.status == 200 | |
| # Stop server | |
| server.stop() | |
| ``` | |
| from conftest import UvicornTestServer | |
| # Create and start server | |
| server = UvicornTestServer(app, host="127.0.0.1", port=8000) | |
| server.start() | |
| # Make HTTP requests | |
| async with ClientSession() as session: | |
| async with session.get(f"{server.base_url}/health") as response: | |
| assert response.status == 200 | |
| # Stop server | |
| server.stop() |
🧰 Tools
🪛 LanguageTool
[grammar] ~23-~23: Use correct spacing
Context: ...n way to start and stop uvicorn servers: python from test_basic import UvicornTestServer # Create and start server server = UvicornTestServer(app, host="127.0.0.1", port=8000) server.start() # Make HTTP requests async with ClientSession() as session: async with session.get(f"{server.base_url}/health") as response: assert response.status == 200 # Stop server server.stop() Features: - ✅ Automatic port detection...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🤖 Prompt for AI Agents
In integration-tests/README.md around lines 23 to 39, the README references
UvicornTestServer as if it lives in test_basic.py but the class actually resides
in integration-tests/conftest.py; update the README text and example to point to
integration-tests/conftest.py (or show importing/using it from conftest) and
adjust any import path or usage example so contributors are directed to the
correct file.
| ## 📁 File Overview | ||
|
|
||
| - **`test_basic.py`** - Main test file with UvicornTestServer class and examples | ||
| - **`test_server_examples.py`** - Comprehensive examples of different testing approaches | ||
| - **`demo_server.py`** - Simple script to run a server manually | ||
| - **`pyproject.toml`** - Project dependencies | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧹 Nitpick (assertive)
Remove/adjust file overview entries that aren’t shipped in this PR
If test_basic.py, test_server_examples.py, and demo_server.py aren’t present, drop or gate them behind a future work note.
🧰 Tools
🪛 LanguageTool
[grammar] ~124-~124: There might be a problem here.
Context: ...0.0.1:8000/test ``` ## 📁 File Overview - test_basic.py - Main test file with UvicornTestServer ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~126-~126: Use correct spacing
Context: ...ith UvicornTestServer class and examples - test_server_examples.py - Comprehensive examples of different te...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~127-~127: Use correct spacing
Context: ...examples of different testing approaches - demo_server.py - Simple script to run a server manually...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~128-~128: Use correct spacing
Context: ...- Simple script to run a server manually - pyproject.toml - Project dependencies ## 🎯 When to Us...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~129-~129: Use correct spacing
Context: ...pyproject.toml`** - Project dependencies ## 🎯 When to Use Each Approach ### Sessio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
🤖 Prompt for AI Agents
In integration-tests/README.md around lines 124 to 130, the file overview lists
test_basic.py, test_server_examples.py, and demo_server.py which are not
included in this PR; either remove those entries or change them to a “future
work / not shipped in this PR” note and, if appropriate, only document files
that are actually present in the repo for this PR; update the list so it
accurately reflects shipped files or clearly indicates missing examples are
planned for a later change.
| async with ClientSession() as session: | ||
| async with session.get(f"{running_server.base_url}/health") as response: | ||
| assert response.status == 200 | ||
| data = await response.json() | ||
| assert data["message"] == "OK" No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Add timeout and fail fast on non-200 responses to reduce flakiness
Explicit timeouts prevent hung jobs; raising for non-2xx gives clearer failures.
- async with ClientSession() as session:
- async with session.get(f"{running_server.base_url}/health") as response:
- assert response.status == 200
- data = await response.json()
- assert data["message"] == "OK"
+ async with ClientSession(timeout=aiohttp.ClientTimeout(total=10)) as session:
+ async with session.get(f"{running_server.base_url}/health") as response:
+ response.raise_for_status()
+ data = await response.json()
+ assert data.get("message") == "OK"Note: add import aiohttp at the top or use from aiohttp import ClientSession, ClientTimeout and adjust accordingly.
🏁 Script executed:
#!/bin/bash
# Locate and display the beginning of integration-tests/test_health.py to inspect imports and existing session usage
file="$(fd -e py test_health.py)"
[ -n "$file" ] && sed -n '1,50p' "$file"Length of output: 598
🏁 Script executed:
#!/bin/bash
# Find all occurrences of ClientSession usage in integration-tests
rg -n --color never "ClientSession" -C2 integration-tests
# Find any mention of ClientTimeout in the repo
rg -n --color never "ClientTimeout" -C2 .Length of output: 2188
Add timeout and fail-fast on health endpoint
Prevent tests hanging on the default 5 min timeout (300 s) by using a 10 s total timeout, and raise on non-2xx for clearer failures.
--- a/integration-tests/test_health.py
+++ b/integration-tests/test_health.py
@@ 1,2c1,2
-from aiohttp import ClientSession
+from aiohttp import ClientSession, ClientTimeout
@@ 7c7
- async with ClientSession() as session:
+ async with ClientSession(timeout=ClientTimeout(total=10)) as session:
@@ 9,10c9
- assert response.status == 200
+ response.raise_for_status()
@@ 11c11
- assert data["message"] == "OK"
+ assert data.get("message") == "OK"(docs.aiohttp.org, brightdata.com)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async with ClientSession() as session: | |
| async with session.get(f"{running_server.base_url}/health") as response: | |
| assert response.status == 200 | |
| data = await response.json() | |
| assert data["message"] == "OK" | |
| from aiohttp import ClientSession, ClientTimeout | |
| async with ClientSession(timeout=ClientTimeout(total=10)) as session: | |
| async with session.get(f"{running_server.base_url}/health") as response: | |
| response.raise_for_status() | |
| data = await response.json() | |
| assert data.get("message") == "OK" |
🤖 Prompt for AI Agents
In integration-tests/test_health.py around lines 7–11, the health-check request
can hang and lacks fail-fast behavior; create an aiohttp.ClientTimeout with
total=10 and pass it to ClientSession (or to session.get) to cap the request at
10 seconds, and call response.raise_for_status() after receiving the response
and before reading JSON so non-2xx responses raise immediately instead of
silently asserting later.
No description provided.