Metadata-Version: 2.4
Name: stress-test-kit
Version: 0.1.1
Summary: 本地压测工具，基于 Locust 和 FastAPI
Author: gg.zhao
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.100.0
Requires-Dist: uvicorn[standard]>=0.23.0
Requires-Dist: sqlalchemy>=2.0.0
Requires-Dist: locust>=2.15.0
Requires-Dist: psutil>=5.9.0
Requires-Dist: requests>=2.28.0
Requires-Dist: click>=8.1.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-multipart>=0.0.6
Requires-Dist: aiofiles>=23.0.0
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Stress Test Kit

一个基于 Locust 的压测工具，提供 Web 界面，支持多接口并发压测、实时监控、历史记录查询和本机资源监控。

## 特性

- **Locust 引擎**：基于成熟的 Locust 框架，支持 Master/Worker 分布式架构
- **多接口并发压测**：一个任务可配置多个接口，按比例因子分配并发用户数
- **实时监控**：压测过程中实时查看 RPS、响应时间、错误率等指标
- **CSV 参数化**：支持从 CSV 文件读取数据作为接口参数
- **JSON 断言规则**：支持对响应结果进行灵活的断言验证
- **内置函数变量**：支持 `{{timestamp10}}`、`{{timestamp13}}`、`{{uuid}}`、`{{random_int}}` 等动态变量
- **历史数据管理**：保存每次压测的详细数据，支持按任务筛选和查看
- **本机资源监控**：实时查看 CPU、内存、磁盘、网络等资源使用情况，管理 Locust 进程
- **Web 界面**：基于 Vue 3 + Element Plus 的现代化界面

## 安装

```bash
pip install stress-test-kit
```

## 快速开始

安装完成后，在命令行运行：

```bash
stress-test
```

程序会启动 Web 服务，默认监听端口 `8000`，在浏览器中打开 `http://localhost:8000` 即可使用。

数据库文件位于 `~/.stress-test-kit/stress_test.db`，日志文件位于 `~/.stress-test-kit/logs/`。

## 功能说明

### 1. 压测任务管理

#### 1.1 任务列表

![任务列表](docs/images/task-list.png)

在任务列表中，可以查看所有已创建的压测任务，包括任务名称、配置的接口数量、创建时间等信息。支持以下操作：

- **启动任务**：点击"启动"按钮开始压测
- **查看任务**：查看任务的详细配置
- **编辑任务**：修改任务配置
- **删除任务**：删除不需要的任务

#### 1.2 创建压测任务

创建压测任务需要配置两部分内容：全局参数和接口配置。

##### 全局参数配置

![全局参数配置](docs/images/task-config-global.png)

全局参数包括：

- **任务名称**：用于标识该压测任务
- **总并发用户数**：整个压测任务的总并发数，会按各接口的比例因子分配到各个接口
- **每秒启动用户数（spawn-rate）**：Locust 启动用户的速率，控制压力上升的速度
- **Worker 数量**：Locust Worker 进程数量，建议设置为 CPU 核心数
- **压测时长（秒）**：压测持续的时间，0 表示持续运行直到手动停止

##### 接口配置

![接口配置](docs/images/task-config-api.png)

每个接口的配置项包括：

- **接口名称**：用于标识该接口
- **请求方法**：GET、POST、PUT、DELETE 等
- **URL**：完整的请求地址
- **请求头**：JSON 格式的请求头，例如 `{"Content-Type": "application/json"}`
- **请求体**：请求的 Body 内容，支持内置函数变量和参数化变量
- **比例因子（weight_factor）**：用于分配并发用户数的权重，详见下方说明
- **参数化文件**：可选，从上传的 CSV 文件中选择数据源
- **断言规则**：可选，对响应结果进行断言验证

##### 内置函数变量

在请求头和请求体中，可以使用以下内置函数变量：

```json
{
  "timestamp10": "{{timestamp10}}",
  "timestamp13": "{{timestamp13}}",
  "uuid": "{{uuid}}",
  "random_int": "{{random_int}}"
}
```

- `{{timestamp10}}`：10 位时间戳（秒）
- `{{timestamp13}}`：13 位时间戳（毫秒）
- `{{uuid}}`：生成一个 UUID
- `{{random_int}}`：生成一个随机整数（0-999999）

##### 参数化文件

如果选择了参数化文件，可以使用 CSV 文件中的列名作为变量，例如 CSV 文件内容为：

```csv
user_id,user_name
1001,Alice
1002,Bob
1003,Charlie
```

在请求体中可以使用：

```json
{
  "user_id": "{{user_id}}",
  "user_name": "{{user_name}}"
}
```

每次请求会按顺序读取 CSV 文件的一行数据。

##### JSON 断言规则

断言规则使用 JSON 格式，支持多种断言方式：

```json
{
  "code": 200,
  "data.status": "success",
  "data.items": {"$contains": {"id": 123}},
  "data.count": {"$gte": 10}
}
```

支持的操作符：

- **直接比较**：`"field": value` 表示字段值必须等于 value
- **`$contains`**：`"field": {"$contains": value}` 表示数组字段必须包含指定元素
- **`$in`**：`"field": {"$in": [v1, v2]}` 表示字段值必须在指定列表中
- **`$gt`、`$gte`、`$lt`、`$lte`、`$ne`**：数值比较操作符

##### 比例因子与并发分配

比例因子（weight_factor）用于在多个接口之间分配总并发用户数。例如：

- 总并发用户数设置为 100
- 接口 A 的比例因子为 3
- 接口 B 的比例因子为 2

则接口 A 分配到的并发数为：`100 * 3 / (3 + 2) = 60`  
接口 B 分配到的并发数为：`100 * 2 / (3 + 2) = 40`

#### 1.3 监控任务运行

启动任务后，可以实时查看压测过程中的各项指标：

- **请求总数、失败数、平均响应时间、当前 RPS**
- **响应时间百分位数（P50、P90、P95、P99）**
- **用户数曲线图**：展示各接口的实际并发用户数随时间的变化
- **统计表格**：各接口的请求数、失败数、响应时间、RPS 等详细数据
- **错误列表**：实时显示压测过程中的错误信息

### 2. 历史记录

![历史记录](docs/images/history-list.png)

历史记录模块保存了所有压测任务的运行记录，包括：

- **运行 ID**：唯一标识一次压测运行
- **所属任务**：该记录对应的压测任务名称
- **并发用户数**：本次运行的总并发数
- **Worker 数量**：本次运行的 Worker 进程数
- **开始时间、结束时间**：压测的起止时间
- **持续时长**：压测实际运行的时间

支持的操作：

- **按任务筛选**：选择特定任务查看其历史记录
- **查看数据**：查看该次运行的详细统计数据
- **批量删除**：删除不需要的历史记录

点击"查看数据"可以查看该次压测的完整统计信息：

- **请求总数、失败数、平均响应时间、总 RPS**
- **响应时间百分位数（P50、P90、P95、P99）**
- **各接口的详细统计**：请求数、失败数、最小/最大/平均响应时间、RPS、P50/P90/P95/P99
- **错误统计**：各类错误的出现次数和错误消息

### 3. 文件管理

文件管理模块用于管理压测任务中使用的参数化文件（CSV 格式）。

文件列表显示已上传的 CSV 文件信息：

- **文件 ID**：唯一标识一个文件
- **文件名**：上传的原始文件名
- **列名**：CSV 文件的表头（列名列表）
- **数据行数**：CSV 文件的数据行数（不含表头行）
- **上传时间**：文件上传的时间

支持的操作：

- **上传 CSV 文件**：点击"上传文件"按钮，选择本地 CSV 文件上传
- **批量删除**：删除不需要的文件

##### CSV 文件格式要求

- 文件必须包含表头行（第一行为列名）
- 文件编码建议使用 UTF-8
- 列名只能包含字母、数字和下划线，且不能以数字开头
- 数据行数建议不超过 10000 行，过多数据可能影响性能

### 4. 本机资源

![本机资源](docs/images/machine-resources.png)

本机资源模块提供对运行压测的机器的实时监控。

#### 4.1 本机资源监控

实时显示机器的资源使用情况：

- **CPU 使用率**：当前 CPU 的使用百分比
- **内存使用率**：当前内存的使用百分比和已用/总量
- **磁盘使用率**：系统盘的使用百分比和已用/总量
- **网络流量**：网络上传和下载的速度（KB/s 或 MB/s）

#### 4.2 当前运行的 Locust 进程

显示当前正在运行的 Locust 进程列表：

- **进程 ID（PID）**：操作系统分配的进程 ID
- **进程类型**：Master 或 Worker
- **所属任务**：该进程所属的压测任务名称
- **启动时间**：进程的启动时间
- **CPU 占用**：该进程的 CPU 使用率
- **内存占用**：该进程的内存使用量（MB）
- **操作**：可以停止该进程

#### 4.3 Locust 孤儿进程扫描

Locust 孤儿进程是指由于异常退出或其他原因导致的残留 Locust 进程（Master 或 Worker）。这些进程可能会占用端口或资源，影响新任务的启动。

本机资源模块提供了孤儿进程扫描和清理功能：

- **扫描孤儿进程**：点击"扫描孤儿进程"按钮，系统会检测所有不属于当前运行任务的 Locust 进程
- **清理孤儿进程**：扫描完成后，可以批量清理这些孤儿进程

##### 使用场景

- 压测任务异常退出后，Locust 进程未正常关闭
- 多次启动任务后，发现端口被占用
- 定期清理残留进程，释放系统资源

## 技术架构

- **后端**：FastAPI + Uvicorn
- **前端**：Vue 3 + TypeScript + Element Plus + Vite
- **压测引擎**：Locust（Master/Worker 架构）
- **数据库**：SQLite + SQLAlchemy（同步 ORM）
- **资源监控**：psutil

## 开发

### 安装开发依赖

```bash
pip install -e ".[dev]"
```

### 运行前端开发服务器

```bash
cd frontend
npm install
npm run dev
```

### 构建前端

```bash
cd frontend
npm run build
```

构建产物会输出到 `stress_test_kit/static/` 目录。

### 运行测试

```bash
pytest
```

## License

MIT License

## 贡献

欢迎提交 Issue 和 Pull Request！
