名称: 差分模糊测试器 描述: 关于差分模糊测试器工具的信息,如何运行并使用它来捕获 Turso 中的错误。运行此工具时始终加载此技能。
差分模糊测试器
始终加载 调试技能以供参考
差分模糊测试器比较 Turso 与 SQLite 对生成的 SQL 语句的结果,以发现正确性错误。
位置
testing/differential-oracle/fuzzer/
运行模糊测试器
单次运行
# 基本运行(100条语句,随机种子)
cargo run --bin differential_fuzzer
# 使用特定种子以确保可重复性
cargo run --bin differential_fuzzer -- --seed 12345
# 更多语句,带详细输出
cargo run --bin differential_fuzzer -- -n 1000 --verbose
# 运行后保留数据库文件(用于调试)
cargo run --bin differential_fuzzer -- --seed 12345 --keep-files
# 所有选项
cargo run --bin differential_fuzzer -- \
--seed <种子> # 确定性种子
-n <数量> # 语句数量(默认: 100)
-t <数量> # 表数量(默认: 2)
-c <数量> # 每表列数(默认: 5)
--verbose # 打印每条 SQL 语句
--keep-files # 将 .db 文件持久化到磁盘
连续模糊测试(循环模式)
# 使用随机种子无限运行
cargo run --bin differential_fuzzer -- loop
# 运行50次迭代
cargo run --bin differential_fuzzer -- loop 50
Docker 运行器(CI/生产)
# 从仓库根目录构建和运行
docker build -f testing/differential-oracle/fuzzer/docker-runner/Dockerfile -t fuzzer .
docker run -e GITHUB_TOKEN=xxx -e SLACK_WEBHOOK_URL=xxx fuzzer
Docker 运行器的环境变量:
TIME_LIMIT_MINUTES- 总运行时间(默认: 1440 = 24小时)PER_RUN_TIMEOUT_SECONDS- 每次运行超时时间(默认: 1200 = 20分钟)NUM_STATEMENTS- 每次运行语句数(默认: 1000)LOG_TO_STDOUT- 打印模糊测试器输出(默认: false)GITHUB_TOKEN- 用于自动提交问题SLACK_WEBHOOK_URL- 用于通知
输出文件
所有输出到 simulator-output/ 目录:
| 文件 | 描述 |
|---|---|
test.sql |
所有执行的 SQL 语句。失败语句前缀为 -- FAILED:,错误前缀为 -- ERROR: |
schema.json |
运行结束时(或失败时)的数据库模式 |
test.db |
Turso 数据库文件(仅在使用 --keep-files 时) |
test-sqlite.db |
SQLite 数据库文件(仅在使用 --keep-files 时) |
重现错误
始终遵循以下步骤
-
在错误输出中找到种子:
INFO: Starting differential_fuzzer with config: SimConfig { seed: 12345, ... } -
使用该种子重新运行:
cargo run --bin differential_fuzzer -- --seed 12345 --verbose --keep-files -
检查输出文件:
simulator-output/test.sql- 查找失败语句(寻找-- FAILED:)simulator-output/schema.json- 检查失败时的表结构
-
创建最小重现器
- 在
.sqltest或.rs中创建重现器,始终加载 调试技能以供参考
- 在
-
手动比较行为: 如果需要,尝试比较行为并最终生成报告。 始终先用编辑工具写入临时文件以测试 SQL,然后传递给二进制文件。
# 对 SQLite 运行失败的 SQL sqlite3 :memory: < simulator-output/test.sql # 对 tursodb CLI 运行 tursodb :memory: < simulator-output/test.sql
理解失败
Oracle 失败类型
- 行集不匹配 - Turso 返回与 SQLite 不同的行
- Turso 错误但 SQLite 成功 - Turso 拒绝了有效的 SQL
- SQLite 错误但 Turso 成功 - Turso 接受了无效的 SQL
- 模式不匹配 - DDL 后表/列不同
警告(非致命)
- 无序 LIMIT 不匹配 - 没有 ORDER BY 的 LIMIT 可能返回不同的有效行
关键源文件
| 文件 | 目的 |
|---|---|
main.rs |
CLI 解析,入口点 |
runner.rs |
主模拟循环,在两种数据库上执行语句 |
oracle.rs |
比较 Turso 与 SQLite 结果 |
schema.rs |
从两个数据库内省模式 |
memory/ |
用于确定性模拟的内存 I/O |
跟踪
设置 RUST_LOG 以获取更详细的输出:
RUST_LOG=debug cargo run --bin differential_fuzzer -- --seed 12345