mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-04 08:25:26 +08:00
feat: Introduce a new Go-based test suite runner with supporting scripts and documentation.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -45,6 +45,7 @@ env/
|
||||
*.log
|
||||
logs/
|
||||
uvicorn.log
|
||||
artifacts/
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
26
DEPLOY.en.md
26
DEPLOY.en.md
@@ -225,3 +225,29 @@ If admin UI is required:
|
||||
```bash
|
||||
curl -s http://127.0.0.1:5001/admin
|
||||
```
|
||||
|
||||
## 7. Pre-release Local Regression (Recommended)
|
||||
|
||||
Run the full live testsuite before release:
|
||||
|
||||
```bash
|
||||
./scripts/testsuite/run-live.sh
|
||||
```
|
||||
|
||||
Optional flags:
|
||||
|
||||
```bash
|
||||
go run ./cmd/ds2api-tests \
|
||||
--config config.json \
|
||||
--admin-key admin \
|
||||
--out artifacts/testsuite \
|
||||
--timeout 120 \
|
||||
--retries 2
|
||||
```
|
||||
|
||||
The testsuite automatically performs:
|
||||
|
||||
- preflight checks (syntax/build/unit tests)
|
||||
- isolated config copy startup (no mutation to your original `config.json`)
|
||||
- live scenario verification (OpenAI/Claude/Admin/concurrency/toolcall/streaming)
|
||||
- full request/response artifact logging for debugging
|
||||
|
||||
26
DEPLOY.md
26
DEPLOY.md
@@ -223,3 +223,29 @@ curl -s http://127.0.0.1:5001/v1/models
|
||||
```bash
|
||||
curl -s http://127.0.0.1:5001/admin
|
||||
```
|
||||
|
||||
## 7. 发布前本地回归(推荐)
|
||||
|
||||
建议在发布前执行一次完整测试集(真实账号链路):
|
||||
|
||||
```bash
|
||||
./scripts/testsuite/run-live.sh
|
||||
```
|
||||
|
||||
可选参数示例:
|
||||
|
||||
```bash
|
||||
go run ./cmd/ds2api-tests \
|
||||
--config config.json \
|
||||
--admin-key admin \
|
||||
--out artifacts/testsuite \
|
||||
--timeout 120 \
|
||||
--retries 2
|
||||
```
|
||||
|
||||
测试集会自动执行:
|
||||
|
||||
- 语法/构建/单测 preflight
|
||||
- 隔离副本配置启动服务(不污染原始 `config.json`)
|
||||
- 真实调用场景验证(OpenAI/Claude/Admin/并发/toolcall/流式)
|
||||
- 全量请求与响应日志落盘(用于故障复盘)
|
||||
|
||||
18
README.MD
18
README.MD
@@ -210,11 +210,29 @@ cp config.example.json config.json
|
||||
- API 文档:`API.md` / `API.en.md`
|
||||
- 部署文档:`DEPLOY.md` / `DEPLOY.en.md`
|
||||
- 贡献指南:`CONTRIBUTING.md` / `CONTRIBUTING.en.md`
|
||||
- 测试集文档:`TESTING.md`
|
||||
|
||||
```bash
|
||||
go test ./...
|
||||
```
|
||||
|
||||
一键真实账号全链路测试(会生成完整请求/响应日志):
|
||||
|
||||
```bash
|
||||
./scripts/testsuite/run-live.sh
|
||||
```
|
||||
|
||||
或使用可配置参数:
|
||||
|
||||
```bash
|
||||
go run ./cmd/ds2api-tests \
|
||||
--config config.json \
|
||||
--admin-key admin \
|
||||
--out artifacts/testsuite \
|
||||
--timeout 120 \
|
||||
--retries 2
|
||||
```
|
||||
|
||||
## 免责声明
|
||||
|
||||
本项目基于逆向方式实现,仅供学习与研究使用。稳定性和可用性不作保证,请勿用于违反服务条款或法律法规的场景。
|
||||
|
||||
18
README.en.md
18
README.en.md
@@ -210,11 +210,29 @@ Tool-call leakage is handled in the current implementation:
|
||||
- API docs: `API.md` / `API.en.md`
|
||||
- Deployment docs: `DEPLOY.md` / `DEPLOY.en.md`
|
||||
- Contributing: `CONTRIBUTING.md` / `CONTRIBUTING.en.md`
|
||||
- Testsuite guide: `TESTING.md`
|
||||
|
||||
```bash
|
||||
go test ./...
|
||||
```
|
||||
|
||||
One-command live end-to-end tests (with full request/response logs):
|
||||
|
||||
```bash
|
||||
./scripts/testsuite/run-live.sh
|
||||
```
|
||||
|
||||
Or run with explicit flags:
|
||||
|
||||
```bash
|
||||
go run ./cmd/ds2api-tests \
|
||||
--config config.json \
|
||||
--admin-key admin \
|
||||
--out artifacts/testsuite \
|
||||
--timeout 120 \
|
||||
--retries 2
|
||||
```
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This project is built through reverse engineering and is provided for learning and research only. Stability is not guaranteed. Do not use it in scenarios that violate terms of service or laws.
|
||||
|
||||
95
TESTING.md
Normal file
95
TESTING.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# DS2API Testing Guide
|
||||
|
||||
## Overview
|
||||
|
||||
DS2API provides a live end-to-end testsuite that runs against your **local configured accounts** and records full artifacts for post-mortem debugging.
|
||||
|
||||
Entry points:
|
||||
|
||||
- `./scripts/testsuite/run-live.sh`
|
||||
- `go run ./cmd/ds2api-tests`
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
./scripts/testsuite/run-live.sh
|
||||
```
|
||||
|
||||
Default behavior:
|
||||
|
||||
- runs preflight checks:
|
||||
- `go test ./... -count=1`
|
||||
- `node --check api/chat-stream.js`
|
||||
- `node --check api/helpers/stream-tool-sieve.js`
|
||||
- `npm run build --prefix webui`
|
||||
- copies `config.json` into an isolated temporary config
|
||||
- starts local server with `go run ./cmd/ds2api`
|
||||
- executes live scenarios (OpenAI/Claude/Admin/stream/toolcall/concurrency)
|
||||
- continues on failures and writes final summary
|
||||
|
||||
## CLI Flags
|
||||
|
||||
```bash
|
||||
go run ./cmd/ds2api-tests \
|
||||
--config config.json \
|
||||
--admin-key admin \
|
||||
--out artifacts/testsuite \
|
||||
--port 0 \
|
||||
--timeout 120 \
|
||||
--retries 2 \
|
||||
--no-preflight=false
|
||||
```
|
||||
|
||||
- `--config`: config file path (default `config.json`)
|
||||
- `--admin-key`: admin key (default from `DS2API_ADMIN_KEY`, fallback `admin`)
|
||||
- `--out`: artifact root directory (default `artifacts/testsuite`)
|
||||
- `--port`: test server port (`0` = auto pick free port)
|
||||
- `--timeout`: per request timeout in seconds (default `120`)
|
||||
- `--retries`: retry count for network/5xx requests (default `2`)
|
||||
- `--no-preflight`: skip preflight checks
|
||||
|
||||
## Artifact Layout
|
||||
|
||||
Each run creates:
|
||||
|
||||
`artifacts/testsuite/<run_id>/`
|
||||
|
||||
- `summary.json`: machine-readable report
|
||||
- `summary.md`: human-readable report
|
||||
- `server.log`: server stdout/stderr log during run
|
||||
- `preflight.log`: preflight command outputs
|
||||
- `cases/<case_id>/`
|
||||
- `request.json`
|
||||
- `response.headers`
|
||||
- `response.body`
|
||||
- `stream.raw`
|
||||
- `assertions.json`
|
||||
- `meta.json`
|
||||
|
||||
## Trace Binding (for fast debugging)
|
||||
|
||||
Each request includes:
|
||||
|
||||
- header: `X-Ds2-Test-Trace: <trace_id>`
|
||||
- query: `__trace_id=<trace_id>`
|
||||
|
||||
When a case fails, `summary.md` includes trace IDs. You can locate related server logs quickly:
|
||||
|
||||
```bash
|
||||
rg "<trace_id>" artifacts/testsuite/<run_id>/server.log
|
||||
```
|
||||
|
||||
## Exit Code
|
||||
|
||||
- `0`: all cases passed
|
||||
- `1`: one or more cases failed
|
||||
|
||||
This allows using the testsuite as a local release gate.
|
||||
|
||||
## Sensitive Data Warning
|
||||
|
||||
This testsuite stores **full raw request/response payloads** for debugging.
|
||||
|
||||
- Do not upload artifacts publicly.
|
||||
- Do not share artifact directories in issue trackers without manual redaction.
|
||||
|
||||
36
cmd/ds2api-tests/main.go
Normal file
36
cmd/ds2api-tests/main.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"ds2api/internal/testsuite"
|
||||
)
|
||||
|
||||
func main() {
|
||||
opts := testsuite.DefaultOptions()
|
||||
var timeoutSeconds int
|
||||
|
||||
flag.StringVar(&opts.ConfigPath, "config", opts.ConfigPath, "Path to config file (default: config.json)")
|
||||
flag.StringVar(&opts.AdminKey, "admin-key", opts.AdminKey, "Admin key (default: DS2API_ADMIN_KEY or admin)")
|
||||
flag.StringVar(&opts.OutputDir, "out", opts.OutputDir, "Output artifact directory")
|
||||
flag.IntVar(&opts.Port, "port", opts.Port, "Server port (0 means auto-select free port)")
|
||||
flag.IntVar(&timeoutSeconds, "timeout", int(opts.Timeout.Seconds()), "Per-request timeout in seconds")
|
||||
flag.IntVar(&opts.Retries, "retries", opts.Retries, "Retry count for network/5xx requests")
|
||||
flag.BoolVar(&opts.NoPreflight, "no-preflight", opts.NoPreflight, "Skip preflight checks")
|
||||
flag.Parse()
|
||||
|
||||
if timeoutSeconds <= 0 {
|
||||
timeoutSeconds = 120
|
||||
}
|
||||
opts.Timeout = time.Duration(timeoutSeconds) * time.Second
|
||||
|
||||
if err := testsuite.Run(context.Background(), opts); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintln(os.Stdout, "testsuite completed successfully")
|
||||
}
|
||||
1564
internal/testsuite/runner.go
Normal file
1564
internal/testsuite/runner.go
Normal file
File diff suppressed because it is too large
Load Diff
8
scripts/testsuite/run-live.sh
Executable file
8
scripts/testsuite/run-live.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT_DIR"
|
||||
|
||||
go run ./cmd/ds2api-tests "$@"
|
||||
|
||||
Reference in New Issue
Block a user