Skip to content

OpenCloudHub/api-testing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

21 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

OpenCloudHub Logo

API Testing Suite

Performance and reliability testing for OpenCloudHub platform using k6.
Explore OpenCloudHub Β»


πŸ“‘ Table of Contents
  1. About
  2. Thesis Context
  3. Features
  4. Architecture
  5. Getting Started
  6. Configuration
  7. Project Structure
  8. Test Types
  9. Running Tests
  10. Kubernetes Testing
  11. Contributing
  12. License
  13. Contact

🎯 About

This repository contains the k6-based performance testing suite example for the OpenCloudHub ML platform. It provides comprehensive testing capabilities across all platform servicesβ€”from quick smoke tests validating service health to extended soak tests that uncover memory leaks and stability issues.

Why Performance Testing?

Performance testing is critical for ML platforms where inference latency directly impacts user experience:

  • Validate Correctness: Ensure services respond correctly under various load conditions
  • Catch Regressions: Identify performance degradation before reaching production
  • Capacity Planning: Understand system limits for infrastructure sizing
  • SLA Compliance: Ensure ML model inference latency meets defined thresholds

Key Capabilities

Capability Description
Multi-Type Testing Smoke, load, stress, spike, soak, and breakpoint tests
Service Coverage ML models, MLOps tools, infrastructure, and observability
Kubernetes Native Run tests inside the cluster using k6-operator
Grafana Integration Results tagged for dashboard filtering and analysis

πŸ“š Thesis Context

Purpose in the Thesis

This work demonstrates how k6 can be integrated for continuous performance validation, with results feeding into Grafana dashboards for trend analysis across deployments.

Related Repositories

Repository Purpose
gitops ArgoCD application definitions and Kubernetes manifests for the tests
api-testing (this repo) Performance testing suite

✨ Features

  • πŸš€ Multiple Test Types β€” Smoke, load, stress, spike, soak, and breakpoint tests with predefined profiles
  • πŸ“Š Service Categories β€” Organized tests for ML models, MLOps, infrastructure, and observability services
  • πŸ”§ Reusable Helpers β€” Common HTTP utilities, data loading, and check functions
  • βš™οΈ Configurable Thresholds β€” Per-test-type thresholds tuned for local Kind/Minikube clusters
  • πŸ“ˆ Automatic Reporting β€” JSON output with detailed metrics per test run
  • 🏷️ Grafana Tagging β€” All requests tagged for dashboard filtering (testid, test_type, test_target)
  • 🐳 DevContainer Ready β€” Works out of the box in VS Code DevContainers
  • ☸️ Kubernetes Native β€” Run tests inside the cluster using k6-operator

πŸ—οΈ Architecture

Execution Modes

Tests can run in two modes:

Mode Command Description
Local make smoke Run k6 directly from DevContainer against cluster services
In-Cluster Via gitops repo k6-operator runs tests inside Kubernetes

Local Execution

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  DevContainer                                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”‚
β”‚  β”‚  make    │───▢│  k6 Runtime   │───▢│  Services (via Ingress)    β”‚      β”‚
β”‚  β”‚  smoke   β”‚     β”‚               β”‚     β”‚  *.opencloudhub.org        β”‚      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚
β”‚                           β”‚                                                 β”‚
β”‚                           β–Ό                                                 β”‚
β”‚                   results/<timestamp>/                                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

In-Cluster Execution (k6-operator)

For Kubernetes-native testing, the gitops repo manages TestRun CRDs that use this repo's Docker image:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Kubernetes Cluster                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚  k6-operator     │──▢│  k6 Runner Pod   │──▢│ Services         β”‚       β”‚
β”‚  β”‚                  β”‚    β”‚  (k6-tests image)β”‚    β”‚ (internal DNS)   β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚                                   β”‚                                         β”‚
β”‚                                   β–Ό                                         β”‚
β”‚                           Prometheus (metrics)                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The Docker image (opencloudhuborg/k6-tests) packages all tests, config, and data from this repo.

Component Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              Test Suite                                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                             β”‚
β”‚   config/                    helpers/                    tests/             β”‚
β”‚   β”œβ”€β”€ environments.js        β”œβ”€β”€ checks.js              β”œβ”€β”€ 01-smoke/       β”‚
β”‚   β”‚   (service URLs)         β”‚   (assertions)           β”œβ”€β”€ 02-load/        β”‚
β”‚   β”œβ”€β”€ endpoints.js           β”œβ”€β”€ data.js                β”œβ”€β”€ 03-stress/      β”‚
β”‚   β”‚   (API paths)            β”‚   (test data)            β”œβ”€β”€ 04-spike/       β”‚
β”‚   └── thresholds.js          └── http.js                β”œβ”€β”€ 05-soak/        β”‚
β”‚       (SLA limits)               (requests)             └── 06-breakpoint/  β”‚
β”‚                                                                             β”‚
β”‚   data/                      scripts/                   results/            β”‚
β”‚   β”œβ”€β”€ fashion-mnist.json     └── summary.sh            └── <timestamp>/     β”‚
β”‚   β”œβ”€β”€ wine.json                 (aggregation)              (JSON output)    β”‚
β”‚   └── qwen-prompts.json                                                     β”‚
β”‚                                                                             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Getting Started

Prerequisites

Requirement Purpose
Docker Container runtime for DevContainer
VS Code IDE with DevContainers extension
OpenCloudHub Cluster Target platform (Minikube or remote)

Setup Steps

1. Clone the repository

git clone https://github.com/opencloudhub/api-testing.git
cd api-testing

2. Open in DevContainer (Recommended)

Press Ctrl+Shift+P β†’ Dev Containers: Rebuild and Reopen in Container

The DevContainer includes k6 pre-installed and configured.

3. Configure /etc/hosts (for local cluster)

Ensure your host machine has cluster IPs mapped:

cat /etc/hosts | grep opencloudhub
# Should show entries like:
# 192.168.49.2 mlflow.internal.opencloudhub.org
# 192.168.49.2 api.opencloudhub.org

4. Verify Setup

make help    # Show all make targets
make list    # List available test scripts

5. Run First Test

make smoke-platform-mlops  # Quick health check

βš™οΈ Configuration

Environment URLs (config/environments.js)

Defines service URLs per environment. Two environments are supported:

Environment Use Case URL Pattern
dev Local testing via ingress https://*.opencloudhub.org
internal In-cluster testing http://*.svc.cluster.local
// Example: Switch environment
// CLI: TEST_ENV=internal make smoke

const ENVIRONMENTS = {
  dev: {
    models: { api: 'https://api.opencloudhub.org' },
    platform: {
      mlops: { mlflow: 'https://mlflow.internal.opencloudhub.org' }
    }
  },
  internal: {
    platform: {
      mlops: { mlflow: 'http://mlflow.mlops.svc.cluster.local:5000' }
    }
  }
};

Thresholds (config/thresholds.js)

Performance thresholds and load profiles per test type:

Metric Smoke Load Stress Spike Soak
http_req_failed <10% <5% <10% <15% <5%
http_req_duration p95 <3s <2.5s <4s <5s <3s
checks pass rate >90% >90% >85% >80% >90%

Endpoints (config/endpoints.js)

Common endpoint patterns by service type:

// Custom ML models (FastAPI)
export const CUSTOM_MODEL_ENDPOINTS = {
  health: '/health',
  info: '/info',
  predict: '/predict'
};

// Base LLM models (OpenAI-compatible)
export const BASE_MODEL_ENDPOINTS = {
  models: '/models',
  chat: '/chat/completions'
};

πŸ“ Project Structure

api-testing/
β”œβ”€β”€ config/                    # Configuration files
β”‚   β”œβ”€β”€ endpoints.js           # API endpoint patterns by service type
β”‚   β”œβ”€β”€ environments.js        # Service URLs per environment (dev, internal)
β”‚   └── thresholds.js          # Performance thresholds and load profiles
β”‚
β”œβ”€β”€ data/                      # Test data files
β”‚   β”œβ”€β”€ fashion-mnist.json     # Image samples (784 pixels each)
β”‚   β”œβ”€β”€ wine.json              # Wine feature samples (13 features)
β”‚   β”œβ”€β”€ qwen-prompts.json      # LLM prompt samples
β”‚   └── rag-queries.json       # RAG query samples
β”‚
β”œβ”€β”€ helpers/                   # Reusable test utilities
β”‚   β”œβ”€β”€ checks.js              # Standardized k6 check functions
β”‚   β”œβ”€β”€ data.js                # Data loading (SharedArray) utilities
β”‚   └── http.js                # HTTP request wrappers with checks
β”‚
β”œβ”€β”€ tests/                     # Test scripts organized by type
β”‚   β”œβ”€β”€ 01-smoke/              # Quick health validation (10s, 1 VU)
β”‚   β”‚   β”œβ”€β”€ apps/              # Team applications
β”‚   β”‚   β”œβ”€β”€ models/            # ML model tests
β”‚   β”‚   β”‚   β”œβ”€β”€ base/          # Base LLM models (qwen)
β”‚   β”‚   β”‚   └── custom/        # Custom models (fashion-mnist, wine)
β”‚   β”‚   └── platform/          # Platform services
β”‚   β”‚       β”œβ”€β”€ gitops.js      # ArgoCD
β”‚   β”‚       β”œβ”€β”€ infrastructure.js  # MinIO, pgAdmin
β”‚   β”‚       β”œβ”€β”€ mlops.js       # MLflow, Argo Workflows
β”‚   β”‚       └── observability.js   # Grafana
β”‚   β”œβ”€β”€ 02-load/               # Normal traffic (~7.5 min, 10-50 VUs)
β”‚   β”œβ”€β”€ 03-stress/             # Beyond normal (~18 min, 5-20 VUs)
β”‚   β”œβ”€β”€ 04-spike/              # Traffic bursts (~2.5 min, 3-25 VUs)
β”‚   β”œβ”€β”€ 05-soak/               # Extended duration (~34 min, 5 VUs)
β”‚   └── 06-breakpoint/         # Find limits (~10 min, 10-100 req/s)
β”‚
β”œβ”€β”€ scripts/
β”‚   └── summary.sh             # Results aggregation script
β”‚
β”œβ”€β”€ results/                   # Test output (gitignored)
β”‚   └── <timestamp>/           # Per-run results
β”‚       β”œβ”€β”€ smoke-*.json       # Full k6 output
β”‚       └── smoke-*-summary.json  # Aggregated metrics
β”‚
β”œβ”€β”€ Dockerfile                 # Container image for k6-operator
β”œβ”€β”€ Makefile                   # Test orchestration commands
└── README.md                  # This documentation

πŸ“Š Test Types

Different test types validate different aspects of system behavior:

Test Duration VUs Purpose When to Use
Smoke 10s 1 Quick health validation After deployments, CI/CD
Load ~7.5m 10β†’50 Normal traffic simulation Capacity validation
Stress ~18m 5β†’20 Beyond normal capacity Find breaking points
Spike ~2.5m 3β†’25 Sudden traffic bursts Test auto-scaling
Soak 34m+ 5 Extended duration Find memory leaks
Breakpoint ~10m 10β†’100 req/s Increasing until failure Max capacity

Smoke Tests πŸ”

Quick validation that services are alive and responding correctly.

make smoke              # All services
make smoke-platform     # Platform services only
make smoke-fashion-mnist  # Single model

Load Tests πŸ“ˆ

Simulate expected production traffic patterns with ramping VUs.

make load               # All load tests
make load-fashion-mnist # Single model (~7.5 minutes)

Stress Tests πŸ’ͺ

Push beyond normal capacity to observe degradation behavior.

make stress-fashion-mnist  # ~18 minutes

Spike Tests ⚑

Sudden traffic bursts to test resilience and recovery.

make spike-fashion-mnist  # ~2.5 minutes

Soak Tests πŸ•

Extended duration to find memory leaks and connection exhaustion.

make soak-fashion-mnist  # ~34 minutes

Breakpoint Tests πŸ”₯

Continuously increase load until the system fails.

make breakpoint-fashion-mnist  # ~10 minutes

πŸƒ Running Tests

Quick Commands

# Run all smoke tests (recommended first step)
make smoke

# Run by category
make smoke-platform      # MLOps, GitOps, Infrastructure, Observability
make smoke-models        # Fashion MNIST, Wine, Qwen

# Run specific service
make smoke-fashion-mnist
make smoke-platform-mlops

# Different environment
TEST_ENV=internal make smoke

View Results

# Show summary of latest run
make summary

# Browse result files
ls results/

# View detailed JSON
cat results/20251203-120000/smoke-platform-mlops-summary.json | jq

Available Targets

Run make help to see all available targets:

Test Types:
  smoke      - Quick health checks (10s)
  load       - Normal load (~9min)
  stress     - Beyond normal (~18min)
  spike      - Sudden bursts (~2.5min)
  soak       - Extended duration (~34min)
  breakpoint - Find limits (~10min)

Targets:
  smoke               Run all smoke tests
  smoke-platform      Platform smoke tests
  smoke-models        Model smoke tests
  load                Run all load tests
  ...

☸️ Kubernetes Testing

For in-cluster testing, see the gitops repo testing section which manages:

  • k6-operator deployment
  • TestRun CRDs for each test
  • Makefile for easy execution (make smoke-fashion-mnist)
  • Prometheus integration for metrics export

The tests use the Docker image built from this repo (opencloudhuborg/k6-tests), which packages all test scripts, config, and data.

Docker Image

# Build locally
docker build -t opencloudhuborg/k6-tests:latest .

# Image contents
/tests/
β”œβ”€β”€ config/      # Environment configs
β”œβ”€β”€ helpers/     # Test utilities
β”œβ”€β”€ tests/       # Test scripts
└── data/        # Test data

πŸ‘₯ Contributing

Contributions are welcome! This project follows OpenCloudHub's contribution standards.

Adding a New Test

  1. Add service URL to config/environments.js
  2. Create test file following existing patterns in tests/
  3. Add make target to Makefile
  4. Test locally before submitting

Code Style

  • Use descriptive check names for Grafana filtering
  • Follow existing file structure and naming conventions
  • Add JSDoc comments for exported functions
  • Use helpers from helpers/ for consistency

Pull Request Process

  1. Fork the repository
  2. Create a feature branch
  3. Commit with descriptive messages
  4. Open PR against main

See Contributing Guidelines for details.


πŸ“„ License

Distributed under the Apache 2.0 License. See LICENSE for details.


πŸ“¬ Contact

OpenCloudHub β€” GitHub Organization

Project Link: https://github.com/opencloudhub/api-testing

(back to top)

About

Performance and reliability testing for OpenCloudHub platform using k6

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published