Skip to content

Two tests assume a platform capability they do not have on Windows (POSIX shell, symlink privilege) #210

Description

@dajiaohuang

Summary

Two tests assert behavior that depends on a capability the host does not have on Windows, so they fail with an environment error rather than an assertion about the code. Both are gated nowhere, and neither can fail in CI because ci.yml runs on ubuntu-latest only.

I am reporting them together because the shared shape is "the test needs a platform capability" — each has its own one-line fix, and they live in different packages, so feel free to split them.


1. tools::tests::bash_stderr_keeps_the_tail assumes a POSIX shell

crates/host-core/src/tools/mod.rs:2902 runs a POSIX command and asserts on its stderr:

let result = execute_tool(Some(ws.path()), None, "Bash",
    &serde_json::json!({
        "command": format!("seq 1 {lines} >&2; printf 'error: the real problem\n' >&2; exit 2")
    }), 30_000).await;
...
assert!(stderr.trim_end().ends_with("error: the real problem"), ...);

On Windows the resolved shell is PowerShell, so the command never reaches a POSIX parser:

thread 'tools::tests::bash_stderr_keeps_the_tail' panicked at tools/mod.rs:2926:
tail retained: "  : ParserError: (:) [], ParentContainsErrorRecordException\r\n    + FullyQualifiedErrorId : MissingFileSpecification\r\n \r\n"

The shell is config.program from read_runner_config (tools/mod.rs:389), i.e. platform-selected — the suite already knows this, since it carries a sibling powershell_preserves_utf8_errors_quotes_cwd_and_native_exit_codes test at tools/mod.rs:4138.

Suggested fix: #[cfg(unix)] on this test, mirroring how the suite already gates symlink tests, or port the command to something both shells accept. The stderr-tail truncation logic it covers is shell-independent, so a PowerShell sibling would keep the coverage on Windows.


2. plugin-devkit test needs SeCreateSymbolicLinkPrivilege

packages/plugin-devkit/src/templates.test.ts:213:

it("rejects symlinks, which host-core refuses to copy", async () => {
    const dir = await scaffolded("panel-basic");
    await symlink(join(dir, "main.js"), join(dir, "link.js"));
    expect((await check(dir)).errors.map((e) => e.code)).toContain("package.symlink");
});

pnpm test on Windows:

FAIL  src/templates.test.ts > check > rejects symlinks, which host-core refuses to copy
Error: EPERM: operation not permitted, symlink
  'C:\Users\...\Temp\pi-devkit-ESn7Tf\plugin\main.js' -> 'C:\Users\...\Temp\pi-devkit-ESn7Tf\plugin\link.js'

Creating a file symlink on Windows requires Developer Mode or elevation. Verified on the reporting host: fs.symlinkSync for a file returns EPERM, while fs.symlinkSync(..., 'junction') succeeds — and Node reports a junction through Dirent.isSymbolicLink() === true, which is the branch walkPluginDir tests (packages/plugin-devkit/src/walk.ts:104). Rust's FileType::is_symlink() sees junctions too, so copy_dir_filtered (crates/host-core/src/plugins.rs:2342) still refuses them.

The affected code path is a real install gate — a package containing a link must never install — so losing Windows coverage of it is worth avoiding.

Suggested fix: try the file symlink first and fall back to a directory junction when the platform refuses it (skipping only if both fail), so the assertion still runs on Windows. A plain skipIf on process.platform === 'win32' also works but drops the coverage on Developer-Mode machines. Note the repo already gates the Rust equivalent with #[cfg(unix)] (crates/host-core/src/db.rs:2503), which is why the TS side has no counterpart.


Environment

PI-Desktop 6e6d710e (main), Windows 10 Pro N 19045, Node 24.14.1, pnpm 11.18.0, rustc/cargo 1.98.1.

Related: #208 and #209 cover the other Windows failures in the same suites (different root causes, filed separately).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: platformOperating-system and environment-specific behaviorbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions