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
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ jobs:
./target/debug/utgen --help
- name: Check the standalone example workspace
run: cargo metadata --manifest-path examples/bytes/Cargo.toml --no-deps --format-version 1 > /dev/null
- name: Install the validated coverage tool
run: cargo +stable install cargo-llvm-cov --version 0.6.16 --locked
- name: Validate the minimal analysis and test pipeline
run: python3 scripts/check_minimal.py
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[workspace]
resolver = "2"
members = ["brinfo", "focxt", "focxt/call_chain", "utgen", "build-utils"]
exclude = ["examples/bytes"]
exclude = ["examples/bytes", "examples/minimal"]
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ PALM combines program analysis with LLMs to generate Rust tests, repair compilat
2. Install [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov):

```sh
cargo +stable install cargo-llvm-cov --locked
cargo +stable install cargo-llvm-cov --version 0.6.16 --locked
```

3. Use the same nightly toolchain for the target crate. The analysis tools handle `lib` and `bin` targets.
Expand Down Expand Up @@ -64,11 +64,11 @@ Run `docker/docker-run` from the same directory to mount the repository at `/hom

## Workflow

Run `cargo brinfo` in the target crate, then run `focxt -c <target-crate-path>` to extract condition chains and context. The current `utgen analyze` command only logs its arguments; these analysis steps must be run explicitly.
On a fresh working copy of a standalone crate, run `utgen pre-process -p <target-crate-path>` before `utgen analyze -p <target-crate-path>`. Analysis clears Cargo's check cache, runs brinfo and focxt, and verifies their outputs. It rejects existing `brinfo/` or `focxt/` directories so previous analysis results cannot be mixed into the run.

Use `utgen pre-process`, `utgen gen`, and `utgen fix` for preprocessing, generation, and compilation repair. Pass `--requirement --context` to `utgen gen` to include path constraints and focal context. Preprocessing and test checks modify the target tree; use a working copy of the target project.
Then use `utgen gen` and `utgen fix` for generation and compilation repair. Pass `--requirement --context` to `utgen gen` to include path constraints and focal context. Preprocessing and test checks modify the target tree; use a working copy of the target project.

See the [bytes example](examples/README.md) and [utgen usage](utgen/README.md) for the commands and result locations.
Start with the [minimal pipeline check](docs/minimal-pipeline.md), which uses fixed local model responses and verifies analysis, generation, repair, source restoration, and coverage. The [bytes example](examples/README.md) remains a larger follow-up target. See [utgen usage](utgen/README.md) for command details.

## Development checks

Expand All @@ -79,7 +79,7 @@ cargo build --workspace --locked
cargo test --workspace --locked
```

Default tests use local model-response fixtures and do not contact a model service. The real-service test is opt-in; see [utgen testing](utgen/README.md#testing). Dependency downloads may still require network access. [Build validation](docs/build-validation.md) records the baseline and checks performed; the GitHub Actions workflow runs the basic checks on Linux.
Default tests use local model-response fixtures and do not contact a model service. The real-service test is opt-in; see [utgen testing](utgen/README.md#testing). Dependency downloads may still require network access. [Build validation](docs/build-validation.md) records the baseline and checks performed; the GitHub Actions workflow runs these checks and the minimal pipeline on Linux.

## Documentation

Expand Down
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ PALM's implementation, technical guide, and conference materials are available i
| --- | --- |
| [Project README](../README.md) | Prerequisites, installation, and workspace layout. |
| [Technical guide in Chinese](palm-rust-unit-test-generation.md) | Condition chains, context construction, generation, repair, and usage. |
| [Minimal pipeline](minimal-pipeline.md) | Deterministic program-analysis, generation, repair, and coverage validation. |
| [bytes example](../examples/README.md) | Commands for analyzing a working copy of the bundled target. |
| [utgen reference](../utgen/README.md) | Configuration, CLI behavior, and output files. |
| [ASE 2025 materials](ase2025/README.md) | Original poster and presentation PDFs. |
Expand Down
6 changes: 3 additions & 3 deletions docs/build-validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ The installer retains Cargo output, uses the repository directory to select its

The proxy regression configures only child-process environments, so parallel tests do not change one another's environment. The ordinary LLM constructor retains the SDK's default proxy behavior. The fixtures inject a separate HTTP client with proxies disabled. A test-only `reqwest` dependency reuses the existing locked version; dependency versions, checksums, and lockfile format were not changed.

The [GitHub Actions workflow](../.github/workflows/ci.yml) configures the build, default tests, CLI help checks, installer syntax/help, and standalone bytes metadata checks on Ubuntu 24.04. Its YAML was parsed locally. A hosted workflow run remains to be verified after publication; this document does not claim a Linux CI pass.
The [GitHub Actions workflow](../.github/workflows/ci.yml) configures the build, default tests, CLI help checks, installer syntax/help, and standalone bytes metadata checks on Ubuntu 24.04. Its YAML was parsed locally. The [Linux branch run](https://github.com/cppbear/PALM/actions/runs/37619301888) and [PR run](https://github.com/cppbear/PALM/actions/runs/37619401144) passed before [PR #5](https://github.com/cppbear/PALM/pull/5) was merged. Subsequent pipeline validation is recorded in [minimal pipeline](minimal-pipeline.md).

## Validation Limits and Next Batch

- No real model service was contacted. Local fixtures validate request construction and response handling, not model compatibility or generation quality.
- The tests added here do not exercise preprocessing correctness, focal-context completeness, generated-test insertion, compilation repair, or coverage measurement end to end.
- Docker was not built: the local Docker daemon was unavailable. Linux runtime validation remains pending.
- Docker was not built: the local Docker daemon was unavailable. The basic Linux CI passed; the Docker image itself remains unverified.
- The pinned toolchain and existing dependency versions were retained; `Cargo.lock` adds only the test dependency edge described above. Compatibility of the coverage tool and target-crate dependencies needs separate verification.
- `utgen analyze` remains a logging-only command. Request concurrency, source restoration, cache validity, and coverage-baseline semantics are unchanged.
- At this baseline, `utgen analyze` was a logging-only command. The following batch connects analysis and adds a minimal end-to-end check; see [minimal pipeline](minimal-pipeline.md). Concurrency, general recovery, and cache invalidation remain follow-up work.

The next batch should use a small target crate to verify the relationship between prepared source files, analysis locations, function identities, focal context, and generated tests. It should establish failure propagation and coverage semantics before proceeding to a large bytes run.
47 changes: 47 additions & 0 deletions docs/minimal-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Minimal Pipeline Validation

This batch follows the [build and configuration baseline](build-validation.md), merged through [PR #5](https://github.com/cppbear/PALM/pull/5). It validates one standalone crate with fixed local model responses, the pinned nightly, and `cargo-llvm-cov 0.6.16`.

## Run the Check

From the repository root:

```sh
cargo build --workspace --locked
cargo +stable install cargo-llvm-cov --version 0.6.16 --locked
python3 scripts/check_minimal.py
```

No model credentials are required. The model endpoint is a temporary loopback HTTP server owned by the script; target commands receive only a dummy key. Dependency downloads may require network access.

The script prints the temporary directory containing source copies, command logs, model-request counts, coverage, and generated results. Use `--work-dir <new-directory>` to select it, `--bin-dir <directory>` for a custom tool build directory, or `--analysis-only` to stop before coverage/generation. Work directories must be new. The [fixture](../examples/minimal/README.md) is never modified.

## Verified Contracts

- Original tests run on an untouched copy. A separate prepared copy is used for generated tests.
- Preprocessing removes test-only source ranges while preserving newlines and byte offsets, including a test and production function sharing one line. Repeating preprocessing is idempotent.
- `utgen analyze` succeeds even after a prior `cargo check`, since it clears the check cache before invoking the compiler wrapper. It rejects existing analysis output directories.
- brinfo and focxt agree on five complete function names. Source locations identify the exported focal code, accounting for brinfo's indentation normalization.
- The `Gauge::label` context contains its struct, the focal method, and the declarations for `classify`, `positive`, and the transitive `threshold` dependency.
- Missing context and malformed source locations fail before generation changes the manifest or source files. Source-location parse errors no longer panic.
- Six model responses produce six candidate tests. One candidate deliberately passes a string to an integer parameter and fails compilation; a numbered ChangeLog response repairs it through the actual repair path.
- Both branches of `classify` are covered. Before repair, the intentionally invalid `double` candidate has zero compilable tests. After repair, all candidates compile and pass.
- Source files and the target manifest match their prepared state after generation and repair; no source backup remains after successful completion.

The regression script runs in Linux CI after the ordinary workspace tests. It uses the real analyzers, compiler, coverage tool, prompt builder, response parser, candidate checks, and repair machinery. Model replies are deterministic fixtures; these results do not measure LLM quality.

## Coverage Interpretation

`original/original-coverage.json` measures all original unit and integration tests on the untouched copy. The check requires both original `classify` branches to have executed.

`generated/utgen/result/` and `generated/utgen/fixed_result/` contain the tool's per-function statistics for generated candidates. The script checks the known branch count and execution outcomes directly. The separate legacy `utgen/original_result.json` restores only the integration-test backup; it must not be presented as coverage of all original tests. Combined original-plus-generated coverage is not part of this check.

## Changes and Limits

`utgen analyze` now invokes the tools and validates their artifacts. Its supported scope is one standalone crate with `Cargo.toml` and `src/`. Generation rejects incomplete indices/context and propagates failed asynchronous generation tasks. Repair validates the analysis and pre-repair JSON before starting.

The preprocessor parses `cfg` predicates conservatively, preserves `cfg(not(test))` and unknown production features, handles nested test ranges and UTF-8 safely, and refuses to overwrite `tests.bak`. Whitespace replacement preserves bytes/newlines, not necessarily character columns inside removed UTF-8 ranges; analysis runs after preprocessing.

Recursive context lookup now resolves full function names through the compiler's encoded-name index and consumes the accumulated dependencies. External functions without local artifacts remain outside this source context.

The local macOS/Apple Silicon run passed using six generation responses and one repair response. Real-model behavior, bytes-scale execution, general multi-crate support, request concurrency limits, hard process timeouts, recovery after forced termination, and parameter-aware cache invalidation remain later work. Git history is retained.
60 changes: 32 additions & 28 deletions docs/palm-rust-unit-test-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,12 @@ Rust 的一个核心挑战是 MIR 的去糖。比如高级语法 `match color`

```text
utgen pre-process --project-dir <PROJECT_DIR> [--work-dir <WORK_DIR>...]
utgen analyze --project-dir <PROJECT_DIR> [--work-dir <WORK_DIR>...]
utgen analyze --project-dir <STANDALONE_CRATE_DIR>
utgen gen --project-dir <PROJECT_DIR> [--work-dir <WORK_DIR>...] [--tasks <N>] [--integration] [--requirement] [--context] [--oracle]
utgen fix --project-dir <PROJECT_DIR> [--work-dir <WORK_DIR>...] [--tasks <N>]
```

注意:`analyze` 子命令目前只打印日志,没有实际调用 `cargo brinfo` 或 `focxt`。实际运行时仍需要手动执行分析步骤。
`analyze` 现在执行 `cargo clean`、`cargo brinfo` 和 `focxt`,随后核对分析索引及上下文文件。当前支持用 `-p` 指定单个独立 crate;目录中已有 `brinfo/` 或 `focxt/` 时会拒绝执行,应使用新的工作副本,避免混入旧分析结果。

参数含义:

Expand Down Expand Up @@ -466,7 +466,7 @@ rustup component add --toolchain nightly-2025-03-19 rust-src rustc-dev llvm-tool
安装覆盖率工具:

```sh
cargo +stable install cargo-llvm-cov --locked
cargo +stable install cargo-llvm-cov --version 0.6.16 --locked
```

目标 crate 根目录建议包含:
Expand Down Expand Up @@ -523,41 +523,47 @@ focxt --help
utgen --help
```

### 10.3 对目标 crate 运行程序分析

进入目标 crate 根目录,先提取条件链:
### 10.3 预处理项目

```sh
cargo clean
cargo brinfo
utgen pre-process -p <target-crate-path>
```

然后构建上下文:
如果项目是 workspace 或需要只处理部分子目录:

```sh
focxt -c <target-crate-path>
utgen pre-process -p <project-root> -w <work-dir-1> -w <work-dir-2>
```

`focxt` 内部会运行 `cargo call-chain`,因此需要先安装 `focxt/call_chain`。
预处理会:

- 将所选 crate 根目录的 `tests` 重命名为 `tests.bak`;已有备份不会被覆盖。
- 将 `src` 中测试专属模块,以及带 `#[test]` 或路径末段为 `test` 的属性的函数替换为空白,保持换行和字节位置。

模块识别解析 `cfg` 表达式,仅移除能确定在关闭 `test` 时不可用的模块;保留 `cfg(not(test))`,对未知 feature/target 条件保守处理。预处理修改目标项目源码树,没有完整的反向预处理命令,应在临时副本中运行。先预处理,再对准备好的源码分析;空白替换保持字节位置,UTF-8 字符列号仍应以处理后的源码为准。`-w` 的相对路径基于当前命令执行目录。

### 10.4 预处理项目
### 10.4 对目标 crate 运行程序分析

预处理后,推荐对新的独立 crate 副本执行:

```sh
utgen pre-process -p <target-crate-path>
utgen analyze -p <target-crate-path>
```

如果项目是 workspace 或需要只处理部分子目录:
也可以手动进入准备好的目标 crate 根目录提取条件链。已有 `cargo check` 缓存可能使编译器包装器不执行,因此需要先清理:

```sh
utgen pre-process -p <project-root> -w <work-dir-1> -w <work-dir-2>
cargo clean
cargo brinfo
```

预处理会:
然后构建上下文:

- 将已有 `tests` 目录重命名为 `tests.bak`。
- 注释 `src` 下被识别为测试模块的模块,以及带 `#[test]` 或路径末段为 `test` 的属性的函数。
```sh
focxt -c <target-crate-path>
```

模块识别使用 `cfg` 属性文本中是否包含 `test` 的判断,不是对任意条件编译表达式求值。预处理会修改目标项目源码树,且没有完整的反向预处理命令,建议在临时副本中运行。`-w` 的相对路径基于当前命令执行目录。
`focxt` 内部会运行 `cargo call-chain`,因此需要先安装 `focxt/call_chain`。

### 10.5 生成测试

Expand Down Expand Up @@ -608,20 +614,18 @@ export PALM_CONFIG="$palm_repo/utgen/res/api.json"
palm_example_dir="$(mktemp -d "${TMPDIR:-/tmp}/palm-bytes.XXXXXX")"
cp -R "$palm_repo/examples/bytes/." "$palm_example_dir/"
cd "$palm_example_dir"
cargo clean
cargo brinfo
focxt -c "$palm_example_dir"
utgen pre-process -p "$palm_example_dir"
utgen analyze -p "$palm_example_dir"
```

按单元测试模式生成和修复:

```sh
utgen pre-process -p "$palm_example_dir"
utgen gen -p "$palm_example_dir" --requirement --context
utgen fix -p "$palm_example_dir"
```

切换到 integration、其他提示词或其他模型时,使用新的目标副本并重新分析,避免复用旧的生成缓存。更详细的示例见 [examples/README.md](../examples/README.md)。
切换到 integration、其他提示词或其他模型时,使用新的目标副本并重新分析,避免复用旧的生成缓存。更详细的示例见 [examples/README.md](../examples/README.md)。当前完整回归使用 [minimal 示例](minimal-pipeline.md);bytes 的完整运行仍是后续验证项。

完成后重点查看临时目标目录中的以下路径:

Expand Down Expand Up @@ -670,11 +674,11 @@ focxt/impl_informations.json
focxt/<encoded>.rs
```

缺少时按顺序重新运行:
缺少或不一致时,生成器会在修改目标文件之前报错。请准备新的目标副本,再按顺序执行:

```sh
cargo brinfo
focxt -c <target-crate-path>
utgen pre-process -p <new-target-copy>
utgen analyze -p <new-target-copy>
```

### 11.5 集成测试生成数量少
Expand All @@ -685,7 +689,7 @@ integration 模式先按 `brinfo` 的 `visible` 标志筛选函数,并且 `utg

会修改目标项目的步骤包括:

- `utgen pre-process`:重命名 `tests`,注释已有测试。
- `utgen pre-process`:重命名所选 crate 的 `tests`,将测试源码区间替换为空白。
- `utgen gen`:可能追加 `ntest` 依赖,写入临时测试文件或插入测试做编译检查。
- `utgen fix`:临时插入测试并恢复,结束时删除备份。

Expand Down
14 changes: 7 additions & 7 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Examples

Start with the [minimal pipeline](../docs/minimal-pipeline.md) for an automated, no-credentials validation. The commands below describe the larger bytes target; the complete pipeline is currently regression-tested on the minimal crate.

## bytes

The bundled target is [tokio-rs/bytes](https://github.com/tokio-rs/bytes), version 1.10.0. It is excluded from PALM's tool workspace and retains its own source files, tests, and license.
Expand All @@ -10,7 +12,7 @@ Follow the [root installation instructions](../README.md#installation), includin

### Prepare a Working Copy

Preprocessing comments out existing tests and renames test directories. Generation can add `ntest` to the target's Cargo.toml, and compilation checks temporarily insert tests. Use a separate copy to preserve the bundled example.
Preprocessing blanks existing test source ranges and renames test directories. Generation can add `ntest` to the target's Cargo.toml, and compilation checks temporarily insert tests. Use a separate copy to preserve the bundled example.

Run the following from the PALM repository root, keeping the same shell for subsequent commands:

Expand All @@ -22,20 +24,18 @@ cp -R "$palm_repo/examples/bytes/." "$palm_example_dir/"
cd "$palm_example_dir"
```

### Extract Information
### Preprocess and Analyze

```sh
cargo clean
cargo brinfo
focxt -c "$palm_example_dir"
utgen pre-process -p "$palm_example_dir"
utgen analyze -p "$palm_example_dir"
```

The last command also runs `cargo call-chain`. The `utgen analyze` subcommand does not currently perform these analysis steps.
Analysis runs brinfo and focxt (including call-chain) on the prepared source. If a function lacks corresponding context, generation reports the missing artifact; support for larger targets is still being validated.

### Generate and Repair Unit Tests

```sh
utgen pre-process -p "$palm_example_dir"
utgen gen -p "$palm_example_dir" --requirement --context
utgen fix -p "$palm_example_dir"
```
Expand Down
7 changes: 7 additions & 0 deletions examples/minimal/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/target/
/brinfo/
/focxt/
/utgen/
/tests.bak/
/coverage.*
/error_output.json
Loading
Loading