Skip to content

Run Test and Debug execute the code in different working directories #4705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
balintbalazs opened this issue Jun 2, 2020 · 10 comments
Closed
Labels
E-easy S-actionable Someone could pick this issue up and work on it right now

Comments

@balintbalazs
Copy link

In certain cases the vscode Run Test and Debug buttons execute the code in different working directories.

In this example I have a workspace in the C:\Dev\rust\rust-project folder, and a crate inside called metadata.

For this test in C:\Dev\rust\rust-project\metadata\lib.rs:

#[test]
fn pwd() {
    let working_dir = std::env::current_dir().unwrap();
    println!("{}", working_dir.display());
}

when clicking Run Test I get the following output:

running 1 test
C:\Dev\rust\rust-project\metadata
test tests::pwd ... ok

But when clicking the Debug option it prints:

running 1 test
C:\Dev\rust\rust-project
test tests::pwd ... ok

This behavior can be fairly inconvenient when the test code needs to read some files, so it would be great if it would be consistent.

Thanks!

@matklad
Copy link
Member

matklad commented Jun 3, 2020

cc @vsrs

I think we should always execute the code with cwd set to the worksapce_root.

@matklad matklad added the E-easy label Jun 3, 2020
@vsrs
Copy link
Contributor

vsrs commented Jun 3, 2020

At the moment runSingle uses runnable.workspaceRoot and debugSingle does not. I'll fix this.

@vsrs
Copy link
Contributor

vsrs commented Jun 3, 2020

Hm, turns out it is not so easy. Both commands correctly set cwd to runnable.workspaceRoot || '.'.

So we just see how Cargo works with virtual workspaces:
cargo test --package metadata --lib -- pwd --exact --nocapture command spawns 3 processes:

executable arguments cwd
~/.cargo/bin/cargo test --package metadata --lib -- pwd --exact --nocapture ${workspaceRoot}
~/.rustup/toolchains/<toolchain>/bin/cargo test --package metadata --lib -- pwd --exact --nocapture ${workspaceRoot}
${workspaceRoot}/target/debug/deps/metadata-34fd8c2a238a9d90 pwd --exact --nocapture ${workspaceRoot}/metadata

So it is Cargo who sets cwd for metadata-34fd8c2a238a9d90. I think the root is here:
https://github.com/rust-lang/cargo/blob/7302186d7beb2b11bf7366c0aa66269313ebe18f/src/cargo/ops/cargo_test.rs#L83

And looks like there is no way to control this behavior and better not to use cwd in tests at all.

CARGO_MANIFEST_DIR for the third process is also ${workspaceRoot}\metadata. Maybe we can add CARGO_WORKSPACE_ROOT_DIR, pointing to the virtual workspace root? Or even do it upstream in the Cargo.

@popzxc
Copy link
Contributor

popzxc commented Sep 13, 2020

I'm unable to reproduce it. It seems it was fixed.

@lnicola lnicola added the S-actionable Someone could pick this issue up and work on it right now label Jan 17, 2021
@sasurau4
Copy link
Contributor

I confirm this issue fixed with the same situation of @balintbalazs .

cargo --version
cargo 1.49.0 (d00d64df9 2020-12-05)

rustc --version
rustc 1.49.0 (e1884a8e3 2020-12-29)

@lnicola lnicola closed this as completed Jan 22, 2021
@gilescope
Copy link
Contributor

I'm getting this issue on vscode/nixos. Personally it seems like the play is getting it right and the debug is choosing the root dir of the workspace. Ideally it should do the same thing as cargo does.

@Marko-Vujnovic
Copy link

Marko-Vujnovic commented May 2, 2022

I'm still affected by this. The behavior is exactly the same as described in the OP.

# cargo --version
cargo 1.62.0-nightly (e2e2ddd 2022-04-05)
# rustc --version
rustc 1.62.0-nightly (e745b4ddb 2022-04-07)

@NiceneNerd
Copy link

I have the same issue as well. Makes relative paths in tests very complicated.

@johannescpk
Copy link

johannescpk commented Sep 29, 2022

Workaround cargo launch configuration to emulate the debug link in a workspace, with correct cwd, that worked for me:

    {
      "type": "lldb",
      "request": "launch",
      "name": "Cargo test test-file-name",
      "cargo": {
        "args": [
          "test",
          "-p",
          "workspace-package-name",
          "--test",
          "test-file-name",
          "--no-run"
        ],
        "filter": { "name": "test-file-name" }
      },
      "program": "${cargo:program}",
      "args": ["--nocapture"],
      "cwd": "${workspaceFolder}/crates/workspace-package-name"
    },

Needs to be configured per test, so workspace-package-name and test-file-name need to be adjusted. If you want to run one specific test in the test file, add args accordingly.

Resources

@d00z3l
Copy link

d00z3l commented May 10, 2023

I have struggled with the same issue, I wanted to use a relative path for a source file for my tests and have it work using run/debug in VS Code and also using cargo test --all. My workaround is as follows:

  1. Create a local settings.json file, i.e. ./.vscode/settings.json
  2. Add the following to the settings file:
{
    "rust-analyzer.runnableEnv": {
        "ENV_ROOT_DIR": "${workspaceFolder}"
    }
}
  1. Create a test function create the path:
    pub fn test_data_path() -> String {
        static FILE_PATH : &str = "./tests/my-file-name.csv";
        match std::env::var("ENV_ROOT_DIR") {
            Ok(path) => {
                Path::new(&path).join(FILE_PATH).display().to_string()
            },
            Err(_) => {
                Path::new(&std::env::current_dir().unwrap()).join("../").join(FILE_PATH).display().to_string()
            }
        }
    }

ENV_ROOT_DIR is used in VS Code and the working directory for cargo test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-easy S-actionable Someone could pick this issue up and work on it right now
Projects
None yet
Development

No branches or pull requests