Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ __pycache__/
*.pyc
jmx_files
jtl_files
reports/*
!reports/.gitkeep

# Frontend dependencies
frontend/package-lock.json
frontend/node_modules/

# C extensions
*.so
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ repos:
rev: 7.1.1
hooks:
- id: flake8
args: [--max-line-length=127, --ignore=E203,W503,F401,E402]
args: ["--max-line-length=127", "--ignore=E203,W503,F401,E402"]
exclude: ^(dev_server\.py|tests/conftest\.py|venv/.*)

# Remove unused imports and variables
Expand Down
22 changes: 19 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ RUN apt-get update && apt-get install -y \
gcc \
curl \
python3-dev \
wget \
unzip \
openjdk-17-jdk \
&& rm -rf /var/lib/apt/lists/*

# Change the working directory to the `app` directory
Expand All @@ -37,19 +40,32 @@ RUN --mount=type=cache,target=/root/.cache/uv \

FROM python:3.12-slim

# Set environment variables
# Set environment variables for JMeter
ENV JMETER_VERSION=5.6.3
ENV JMETER_HOME=/opt/apache-jmeter-${JMETER_VERSION}
ENV PATH="${JMETER_HOME}/bin:/app/.venv/bin:$PATH"

# Set application environment variables
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=production
ENV DATABASE_URL=sqlite:///./app.db
ENV PATH="/app/.venv/bin:$PATH"

# Install runtime dependencies
# Install runtime dependencies including JMeter requirements
RUN apt-get update && apt-get install -y \
libmagic1 \
libpq-dev \
curl \
wget \
unzip \
openjdk-17-jdk \
&& rm -rf /var/lib/apt/lists/*

# Install JMeter
RUN wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz \
&& tar -xzf apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
&& rm apache-jmeter-${JMETER_VERSION}.tgz \
&& chmod +x ${JMETER_HOME}/bin/jmeter

# Copy the environment with all dependencies
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app /app
Expand Down
26 changes: 22 additions & 4 deletions Dockerfile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ ENV ENVIRONMENT=development
ENV DATABASE_URL=sqlite:///./ci_test.db
ENV DEBUG=true

# Install build dependencies and minimal dependencies
# Install build dependencies and JMeter dependencies
RUN apt-get update && apt-get install -y \
curl \
gcc \
python3-dev \
wget \
unzip \
openjdk-17-jdk \
&& rm -rf /var/lib/apt/lists/*

# Change the working directory to the `app` directory
Expand All @@ -36,18 +39,31 @@ RUN --mount=type=cache,target=/root/.cache/uv \

FROM python:3.12-slim

# Set environment variables for JMeter
ENV JMETER_VERSION=5.6.3
ENV JMETER_HOME=/opt/apache-jmeter-${JMETER_VERSION}
ENV PATH="${JMETER_HOME}/bin:/app/.venv/bin:$PATH"

# Set environment variables for CI
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=development
ENV DATABASE_URL=sqlite:///./ci_test.db
ENV DEBUG=true
ENV PATH="/app/.venv/bin:$PATH"

# Install minimal dependencies
# Install JMeter dependencies
RUN apt-get update && apt-get install -y \
curl \
wget \
unzip \
openjdk-17-jdk \
&& rm -rf /var/lib/apt/lists/*

# Install JMeter
RUN wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz \
&& tar -xzf apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
&& rm apache-jmeter-${JMETER_VERSION}.tgz \
&& chmod +x ${JMETER_HOME}/bin/jmeter

# Copy the environment with all dependencies including pytest
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app /app
Expand All @@ -63,12 +79,14 @@ RUN mkdir -p jmx_files jtl_files reports static templates
# Create test database file
RUN touch ci_test.db

# Verify pytest installation with detailed logging
# Verify installations with detailed logging
RUN echo "🔍 Checking Python environment..." && \
echo "Python version: $(python --version)" && \
echo "Python path: $(which python)" && \
echo "🔍 Checking virtual environment..." && \
echo "Virtual env path: /app/.venv" && \
echo "🔍 Checking JMeter installation..." && \
jmeter --version && \
echo "🔍 Listing installed packages..." && \
uv pip list | grep -i pytest || echo "❌ No pytest packages found" && \
echo "🔍 Checking pytest directly..." && \
Expand Down
47 changes: 47 additions & 0 deletions Dockerfile.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Test Dockerfile with JMeter for CI environments
FROM python:3.9-slim

# Set environment variables for JMeter
ENV JMETER_VERSION=5.6.3
ENV JMETER_HOME=/opt/apache-jmeter-${JMETER_VERSION}
ENV PATH="${JMETER_HOME}/bin:$PATH"

# Set application environment variables
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=test

# Install system dependencies including JMeter requirements
RUN apt-get update && apt-get install -y \
libmagic1 \
libpq-dev \
gcc \
curl \
wget \
unzip \
openjdk-17-jdk \
&& rm -rf /var/lib/apt/lists/*

# Install JMeter
RUN wget https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz \
&& tar -xzf apache-jmeter-${JMETER_VERSION}.tgz -C /opt \
&& rm apache-jmeter-${JMETER_VERSION}.tgz \
&& chmod +x ${JMETER_HOME}/bin/jmeter

# Set working directory
WORKDIR /app

# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY . .

# Create required directories
RUN mkdir -p jmx_files jtl_files reports static templates

# Verify JMeter installation
RUN jmeter --version

# Default command for tests
CMD ["python", "-m", "pytest", "-v"]
3 changes: 2 additions & 1 deletion config/dev_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class DevSettings(Settings):
# Development settings
debug: bool = True
reload: bool = True
environment: str = "development"
# environment: str = "development"
environment: str = "production"
log_level: str = "DEBUG"

# Allow all origins for development
Expand Down
5 changes: 2 additions & 3 deletions core/jmeter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import yaml
from fastapi import HTTPException, UploadFile
from loguru import logger
from pydantic import BaseModel
from sqlalchemy.orm import Session

from config import settings
Expand All @@ -18,14 +17,14 @@
from utils.tasks import execute_jmeter_task, generate_html_report_task


class RunCmdResp(BaseModel):
class RunCmdResp:
pid: int
stdout: str
stderr: str
returncode: int


class ExecuteJmxResponse(BaseModel):
class ExecuteJmxResponse:
output_file_path: str
cost_time: str
status: str
Expand Down
4 changes: 2 additions & 2 deletions database/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Database module."""

from .base import Base, SessionLocal, engine, get_db
from .models import AuditLog, FileRecord, FileType, Report, Task, TaskStatus
from .models import AuditLog, FileRecord, FileType, Task, TaskStatus

__all__ = ["Base", "engine", "get_db", "SessionLocal", "Task", "FileRecord", "Report", "AuditLog", "TaskStatus", "FileType"]
__all__ = ["Base", "engine", "get_db", "SessionLocal", "Task", "FileRecord", "AuditLog", "TaskStatus", "FileType"]
22 changes: 0 additions & 22 deletions database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,6 @@ def __repr__(self):
return f"<FileRecord(id={self.id}, name={self.original_name}, type={self.file_type})>"


class Report(Base):
"""Report model."""

__tablename__ = "reports"

id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
task_id = Column(UUID(as_uuid=True), nullable=False)
jtl_file_path = Column(String(500), nullable=False)
report_path = Column(String(500), nullable=False)
report_url = Column(String(500), nullable=False)

# Generation information
generation_time = Column(Float, nullable=True) # in seconds
generated_at = Column(DateTime, default=datetime.utcnow, nullable=False)

# Metadata
is_deleted = Column(Boolean, default=False, nullable=False)

def __repr__(self):
return f"<Report(id={self.id}, task_id={self.task_id})>"


class AuditLog(Base):
"""Audit log model."""

Expand Down
23 changes: 23 additions & 0 deletions dev_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"tasks": {
"8c8f1353-9c3c-4473-a8ab-3102693071e1": {
"status": "completed",
"file_name": "simple_test.jmx",
"output_file": "simple_test_20250628_165240.jtl",
"cost_time": "0.15s",
"created_at": "2025-06-28T08:52:40.449456",
"completed_at": "2025-06-28T08:52:40.449463",
"task_id": "8c8f1353-9c3c-4473-a8ab-3102693071e1"
},
"2609c0b6-406b-438c-91f7-5fb78ae489a5": {
"status": "completed",
"file_name": "simple_test.jmx",
"output_file": "simple_test_20250628_165257.jtl",
"cost_time": "0.15s",
"created_at": "2025-06-28T08:52:57.978837",
"completed_at": "2025-06-28T08:52:57.978845",
"task_id": "2609c0b6-406b-438c-91f7-5fb78ae489a5"
}
},
"files": {}
}
Loading
Loading