Performance Testing Framework for OSDU Services - A comprehensive tool for testing OSDU APIs with Locust and Azure Load Testing SDK
Project description
๐ฅ OSDU Performance Testing Framework
A comprehensive Python framework for performance testing OSDU (Open Subsurface Data Universe) services. Features automatic test discovery, Azure authentication, Locust integration, and both local and cloud-based load testing capabilities with intelligent service orchestration.
๐ Key Features
โ
Service Orchestration - Intelligent service discovery and execution management
โ
Azure Authentication - Seamless Azure AD token management with multiple credential flows
โ
Dual Execution Modes - Run locally with Locust or scale with Azure Load Testing
โ
CLI Tools - Comprehensive command-line interface with three main commands
โ
Template System - Pre-built templates for common OSDU services
โ
Configuration Management - YAML-based configuration with environment-aware settings
โ
Metrics Collection - Automated metrics push to Azure Data Explorer (Kusto)
โ
Environment Detection - Automatically adapts behavior for local vs Azure environments
๐๏ธ Framework Architecture
Core Components
PerformanceUser: Locust integration with automatic service discoveryServiceOrchestrator: Plugin architecture for test discovery and executionBaseService: Abstract base class for implementing performance testsInputHandler: Configuration management and environment detectionAzureTokenManager: Multi-credential authentication system
๐ Quick Start
Installation
# Install from PyPI
pip install osdu_perf
Three Simple Commands
The framework provides three main commands for the complete performance testing workflow:
1. Initialize Project (init)
# Create a new performance testing project
osdu_perf init <service_name>
# Examples:
osdu_perf init storage # Creates storage service performance tests
osdu_perf init search # Creates search service performance tests
osdu_perf init wellbore # Creates wellbore service performance tests
What this creates:
perf_tests/
โโโ config.yaml # Framework configuration
โโโ locustfile.py # Main test file with API calls
โโโ requirements.txt # Python dependencies
โโโ README.md # Project documentation
2. Run Local Tests (run local)
# Run performance tests locally using Locust
osdu_perf run local --config config.yaml
Features:
- Uses Locust for load generation
- Azure CLI authentication for local development
- Real-time web UI at http://localhost:8089
- Automatic service discovery and execution
- Automatic metric collection and sends to Kusto
3. Run Azure Load Tests (run azure_load_test)
# Deploy and run tests on Azure Load Testing service
osdu_perf run azure_load_test --config config.yaml
Features:
- Creates Azure Load Testing resources automatically
- Scales to hundreds/thousands of concurrent users
- Managed Identity authentication in Azure
- Comprehensive metrics and reporting
- Entitlement will be created on ADME for azure load tests
๐ ๏ธ Command Reference
1. Initialize Command
osdu_perf init <service_name> [OPTIONS]
Parameters:
service_name: Name of the OSDU service to test (e.g., storage, search, wellbore)--force: Force overwrite existing files without prompting
Examples:
osdu_perf init storage # Initialize storage service tests
osdu_perf init search --force # Force overwrite existing search tests
osdu_perf init wellbore # Initialize wellbore service tests
Generated Files:
config.yaml- Framework configuration with OSDU connection detailslocustfile.py- Main test file with API calls to your servicerequirements.txt- Python dependenciesREADME.md- Project-specific documentation
2. Local Testing Command
osdu_perf run local [OPTIONS]
Configuration:
- Uses
config.yamlfor base configuration - CLI arguments override config file settings
- Environment variables provide runtime values
Key Options:
--config: Path to config.yaml file (required)--host: OSDU host URL (overrides config)--partition: OSDU data partition ID (overrides config)--app-id: Azure AD Application ID (overrides config)--users(-u): Number of concurrent users (default: from config)--spawn-rate(-r): User spawn rate per second (default: from config)--run-time(-t): Test duration (default: from config)
Examples:
# Basic run using config.yaml
osdu_perf run local --config config.yaml
# Override specific settings
osdu_perf run local --config config.yaml --users 50 --run-time 5m
# Full override
osdu_perf run local \
--config config.yaml \
--host https://api.example.com \
--partition dp1 \
--app-id 12345678-1234-1234-1234-123456789abc \
--users 25 --spawn-rate 5
3. Azure Load Testing Command
osdu_perf run azure_load_test [OPTIONS]
Required Parameters:
--config: Path to config.yaml file
Optional Parameters:
--loadtest-name: Azure Load Testing resource name (auto-generated)--test-name: Test name (auto-generated with timestamp)--engine-instances: Number of load generator instances (default: from config)--users(-u): Number of concurrent users per instance (default: from config)--run-time(-t): Test duration (default: from config)
Examples:
# Basic Azure Load Test using config
osdu_perf run azure \
--config config.yaml \
--subscription-id "12345678-1234-1234-1234-123456789012" \
--resource-group "myResourceGroup" \
--location "eastus"
# High-scale cloud test
osdu_perf run azure \
--config config.yaml \
--subscription-id "12345678-1234-1234-1234-123456789012" \
--resource-group "myResourceGroup" \
--location "eastus" \
--users 100 --engine-instances 5 --run-time 30m
๐ Configuration System
config.yaml Structure
The framework uses a centralized configuration file that supports both local and Azure environments:
# OSDU Environment Configuration
osdu_environment:
# OSDU instance details (required for run local command)
host: "https://your-osdu-host.com"
partition: "your-partition-id"
app_id: "your-azure-app-id"
# OSDU deployment details (optional - used for metrics collection)
sku: "Standard"
version: "25.2.35"
# Authentication (optional - uses automatic token generation if not provided)
auth:
# Manual token override (optional)
token: ""
# Metrics Collection Configuration
metrics_collector:
# Kusto (Azure Data Explorer) Configuration
kusto:
cluster: "https://your-kusto-cluster.eastus.kusto.windows.net"
database: "your-database"
ingest_uri: "https://ingest-your-kusto.eastus.kusto.windows.net"
# Test Configuration (Optional)
test_settings:
# Azure Load Test resource and test locations
subscription_id: "your-azure-subscription-id"
resource_group: "your-resource-group"
location: "eastus"
# Test-specific configurations
default_wait_time:
min: 1
max: 3
users: 10
spawn_rate: 2
run_time: "60s"
engine_instances: 1
test_name_prefix: "osdu_perf_test"
test_scenario: "health_check"
test_run_id_description: "Automated performance test"
Configuration Hierarchy
The framework uses a layered configuration approach:
- config.yaml (project-specific settings)
- CLI arguments (highest priority)
๐๏ธ How It Works
๐ Simple API-Based Approach
The framework now uses a simplified API-based approach where developers write test methods directly in locustfile.py:
perf_tests/
โโโ locustfile.py โ OSDUUser class with @task methods for testing
โโโ config.yaml โ Configuration for host, partition, authentication
โโโ requirements.txt โ Dependencies (osdu_perf package)
Simplified Process:
osdu_perf init <service>generateslocustfile.pytemplate- Developers add
@taskmethods with API calls (self.get(),self.post(), etc.) PerformanceUserbase class handles authentication, headers, tokens automatically- Run with
osdu_perf run localorosdu_perf run azure_load_test
๐ฏ Smart Resource Naming
Based on detected services, Azure resources are automatically named:
- Load Test Resource:
osdu-{service}-loadtest-{timestamp} - Test Name:
osdu_{service}_test_{timestamp} - Example:
osdu-storage-loadtest-20241028with testosdu_storage_test_20241028_142250
๐ Multi-Environment Authentication
Local Development:
- Azure CLI credentials (
az login) - Manual token via config or environment variables
- Automatic token refresh and caching
Azure Load Testing:
- Managed Identity authentication (no secrets needed)
- Environment variables injected by Azure Load Testing service
- Automatic credential detection and fallback
๐ Intelligent Metrics Collection
Automatic Kusto Integration:
- Detects environment (local vs Azure) automatically
- Uses appropriate authentication method
- Pushes detailed metrics to three tables:
LocustMetrics- Per-endpoint statisticsLocustExceptions- Error trackingLocustTestSummary- Overall test summaries
๐งช Writing Performance Tests
Simple API-Based Approach
The framework generate your locustfile.py:
"""
OSDU Performance Tests - Locust Configuration
Generated by OSDU Performance Testing Framework
"""
import os
from locust import events, task, tag
from osdu_perf import PerformanceUser
# STEP 1: Register custom CLI args with Locust
@events.init_command_line_parser.add_listener
def add_custom_args(parser):
"""Add OSDU-specific command line arguments"""
parser.add_argument("--partition", type=str, default=os.getenv("PARTITION"), help="OSDU Data Partition ID")
parser.add_argument("--appid", type=str, default=os.getenv("APPID"), help="Azure AD Application ID")
class OSDUUser(PerformanceUser):
"""
OSDU Performance Test User
This class automatically:
- Handles Azure authentication using --appid
- Manages HTTP headers and tokens
- Provides simple API methods for testing
- Manages Locust user simulation and load testing
"""
def on_start(self):
"""Called when a user starts - performs setup"""
super().on_start()
# Access OSDU parameters from Locust parsed options or environment variables
partition = getattr(self.environment.parsed_options, 'partition', None) or os.getenv('PARTITION')
host = getattr(self.environment.parsed_options, 'host', None) or self.host or os.getenv('HOST')
token = os.getenv('ADME_BEARER_TOKEN') # Token only from environment for security
appid = getattr(self.environment.parsed_options, 'appid', None) or os.getenv('APPID')
print(f"๏ฟฝ Started performance testing user")
print(f" ๐ Partition: {partition}")
print(f" ๐ Host: {host}")
print(f" ๐ Token: {'***' if token else 'Not provided'}")
print(f" ๐ App ID: {appid or 'Not provided'}")
@tag("storage", "health_check")
@task(1)
def check_service_health(self):
# Simple API call - framework handles headers, tokens, authentication
self.get("/api/storage/v2/health")
@tag("storage", "health_check")
@task(2)
def test_service_endpoints(self):
# More API calls for your service
self.get("/api/storage/v2/info")
self.post("/api/storage/v2/records", json={"test": "data"})
Key Implementation Points
- Inherit from PerformanceUser: Your class extends
PerformanceUserwhich handles all authentication and setup - Use @task decorators: Mark methods with
@task(weight)to define test scenarios - Simple HTTP methods: Use
self.get(),self.post(),self.put(),self.delete()- framework handles headers/tokens - No manual authentication: Framework automatically handles Azure AD tokens and HTTP headers
- Environment awareness: Automatically adapts for local vs Azure Load Testing environments
Available HTTP Methods
The PerformanceUser base class provides these simple methods:
# GET request
self.get("/api/storage/v2/records/12345")
# POST request with JSON data
self.post("/api/storage/v2/records", json={
"kind": "osdu:wks:partition:storage:1.0.0",
"data": {"test": "data"}
})
# PUT request
self.put("/api/storage/v2/records/12345", json=updated_data)
# DELETE request
self.delete("/api/storage/v2/records/12345")
# Custom headers (if needed)
self.get("/api/storage/v2/info", headers={"Custom-Header": "value"})
# Also locust client available
self.client.get("/api/storage/v2/records/12345")
Authentication Handling
The framework automatically manages authentication:
- Local Development: Uses Azure CLI credentials (
az login) - Azure Load Testing: Uses Managed Identity
- Manual Override: Set
ADME_BEARER_TOKENenvironment variable - All requests: Automatically include proper Authorization headers
๐ง Configuration & Environment Variables
Configuration Hierarchy
The framework uses a layered configuration approach (highest priority first):
- CLI arguments - Direct command-line overrides
- Environment variables - Runtime values
- config.yaml - Project-specific settings
- Default values - Framework defaults
Environment Variables
Universal Variables:
OSDU_HOST: Base URL of OSDU instanceOSDU_PARTITION: Data partition IDOSDU_APP_ID: Azure AD Application IDADME_BEARER_TOKEN: Manual bearer token override
Azure Load Testing Variables (auto-set):
AZURE_LOAD_TEST=true: Indicates Azure environmentPARTITION: Data partition IDLOCUST_HOST: OSDU host URLAPPID: Azure AD Application ID
Metrics Collection:
KUSTO_CLUSTER: Azure Data Explorer cluster URLKUSTO_DATABASE: Database name for metricsTEST_RUN_ID: Unique identifier for test run
Azure Authentication
The framework supports multiple Azure authentication methods with automatic detection:
Local Development:
- Azure CLI credentials (
az login) - Service Principal (via environment variables)
- DefaultAzureCredential chain
Azure Environments:
- Managed Identity (preferred for Azure-hosted resources)
- System-assigned or user-assigned identities
- Automatic credential detection and fallback
๐ Monitoring & Results
Local Testing (Web UI)
- Open http://localhost:8089 after starting with
--web-ui - Real-time performance metrics
- Request statistics and response times
- Download results as CSV
Azure Load Testing
- Monitor in Azure Portal under "Load Testing"
- Comprehensive dashboards and metrics
- Automated result retention
- Integration with Azure Monitor
Key Metrics
- Requests per second (RPS)
- Average response time
- 95th percentile response time
- Error rate
- Failure count by endpoint
๐ Advanced Usage
Multiple Services
Test multiple services by adding more @task methods in your locustfile.py:
class OSDUUser(PerformanceUser):
@task(3) # Higher weight = more frequent execution
def test_storage_apis(self):
self.get("/api/storage/v2/info")
self.post("/api/storage/v2/records", json={"data": "test"})
@task(2)
def test_search_apis(self):
self.get("/api/search/v2/query")
self.post("/api/search/v2/query", json={"query": "*"})
@task(1)
def test_schema_apis(self):
self.get("/api/schema-service/v1/schema")
All tests run in the same locustfile.py with automatic load balancing based on task weights.
CI/CD Integration
# Example GitHub Actions workflow
- name: Run OSDU Performance Tests
run: |
osdu_perf run local \
--host ${{ secrets.OSDU_HOST }} \
--partition ${{ secrets.OSDU_PARTITION }} \
--token ${{ secrets.OSDU_TOKEN }} \
--headless \
--users 5 \
--run-time 2m
๐ Troubleshooting
Common Issues
Authentication Errors
# Ensure Azure CLI is logged in
az login
Import Errors
# Install dependencies
pip install -r requirements.txt
Service Discovery Issues
# Ensure locustfile.py exists and inherits from PerformanceUser
ls locustfile.py
# Check class inheritance
grep "PerformanceUser" locustfile.py
Azure Load Testing Errors
# Install Azure dependencies
pip install azure-cli azure-identity azure-mgmt-loadtesting azure-mgmt-resource requests
๐งฉ Project Structure (Generated)
perf_tests/
โโโ locustfile.py # Main test file with API calls and @task methods
โโโ config.yaml # Framework configuration (OSDU, metrics, test settings)
โโโ requirements.txt # Python dependencies (osdu_perf package)
โโโ README.md # Project documentation
๐งช Development
Running Tests
pytest tests/
Code Quality
# Formatting
black osdu_perf/
# Linting
flake8 osdu_perf/
Building Package
# Build wheel and source distribution
python -m build
# Upload to TestPyPI
python -m twine upload --repository testpypi dist/*
๐ License
This project is licensed under the MIT License โ see the LICENSE file for details.
๐ Support
- Issues: GitHub Issues
- Contact: janrajcj@microsoft.com
- Documentation: This README and inline code documentation
๐ What's New in v1.0.24
- โ
Three-Command Workflow:
init,run local,run azure- complete testing pipeline - โ Configuration-Driven: YAML-based configuration with environment-aware settings
- โ Service Orchestration: Intelligent service discovery with lifecycle management
- โ Enhanced Authentication: Multi-credential Azure authentication with automatic detection
- โ Metrics Integration: Automated Kusto metrics collection with environment detection
- โ Template System: Updated project templates with modern framework patterns
- โ Error Handling: Improved error handling and defensive coding patterns
- โ CLI Improvements: Better argument parsing and validation
Generated by OSDU Performance Testing Framework v1.0.24
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file osdu_perf-1.0.30.tar.gz.
File metadata
- Download URL: osdu_perf-1.0.30.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ea48e79abc9c16dc31be6853571dc749606219bc4df5f18d6207f391d9783d4
|
|
| MD5 |
4180045d80054ad58a358d03b5cede31
|
|
| BLAKE2b-256 |
fd1b188b7698d5c8cb1ed1acb4e6426917e3b1ced95d397d241bc073b97abc88
|
File details
Details for the file osdu_perf-1.0.30-py3-none-any.whl.
File metadata
- Download URL: osdu_perf-1.0.30-py3-none-any.whl
- Upload date:
- Size: 67.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
73e4093d251e3c7f78a0645fc058efc32f9a6d7056b360a8efc4da8f5cd71f3e
|
|
| MD5 |
dcb293fb62c6923f5605c9e3d32466bf
|
|
| BLAKE2b-256 |
2ea9cf98d861de616f0c8418ef07aa5a24797ff5da0774db287c52bb6ad2bce5
|