Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/actions/pytest/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ inputs:
description: 'Run pytest in dry-run mode (collect tests only, do not execute)'
required: false
default: 'false'
start_minio:
description: 'Start MinIO service for LoRA tests (true/false)'
required: false
default: 'true'


runs:
Expand All @@ -47,6 +51,47 @@ runs:
echo "PLATFORM_ARCH=${PLATFORM_ARCH}" >> $GITHUB_ENV
echo "🏗️ Platform architecture: ${PLATFORM_ARCH}"

- name: Start MinIO Service
if: inputs.start_minio == 'true'
shell: bash
env:
MINIO_CONTAINER_NAME: dynamo-minio-test
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
run: |
# Start MinIO for S3-compatible object storage (used by LoRA tests)
echo "🗄️ Starting MinIO service..."

# Remove any existing container
docker rm -f "${MINIO_CONTAINER_NAME}" 2>/dev/null || true

docker run -d \
--name "${MINIO_CONTAINER_NAME}" \
-p 9000:9000 \
-p 9001:9001 \
-e "MINIO_ROOT_USER=${MINIO_ACCESS_KEY}" \
-e "MINIO_ROOT_PASSWORD=${MINIO_SECRET_KEY}" \
quay.io/minio/minio server /data --console-address ':9001'

# Wait for MinIO to be ready with exponential backoff
echo "⏳ Waiting for MinIO to be ready..."
MAX_ATTEMPTS=30
ATTEMPT=0
while [ $ATTEMPT -lt $MAX_ATTEMPTS ]; do
if curl -sf http://localhost:9000/minio/health/live > /dev/null 2>&1; then
echo "✅ MinIO is ready (attempt $((ATTEMPT + 1)))"
break
fi
ATTEMPT=$((ATTEMPT + 1))
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
echo "❌ MinIO failed to start within ${MAX_ATTEMPTS} seconds"
echo "📋 Container logs:"
docker logs "${MINIO_CONTAINER_NAME}" 2>&1 || true
exit 1
fi
sleep 1
done

- name: Run tests
shell: bash
env:
Expand Down Expand Up @@ -140,6 +185,13 @@ runs:
# Exit with original test result to maintain workflow behavior
exit ${TEST_EXIT_CODE}

- name: Cleanup MinIO Service
if: always() && inputs.start_minio == 'true'
shell: bash
run: |
echo "🧹 Cleaning up MinIO container..."
docker rm -f dynamo-minio-test 2>/dev/null || true

- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always() # Always upload test results, even if tests failed
Expand Down
3 changes: 3 additions & 0 deletions container/deps/requirements.test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
# create non-reproducible builds, and cause dependency conflicts. Every installed version
# should be explicitly tested, not an unknown future release.

# For MinIO/S3 operations in LoRA tests (replaces AWS CLI dependency)
boto3==1.36.14
boto3-stubs[s3]==1.36.14 # Type stubs for boto3 S3 client
# For IFEval dataset loading in kvbm tests
datasets==4.4.1
# For NATS object store verification in router tests
Expand Down
19 changes: 5 additions & 14 deletions tests/serve/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# SPDX-License-Identifier: Apache-2.0

import os
import shutil
from dataclasses import dataclass
from typing import Generator

Expand Down Expand Up @@ -95,36 +94,28 @@ def minio_lora_service():
Provide a MinIO service with a pre-uploaded LoRA adapter for testing.

This fixture:
1. Starts a MinIO Docker container
1. Connects to existing MinIO or starts a Docker container
2. Creates the required S3 bucket
3. Downloads the LoRA adapter from Hugging Face Hub
4. Uploads it to MinIO
5. Yields the MinioLoraConfig with connection details
6. Cleans up after the test
6. Cleans up after the test (only stops container if we started it)

Usage:
def test_lora(minio_lora_service):
config = minio_lora_service
# Use config.get_env_vars() for environment setup
# Use config.get_s3_uri() to get the S3 URI for loading LoRA
"""
# LoRA serve tests spin up a local MinIO via Docker. Some environments are
# intentionally minimal (e.g. vLLM-only containers) and do not include the
# docker CLI, in which case we skip the LoRA tests.
if shutil.which("docker") is None:
pytest.skip("LoRA serve tests require the docker CLI (MinIO container).")

config = MinioLoraConfig()
service = MinioService(config)

try:
# Start MinIO
# Start or connect to MinIO
service.start()

# Create bucket
# Create bucket and upload LoRA
service.create_bucket()

# Download and upload LoRA
local_path = service.download_lora()
service.upload_lora(local_path)

Expand All @@ -134,6 +125,6 @@ def test_lora(minio_lora_service):
yield config

finally:
# Stop MinIO and clean up
# Stop MinIO only if we started it, clean up temp dirs
service.stop()
service.cleanup_temp()
Loading
Loading