Files
openobserve/tests/db-testing/README.md
T
Subhra264 0d956ebdde test: Add tests to directly validate db records (#9356)
pytest to directly access db, and validate test cases using db queries.
2025-11-28 17:20:10 +05:30

181 lines
4.9 KiB
Markdown

# Database Validation Tests
This directory contains database validation tests for OpenObserve. These tests ingest data via the API and then validate the database state by directly querying the metadata database.
## Purpose
These tests are separate from:
- **Rust integration tests** (`tests/integration_test.rs`) - To avoid increasing PR CI time
- **API tests** (`tests/api-testing/`) - Different concern: DB state validation vs API endpoint testing
## Structure
```
tests/db-testing/
├── README.md # This file
├── pyproject.toml # Python project configuration (auto-generated in CI)
├── requirements.lock # Locked dependencies (managed by rye)
└── tests/
├── conftest.py # Pytest fixtures and configuration
└── test_*.py # Test files
```
## Dependencies
- `pytest` - Test framework
- `requests` - HTTP client for API calls
- `psycopg2-binary` - PostgreSQL database driver
- `python-dotenv` - Environment variable management
## Running Tests Locally
### Prerequisites
1. Install [rye](https://rye-up.com/):
```bash
curl -sSf https://rye.astral.sh/get | bash
```
2. Build OpenObserve:
```bash
cargo build --features mimalloc
```
3. Start a PostgreSQL instance:
```bash
docker run -d \
--name postgres-test \
-e POSTGRES_PASSWORD=password \
-p 5432:5432 \
postgres:17.5-alpine3.22
```
### Run Tests
1. Start OpenObserve with Postgres backend:
```bash
export ZO_META_STORE=postgres
export ZO_META_POSTGRES_DSN=postgres://postgres:password@localhost:5432/postgres
export ZO_ROOT_USER_EMAIL=root@example.com
export ZO_ROOT_USER_PASSWORD=Complexpass#123
target/debug/openobserve
```
2. In another terminal, run the tests:
```bash
cd tests/db-testing
rye sync # Install dependencies
rye run pytest -v
```
## Writing Tests
### Test Structure
Each test should follow this pattern:
1. **Ingest data** via the OpenObserve API
2. **Query the database** directly to validate state
3. **Assert** that the database state matches expectations
### Example Test
```python
def test_my_validation(ingest_test_data, db_cursor, test_org, test_stream):
"""Test description."""
# 1. Ingest test data
test_data = [{"timestamp": "...", "field": "value"}]
ingest_test_data(test_data)
# 2. Query database
db_cursor.execute("""
SELECT * FROM meta
WHERE org_id = %s
AND key2 = %s
""", (test_org, test_stream))
results = db_cursor.fetchall()
# 3. Validate
assert len(results) > 0, "Expected data not found"
```
### Available Fixtures
- `db_connection` - PostgreSQL connection (session-scoped)
- `db_cursor` - Database cursor for queries
- `ingest_test_data` - Function to ingest data via API
- `query_api` - Function to query OpenObserve search API
- `openobserve_base_url` - OpenObserve API base URL
- `auth_credentials` - Authentication credentials tuple
- `test_org` - Test organization name (default: "default")
- `test_stream` - Test stream name (default: "db_test_stream")
## CI Integration
Tests run automatically in the `db-testing.yml` GitHub Actions workflow on:
- Push to `main` branch
- Pull requests to any branch
The workflow:
1. Starts a PostgreSQL service
2. Builds OpenObserve
3. Configures OpenObserve to use Postgres
4. Runs pytest tests
5. Uploads logs on failure
## Database Schema Reference
The `meta` table structure (adjust based on your actual schema):
```sql
CREATE TABLE meta (
id SERIAL PRIMARY KEY,
org_id VARCHAR(100),
module VARCHAR(100),
key1 VARCHAR(256),
key2 VARCHAR(256),
start_dt BIGINT,
value TEXT,
-- ... other columns
);
```
Common modules:
- `schema` - Stream schemas
- `stream_settings` - Stream configuration
- `file_list` - File metadata
- `organization` - Organization settings
- `user` - User data
## Tips
1. **Use transactions** in tests when you need to clean up (though fixtures handle most cleanup)
2. **Wait for ingestion** - Data ingestion is async, use `wait_for_ingestion()` helper
3. **Print debug info** - Use `print()` statements to debug queries during development
4. **Test isolation** - Each test should be independent and not rely on other tests
5. **Database state** - Tests query a shared database; use unique stream names if needed
## Troubleshooting
### Tests fail with "connection refused"
- Ensure PostgreSQL is running and accessible
- Check `ZO_META_POSTGRES_DSN` environment variable
### Tests fail with "table not found"
- OpenObserve may not have initialized the database schema
- Check OpenObserve logs for migration errors
### Tests timeout
- Increase wait times in `wait_for_ingestion()`
- Check if OpenObserve is running and healthy
## Future Enhancements
- [ ] Add SQLite backend testing
- [ ] Add tests for data compaction
- [ ] Add tests for schema evolution
- [ ] Add tests for multi-tenancy
- [ ] Add performance/load tests
- [ ] Add tests for backup/restore operations