osdu-perf


Nameosdu-perf JSON
Version 1.0.28.2 PyPI version JSON
download
home_pagehttps://github.com/janraj/osdu_perf
SummaryPerformance Testing Framework for OSDU Services - A comprehensive tool for testing OSDU APIs with Locust and Azure Load Testing SDK
upload_time2025-11-12 02:36:48
maintainerNone
docs_urlNone
authorJanraj CJ
requires_python>=3.8
licenseNone
keywords performance testing locust azure osdu load-testing azure-sdk performance-testing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ๐Ÿ”ฅ OSDU Performance Testing Framework

[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI version](https://img.shields.io/pypi/v/osdu-perf.svg)](https://pypi.org/project/osdu-perf/)

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 discovery
- **`ServiceOrchestrator`**: Plugin architecture for test discovery and execution
- **`BaseService`**: Abstract base class for implementing performance tests
- **`InputHandler`**: Configuration management and environment detection
- **`AzureTokenManager`**: Multi-credential authentication system  

## ๐Ÿš€ Quick Start

### Installation

```bash
# 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`)

```bash
# 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`)

```bash
# 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`)

```bash
# 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

```bash
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:**
```bash
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 details
- `locustfile.py` - Main test file with API calls to your service
- `requirements.txt` - Python dependencies
- `README.md` - Project-specific documentation

### 2. Local Testing Command

```bash
osdu_perf run local [OPTIONS]
```

**Configuration:**
- Uses `config.yaml` for 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:**
```bash
# 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

```bash
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:**
```bash
# 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:

```yaml
# 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:

1. **config.yaml** (project-specific settings)
2. **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:**
1. `osdu_perf init <service>` generates `locustfile.py` template
2. Developers add `@task` methods with API calls (`self.get()`, `self.post()`, etc.)
3. `PerformanceUser` base class handles authentication, headers, tokens automatically
4. Run with `osdu_perf run local` or `osdu_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-20241028` with test `osdu_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 statistics
  - `LocustExceptions` - Error tracking
  - `LocustTestSummary` - Overall test summaries

## ๐Ÿงช Writing Performance Tests

### Simple API-Based Approach

The framework generate your `locustfile.py`:

```python
"""
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

1. **Inherit from PerformanceUser**: Your class extends `PerformanceUser` which handles all authentication and setup
2. **Use @task decorators**: Mark methods with `@task(weight)` to define test scenarios
3. **Simple HTTP methods**: Use `self.get()`, `self.post()`, `self.put()`, `self.delete()` - framework handles headers/tokens
4. **No manual authentication**: Framework automatically handles Azure AD tokens and HTTP headers
5. **Environment awareness**: Automatically adapts for local vs Azure Load Testing environments

### Available HTTP Methods

The `PerformanceUser` base class provides these simple methods:

```python
# 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_TOKEN` environment variable
- **All requests**: Automatically include proper Authorization headers

## ๐Ÿ”ง Configuration & Environment Variables

### Configuration Hierarchy

The framework uses a layered configuration approach (highest priority first):

1. **CLI arguments** - Direct command-line overrides
2. **Environment variables** - Runtime values  
3. **config.yaml** - Project-specific settings
4. **Default values** - Framework defaults

### Environment Variables

**Universal Variables:**
- `OSDU_HOST`: Base URL of OSDU instance
- `OSDU_PARTITION`: Data partition ID
- `OSDU_APP_ID`: Azure AD Application ID
- `ADME_BEARER_TOKEN`: Manual bearer token override

**Azure Load Testing Variables (auto-set):**
- `AZURE_LOAD_TEST=true`: Indicates Azure environment
- `PARTITION`: Data partition ID
- `LOCUST_HOST`: OSDU host URL
- `APPID`: Azure AD Application ID

**Metrics Collection:**
- `KUSTO_CLUSTER`: Azure Data Explorer cluster URL
- `KUSTO_DATABASE`: Database name for metrics
- `TEST_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`:

```python
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

```yaml
# 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**
```bash
# Ensure Azure CLI is logged in
az login

```

**Import Errors**
```bash
# Install dependencies
pip install -r requirements.txt
```

**Service Discovery Issues**
```bash
# Ensure locustfile.py exists and inherits from PerformanceUser
ls locustfile.py

# Check class inheritance
grep "PerformanceUser" locustfile.py
```

**Azure Load Testing Errors**
```bash
# 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
```bash
pytest tests/
```

### Code Quality
```bash
# Formatting
black osdu_perf/

# Linting  
flake8 osdu_perf/
```

### Building Package
```bash
# 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](https://github.com/janraj/osdu_perf/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**


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/janraj/osdu_perf",
    "name": "osdu-perf",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Janraj CJ <janrajcj@microsoft.com>",
    "keywords": "performance, testing, locust, azure, osdu, load-testing, azure-sdk, performance-testing",
    "author": "Janraj CJ",
    "author_email": "Janraj CJ <janrajcj@microsoft.com>",
    "download_url": "https://files.pythonhosted.org/packages/2b/62/81564be84afd1b87191e9cfff42cf514a544923767d26bb08c1508737451/osdu_perf-1.0.28.2.tar.gz",
    "platform": null,
    "description": "# \ud83d\udd25 OSDU Performance Testing Framework\r\n\r\n[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)\r\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\r\n[![PyPI version](https://img.shields.io/pypi/v/osdu-perf.svg)](https://pypi.org/project/osdu-perf/)\r\n\r\nA 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.\r\n\r\n## \ud83d\udccb Key Features\r\n\r\n\u2705 **Service Orchestration** - Intelligent service discovery and execution management  \r\n\u2705 **Azure Authentication** - Seamless Azure AD token management with multiple credential flows  \r\n\u2705 **Dual Execution Modes** - Run locally with Locust or scale with Azure Load Testing  \r\n\u2705 **CLI Tools** - Comprehensive command-line interface with three main commands  \r\n\u2705 **Template System** - Pre-built templates for common OSDU services  \r\n\u2705 **Configuration Management** - YAML-based configuration with environment-aware settings  \r\n\u2705 **Metrics Collection** - Automated metrics push to Azure Data Explorer (Kusto)  \r\n\u2705 **Environment Detection** - Automatically adapts behavior for local vs Azure environments  \r\n\r\n## \ud83c\udfd7\ufe0f Framework Architecture\r\n\r\n### Core Components\r\n- **`PerformanceUser`**: Locust integration with automatic service discovery\r\n- **`ServiceOrchestrator`**: Plugin architecture for test discovery and execution\r\n- **`BaseService`**: Abstract base class for implementing performance tests\r\n- **`InputHandler`**: Configuration management and environment detection\r\n- **`AzureTokenManager`**: Multi-credential authentication system  \r\n\r\n## \ud83d\ude80 Quick Start\r\n\r\n### Installation\r\n\r\n```bash\r\n# Install from PyPI\r\npip install osdu_perf\r\n```\r\n\r\n### Three Simple Commands\r\n\r\nThe framework provides three main commands for the complete performance testing workflow:\r\n\r\n#### 1. Initialize Project (`init`)\r\n\r\n```bash\r\n# Create a new performance testing project\r\nosdu_perf init <service_name>\r\n\r\n# Examples:\r\nosdu_perf init storage     # Creates storage service performance tests\r\nosdu_perf init search      # Creates search service performance tests\r\nosdu_perf init wellbore    # Creates wellbore service performance tests\r\n```\r\n\r\n**What this creates:**\r\n```\r\nperf_tests/\r\n\u251c\u2500\u2500 config.yaml               # Framework configuration\r\n\u251c\u2500\u2500 locustfile.py             # Main test file with API calls\r\n\u251c\u2500\u2500 requirements.txt          # Python dependencies\r\n\u2514\u2500\u2500 README.md                 # Project documentation\r\n```\r\n\r\n#### 2. Run Local Tests (`run local`)\r\n\r\n```bash\r\n# Run performance tests locally using Locust\r\nosdu_perf run local --config config.yaml\r\n\r\n```\r\n\r\n**Features:**\r\n- Uses Locust for load generation\r\n- Azure CLI authentication for local development  \r\n- Real-time web UI at http://localhost:8089\r\n- Automatic service discovery and execution\r\n- Automatic metric collection and sends to Kusto \r\n\r\n#### 3. Run Azure Load Tests (`run azure_load_test`)\r\n\r\n```bash\r\n# Deploy and run tests on Azure Load Testing service\r\nosdu_perf run azure_load_test --config config.yaml \r\n```\r\n\r\n**Features:**\r\n- Creates Azure Load Testing resources automatically\r\n- Scales to hundreds/thousands of concurrent users\r\n- Managed Identity authentication in Azure\r\n- Comprehensive metrics and reporting\r\n- Entitlement will be created on ADME for azure load tests \r\n\r\n## \ud83d\udee0\ufe0f Command Reference\r\n\r\n### 1. Initialize Command\r\n\r\n```bash\r\nosdu_perf init <service_name> [OPTIONS]\r\n```\r\n\r\n**Parameters:**\r\n- `service_name`: Name of the OSDU service to test (e.g., storage, search, wellbore)\r\n- `--force`: Force overwrite existing files without prompting\r\n\r\n**Examples:**\r\n```bash\r\nosdu_perf init storage              # Initialize storage service tests\r\nosdu_perf init search --force       # Force overwrite existing search tests\r\nosdu_perf init wellbore            # Initialize wellbore service tests\r\n```\r\n\r\n**Generated Files:**\r\n- `config.yaml` - Framework configuration with OSDU connection details\r\n- `locustfile.py` - Main test file with API calls to your service\r\n- `requirements.txt` - Python dependencies\r\n- `README.md` - Project-specific documentation\r\n\r\n### 2. Local Testing Command\r\n\r\n```bash\r\nosdu_perf run local [OPTIONS]\r\n```\r\n\r\n**Configuration:**\r\n- Uses `config.yaml` for base configuration\r\n- CLI arguments override config file settings\r\n- Environment variables provide runtime values\r\n\r\n**Key Options:**\r\n- `--config`: Path to config.yaml file (required)\r\n- `--host`: OSDU host URL (overrides config)\r\n- `--partition`: OSDU data partition ID (overrides config)  \r\n- `--app-id`: Azure AD Application ID (overrides config)\r\n- `--users` (`-u`): Number of concurrent users (default: from config)\r\n- `--spawn-rate` (`-r`): User spawn rate per second (default: from config)\r\n- `--run-time` (`-t`): Test duration (default: from config)\r\n\r\n**Examples:**\r\n```bash\r\n# Basic run using config.yaml\r\nosdu_perf run local --config config.yaml\r\n\r\n# Override specific settings\r\nosdu_perf run local --config config.yaml --users 50 --run-time 5m\r\n\r\n# Full override\r\nosdu_perf run local \\\r\n  --config config.yaml \\\r\n  --host https://api.example.com \\\r\n  --partition dp1 \\\r\n  --app-id 12345678-1234-1234-1234-123456789abc \\\r\n  --users 25 --spawn-rate 5\r\n```\r\n\r\n### 3. Azure Load Testing Command\r\n\r\n```bash\r\nosdu_perf run azure_load_test [OPTIONS]\r\n```\r\n\r\n**Required Parameters:**\r\n- `--config`: Path to config.yaml file\r\n\r\n\r\n**Optional Parameters:**\r\n- `--loadtest-name`: Azure Load Testing resource name (auto-generated)\r\n- `--test-name`: Test name (auto-generated with timestamp)\r\n- `--engine-instances`: Number of load generator instances (default: from config)\r\n- `--users` (`-u`): Number of concurrent users per instance (default: from config)\r\n- `--run-time` (`-t`): Test duration (default: from config)\r\n\r\n**Examples:**\r\n```bash\r\n# Basic Azure Load Test using config\r\nosdu_perf run azure \\\r\n  --config config.yaml \\\r\n  --subscription-id \"12345678-1234-1234-1234-123456789012\" \\\r\n  --resource-group \"myResourceGroup\" \\\r\n  --location \"eastus\"\r\n\r\n# High-scale cloud test\r\nosdu_perf run azure \\\r\n  --config config.yaml \\\r\n  --subscription-id \"12345678-1234-1234-1234-123456789012\" \\\r\n  --resource-group \"myResourceGroup\" \\\r\n  --location \"eastus\" \\\r\n  --users 100 --engine-instances 5 --run-time 30m\r\n```\r\n\r\n## \ud83d\udcdd Configuration System\r\n\r\n### config.yaml Structure\r\n\r\nThe framework uses a centralized configuration file that supports both local and Azure environments:\r\n\r\n```yaml\r\n# OSDU Environment Configuration\r\nosdu_environment:\r\n  # OSDU instance details (required for run local command)\r\n  host: \"https://your-osdu-host.com\"\r\n  partition: \"your-partition-id\"\r\n  app_id: \"your-azure-app-id\"\r\n  \r\n  # OSDU deployment details (optional - used for metrics collection)\r\n  sku: \"Standard\"\r\n  version: \"25.2.35\"\r\n  \r\n  # Authentication (optional - uses automatic token generation if not provided)\r\n  auth:\r\n    # Manual token override (optional)\r\n    token: \"\"\r\n\r\n# Metrics Collection Configuration  \r\nmetrics_collector:\r\n  # Kusto (Azure Data Explorer) Configuration\r\n  kusto:\r\n    cluster: \"https://your-kusto-cluster.eastus.kusto.windows.net\"\r\n    database: \"your-database\"\r\n    ingest_uri: \"https://ingest-your-kusto.eastus.kusto.windows.net\"\r\n\r\n# Test Configuration (Optional)\r\ntest_settings:\r\n  # Azure Load Test resource and test locations\r\n  subscription_id: \"your-azure-subscription-id\"\r\n  resource_group: \"your-resource-group\"\r\n  location: \"eastus\"\r\n  \r\n  # Test-specific configurations\r\n  default_wait_time: \r\n    min: 1\r\n    max: 3\r\n  users: 10\r\n  spawn_rate: 2\r\n  run_time: \"60s\"\r\n  engine_instances: 1\r\n  test_name_prefix: \"osdu_perf_test\"\r\n  test_scenario: \"health_check\"\r\n  test_run_id_description: \"Automated performance test\"\r\n```\r\n\r\n### Configuration Hierarchy\r\n\r\nThe framework uses a layered configuration approach:\r\n\r\n1. **config.yaml** (project-specific settings)\r\n2. **CLI arguments** (highest priority)\r\n\r\n\r\n## \ud83c\udfd7\ufe0f How It Works\r\n\r\n### \ud83d\udd0d Simple API-Based Approach\r\n\r\nThe framework now uses a simplified API-based approach where developers write test methods directly in `locustfile.py`:\r\n\r\n```\r\nperf_tests/\r\n\u251c\u2500\u2500 locustfile.py            \u2192 OSDUUser class with @task methods for testing\r\n\u251c\u2500\u2500 config.yaml              \u2192 Configuration for host, partition, authentication  \r\n\u251c\u2500\u2500 requirements.txt         \u2192 Dependencies (osdu_perf package)\r\n```\r\n\r\n**Simplified Process:**\r\n1. `osdu_perf init <service>` generates `locustfile.py` template\r\n2. Developers add `@task` methods with API calls (`self.get()`, `self.post()`, etc.)\r\n3. `PerformanceUser` base class handles authentication, headers, tokens automatically\r\n4. Run with `osdu_perf run local` or `osdu_perf run azure_load_test`\r\n\r\n\r\n### \ud83c\udfaf Smart Resource Naming\r\n\r\nBased on detected services, Azure resources are automatically named:\r\n- **Load Test Resource**: `osdu-{service}-loadtest-{timestamp}`\r\n- **Test Name**: `osdu_{service}_test_{timestamp}`\r\n- **Example**: `osdu-storage-loadtest-20241028` with test `osdu_storage_test_20241028_142250`\r\n\r\n### \ud83d\udd10 Multi-Environment Authentication\r\n\r\n**Local Development:**\r\n- Azure CLI credentials (`az login`)\r\n- Manual token via config or environment variables\r\n- Automatic token refresh and caching\r\n\r\n**Azure Load Testing:**\r\n- Managed Identity authentication (no secrets needed)\r\n- Environment variables injected by Azure Load Testing service\r\n- Automatic credential detection and fallback\r\n\r\n### \ud83d\udcca Intelligent Metrics Collection\r\n\r\n**Automatic Kusto Integration:**\r\n- Detects environment (local vs Azure) automatically\r\n- Uses appropriate authentication method\r\n- Pushes detailed metrics to three tables:\r\n  - `LocustMetrics` - Per-endpoint statistics\r\n  - `LocustExceptions` - Error tracking\r\n  - `LocustTestSummary` - Overall test summaries\r\n\r\n## \ud83e\uddea Writing Performance Tests\r\n\r\n### Simple API-Based Approach\r\n\r\nThe framework generate your `locustfile.py`:\r\n\r\n```python\r\n\"\"\"\r\nOSDU Performance Tests - Locust Configuration\r\nGenerated by OSDU Performance Testing Framework\r\n\"\"\"\r\n\r\nimport os\r\nfrom locust import events, task, tag\r\nfrom osdu_perf import PerformanceUser\r\n\r\n# STEP 1: Register custom CLI args with Locust\r\n@events.init_command_line_parser.add_listener\r\ndef add_custom_args(parser):\r\n    \"\"\"Add OSDU-specific command line arguments\"\"\"\r\n    parser.add_argument(\"--partition\", type=str, default=os.getenv(\"PARTITION\"), help=\"OSDU Data Partition ID\")\r\n    parser.add_argument(\"--appid\", type=str, default=os.getenv(\"APPID\"), help=\"Azure AD Application ID\")\r\n\r\nclass OSDUUser(PerformanceUser):\r\n    \"\"\"\r\n    OSDU Performance Test User\r\n    \r\n    This class automatically:\r\n    - Handles Azure authentication using --appid\r\n    - Manages HTTP headers and tokens\r\n    - Provides simple API methods for testing\r\n    - Manages Locust user simulation and load testing\r\n    \"\"\"\r\n    \r\n    def on_start(self):\r\n        \"\"\"Called when a user starts - performs setup\"\"\"\r\n        super().on_start()\r\n        \r\n        # Access OSDU parameters from Locust parsed options or environment variables\r\n        partition = getattr(self.environment.parsed_options, 'partition', None) or os.getenv('PARTITION')\r\n        host = getattr(self.environment.parsed_options, 'host', None) or self.host or os.getenv('HOST')\r\n        token = os.getenv('ADME_BEARER_TOKEN')  # Token only from environment for security\r\n        appid = getattr(self.environment.parsed_options, 'appid', None) or os.getenv('APPID')\r\n        \r\n        print(f\"\ufffd Started performance testing user\")\r\n        print(f\"   \ud83d\udccd Partition: {partition}\")\r\n        print(f\"   \ud83c\udf10 Host: {host}\")\r\n        print(f\"   \ud83d\udd11 Token: {'***' if token else 'Not provided'}\")\r\n        print(f\"   \ud83c\udd94 App ID: {appid or 'Not provided'}\")\r\n    \r\n    @tag(\"storage\", \"health_check\")\r\n    @task(1)\r\n    def check_service_health(self):\r\n        # Simple API call - framework handles headers, tokens, authentication\r\n        self.get(\"/api/storage/v2/health\")\r\n    \r\n    @tag(\"storage\", \"health_check\")\r\n    @task(2)\r\n    def test_service_endpoints(self):\r\n        # More API calls for your service\r\n        self.get(\"/api/storage/v2/info\")\r\n        self.post(\"/api/storage/v2/records\", json={\"test\": \"data\"})\r\n```\r\n\r\n### Key Implementation Points\r\n\r\n1. **Inherit from PerformanceUser**: Your class extends `PerformanceUser` which handles all authentication and setup\r\n2. **Use @task decorators**: Mark methods with `@task(weight)` to define test scenarios\r\n3. **Simple HTTP methods**: Use `self.get()`, `self.post()`, `self.put()`, `self.delete()` - framework handles headers/tokens\r\n4. **No manual authentication**: Framework automatically handles Azure AD tokens and HTTP headers\r\n5. **Environment awareness**: Automatically adapts for local vs Azure Load Testing environments\r\n\r\n### Available HTTP Methods\r\n\r\nThe `PerformanceUser` base class provides these simple methods:\r\n\r\n```python\r\n# GET request\r\nself.get(\"/api/storage/v2/records/12345\")\r\n\r\n# POST request with JSON data\r\nself.post(\"/api/storage/v2/records\", json={\r\n    \"kind\": \"osdu:wks:partition:storage:1.0.0\",\r\n    \"data\": {\"test\": \"data\"}\r\n})\r\n\r\n# PUT request\r\nself.put(\"/api/storage/v2/records/12345\", json=updated_data)\r\n\r\n# DELETE request  \r\nself.delete(\"/api/storage/v2/records/12345\")\r\n\r\n# Custom headers (if needed)\r\nself.get(\"/api/storage/v2/info\", headers={\"Custom-Header\": \"value\"})\r\n\r\n# Also locust client available \r\n\r\nself.client.get(\"/api/storage/v2/records/12345\")\r\n```\r\n\r\n### Authentication Handling\r\n\r\nThe framework automatically manages authentication:\r\n\r\n- **Local Development**: Uses Azure CLI credentials (`az login`)\r\n- **Azure Load Testing**: Uses Managed Identity  \r\n- **Manual Override**: Set `ADME_BEARER_TOKEN` environment variable\r\n- **All requests**: Automatically include proper Authorization headers\r\n\r\n## \ud83d\udd27 Configuration & Environment Variables\r\n\r\n### Configuration Hierarchy\r\n\r\nThe framework uses a layered configuration approach (highest priority first):\r\n\r\n1. **CLI arguments** - Direct command-line overrides\r\n2. **Environment variables** - Runtime values  \r\n3. **config.yaml** - Project-specific settings\r\n4. **Default values** - Framework defaults\r\n\r\n### Environment Variables\r\n\r\n**Universal Variables:**\r\n- `OSDU_HOST`: Base URL of OSDU instance\r\n- `OSDU_PARTITION`: Data partition ID\r\n- `OSDU_APP_ID`: Azure AD Application ID\r\n- `ADME_BEARER_TOKEN`: Manual bearer token override\r\n\r\n**Azure Load Testing Variables (auto-set):**\r\n- `AZURE_LOAD_TEST=true`: Indicates Azure environment\r\n- `PARTITION`: Data partition ID\r\n- `LOCUST_HOST`: OSDU host URL\r\n- `APPID`: Azure AD Application ID\r\n\r\n**Metrics Collection:**\r\n- `KUSTO_CLUSTER`: Azure Data Explorer cluster URL\r\n- `KUSTO_DATABASE`: Database name for metrics\r\n- `TEST_RUN_ID`: Unique identifier for test run\r\n\r\n### Azure Authentication\r\n\r\nThe framework supports multiple Azure authentication methods with automatic detection:\r\n\r\n**Local Development:**\r\n- Azure CLI credentials (`az login`)\r\n- Service Principal (via environment variables)\r\n- DefaultAzureCredential chain\r\n\r\n**Azure Environments:**\r\n- Managed Identity (preferred for Azure-hosted resources)\r\n- System-assigned or user-assigned identities\r\n- Automatic credential detection and fallback\r\n\r\n## \ud83d\udcca Monitoring & Results\r\n\r\n### Local Testing (Web UI)\r\n- Open http://localhost:8089 after starting with `--web-ui`\r\n- Real-time performance metrics\r\n- Request statistics and response times\r\n- Download results as CSV\r\n\r\n### Azure Load Testing\r\n- Monitor in Azure Portal under \"Load Testing\"\r\n- Comprehensive dashboards and metrics\r\n- Automated result retention\r\n- Integration with Azure Monitor\r\n\r\n### Key Metrics\r\n- **Requests per second (RPS)**\r\n- **Average response time**\r\n- **95th percentile response time**  \r\n- **Error rate**\r\n- **Failure count by endpoint**\r\n\r\n## \ud83d\ude80 Advanced Usage\r\n\r\n\r\n### Multiple Services\r\nTest multiple services by adding more `@task` methods in your `locustfile.py`:\r\n\r\n```python\r\nclass OSDUUser(PerformanceUser):\r\n    \r\n    @task(3)  # Higher weight = more frequent execution\r\n    def test_storage_apis(self):\r\n        self.get(\"/api/storage/v2/info\")\r\n        self.post(\"/api/storage/v2/records\", json={\"data\": \"test\"})\r\n    \r\n    @task(2) \r\n    def test_search_apis(self):\r\n        self.get(\"/api/search/v2/query\")\r\n        self.post(\"/api/search/v2/query\", json={\"query\": \"*\"})\r\n    \r\n    @task(1)\r\n    def test_schema_apis(self):\r\n        self.get(\"/api/schema-service/v1/schema\")\r\n```\r\n\r\nAll tests run in the same `locustfile.py` with automatic load balancing based on task weights.\r\n\r\n### CI/CD Integration\r\n\r\n```yaml\r\n# Example GitHub Actions workflow\r\n- name: Run OSDU Performance Tests\r\n  run: |\r\n    osdu_perf run local \\\r\n      --host ${{ secrets.OSDU_HOST }} \\\r\n      --partition ${{ secrets.OSDU_PARTITION }} \\\r\n      --token ${{ secrets.OSDU_TOKEN }} \\\r\n      --headless \\\r\n      --users 5 \\\r\n      --run-time 2m\r\n```\r\n\r\n## \ud83d\udc1b Troubleshooting\r\n\r\n### Common Issues\r\n\r\n**Authentication Errors**\r\n```bash\r\n# Ensure Azure CLI is logged in\r\naz login\r\n\r\n```\r\n\r\n**Import Errors**\r\n```bash\r\n# Install dependencies\r\npip install -r requirements.txt\r\n```\r\n\r\n**Service Discovery Issues**\r\n```bash\r\n# Ensure locustfile.py exists and inherits from PerformanceUser\r\nls locustfile.py\r\n\r\n# Check class inheritance\r\ngrep \"PerformanceUser\" locustfile.py\r\n```\r\n\r\n**Azure Load Testing Errors**\r\n```bash\r\n# Install Azure dependencies\r\npip install azure-cli azure-identity azure-mgmt-loadtesting azure-mgmt-resource requests\r\n```\r\n\r\n## \ud83e\udde9 Project Structure (Generated)\r\n\r\n```\r\nperf_tests/\r\n\u251c\u2500\u2500 locustfile.py            # Main test file with API calls and @task methods\r\n\u251c\u2500\u2500 config.yaml              # Framework configuration (OSDU, metrics, test settings)\r\n\u251c\u2500\u2500 requirements.txt         # Python dependencies (osdu_perf package)  \r\n\u2514\u2500\u2500 README.md               # Project documentation\r\n```\r\n\r\n## \ud83e\uddea Development\r\n\r\n### Running Tests\r\n```bash\r\npytest tests/\r\n```\r\n\r\n### Code Quality\r\n```bash\r\n# Formatting\r\nblack osdu_perf/\r\n\r\n# Linting  \r\nflake8 osdu_perf/\r\n```\r\n\r\n### Building Package\r\n```bash\r\n# Build wheel and source distribution\r\npython -m build\r\n\r\n# Upload to TestPyPI\r\npython -m twine upload --repository testpypi dist/*\r\n```\r\n\r\n## \ud83d\udcc4 License\r\n\r\nThis project is licensed under the MIT License \u2014 see the `LICENSE` file for details.\r\n\r\n## \ud83c\udd98 Support\r\n\r\n- **Issues**: [GitHub Issues](https://github.com/janraj/osdu_perf/issues)\r\n- **Contact**: janrajcj@microsoft.com\r\n- **Documentation**: This README and inline code documentation\r\n\r\n## \ud83d\ude80 What's New in v1.0.24\r\n\r\n- \u2705 **Three-Command Workflow**: `init`, `run local`, `run azure` - complete testing pipeline\r\n- \u2705 **Configuration-Driven**: YAML-based configuration with environment-aware settings\r\n- \u2705 **Service Orchestration**: Intelligent service discovery with lifecycle management\r\n- \u2705 **Enhanced Authentication**: Multi-credential Azure authentication with automatic detection\r\n- \u2705 **Metrics Integration**: Automated Kusto metrics collection with environment detection\r\n- \u2705 **Template System**: Updated project templates with modern framework patterns\r\n- \u2705 **Error Handling**: Improved error handling and defensive coding patterns\r\n- \u2705 **CLI Improvements**: Better argument parsing and validation\r\n\r\n---\r\n\r\n**Generated by OSDU Performance Testing Framework v1.0.24**\r\n\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Performance Testing Framework for OSDU Services - A comprehensive tool for testing OSDU APIs with Locust and Azure Load Testing SDK",
    "version": "1.0.28.2",
    "project_urls": {
        "Documentation": "https://github.com/janraj/osdu_perf#readme",
        "Homepage": "https://github.com/janraj/osdu_perf",
        "Issues": "https://github.com/janraj/osdu_perf/issues",
        "Repository": "https://github.com/janraj/osdu_perf"
    },
    "split_keywords": [
        "performance",
        " testing",
        " locust",
        " azure",
        " osdu",
        " load-testing",
        " azure-sdk",
        " performance-testing"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "379b5c07f1c65aa954c7f373beb770103e023ed752658853c2875589420fb3d4",
                "md5": "94562918eb8e13b6b1ba86a5f86896e1",
                "sha256": "601f4e949b693e5c1a66dfcc041d1d41c8b05b8baf0f533384dd543e92669e8c"
            },
            "downloads": -1,
            "filename": "osdu_perf-1.0.28.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "94562918eb8e13b6b1ba86a5f86896e1",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 75423,
            "upload_time": "2025-11-12T02:36:46",
            "upload_time_iso_8601": "2025-11-12T02:36:46.720986Z",
            "url": "https://files.pythonhosted.org/packages/37/9b/5c07f1c65aa954c7f373beb770103e023ed752658853c2875589420fb3d4/osdu_perf-1.0.28.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "2b6281564be84afd1b87191e9cfff42cf514a544923767d26bb08c1508737451",
                "md5": "d6ef1ca3a3ef08ac6de43f7c11d63d1c",
                "sha256": "8cd934f87291b7868f4cc4280d68363224b40aef548d315797bac272014f3680"
            },
            "downloads": -1,
            "filename": "osdu_perf-1.0.28.2.tar.gz",
            "has_sig": false,
            "md5_digest": "d6ef1ca3a3ef08ac6de43f7c11d63d1c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 70031,
            "upload_time": "2025-11-12T02:36:48",
            "upload_time_iso_8601": "2025-11-12T02:36:48.190021Z",
            "url": "https://files.pythonhosted.org/packages/2b/62/81564be84afd1b87191e9cfff42cf514a544923767d26bb08c1508737451/osdu_perf-1.0.28.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-12 02:36:48",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "janraj",
    "github_project": "osdu_perf",
    "github_not_found": true,
    "lcname": "osdu-perf"
}
        
Elapsed time: 4.80500s