mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
181 lines
4.9 KiB
Markdown
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
|