Skip to content
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

main_binary takes ~300ms per invocation #6

Closed
epage opened this issue May 28, 2018 · 16 comments · Fixed by #69
Closed

main_binary takes ~300ms per invocation #6

epage opened this issue May 28, 2018 · 16 comments · Fixed by #69
Labels
bug Not as expected

Comments

@epage
Copy link
Contributor

epage commented May 28, 2018

From @rcoh assert-rs/assert_cli#100

  • assert_cli version: 0.5
  • Rust version: 1.25.0
  • OS and version: Ubuntu 16.04
    Unfortunately, cargo run takes at minimum about 300ms on my computer:
➜  angle-grinder git:(master) ✗ time cargo run --bin agrind -- '* | json | count' --file test_files/empty
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/agrind '* | json | count' --file test_files/empty`
No data
cargo run --bin agrind -- '* | json | count' --file test_files/empty  0.22s user 0.06s system 92% cpu 0.307 total

It makes it impractical to run hundreds of integration tests with assert_cli.

I'm not positive what a better way would be -- I guess running the binary in dist directly if it exists?

Workaround

See assert_cmd::cargo's docs

@epage epage added the bug Not as expected label May 28, 2018
@epage
Copy link
Contributor Author

epage commented May 28, 2018

From killercup: cargo issue: rust-lang/cargo#5315

@epage
Copy link
Contributor Author

epage commented May 29, 2018

So a user can work around this in assert_cmd by accessing cargo_bin_path, etc. This causes the 300ms to only be hit once instead of on every run.

lazy_static! {
    const BIN_UNDER_TEST = assert-cmd::cargo_bin_path("bin_fixture");
}

#[test]
fn test_bin() {
    Command::new(BIN_UNDER_TEST).assert().success();
}

Should we provide an API on to simplify this?

Example

lazy_static!{
   const BIN_FIXTURE = assert_cmd::cargo_bin("bin_fixture");
}
...
println!("{:?}", BIN_FIXTURE.path());
BIN_FIXTURE.cmd().arg("stdout", 42).unwrap();

@epage epage changed the title Takes ~300ms to run 1 invocation main_binary takes ~300ms to run 1 invocation May 29, 2018
@zetok
Copy link

zetok commented Jul 24, 2018

Additions to API aren't needed, but docs that would point out this functionality would be really helpful. Since right now one needs to go to the issue tracker of the crate to find the solution, which is suboptimal.

As for why an additional API is not needed – e.g. regex crate doesn't have an additional API for creating a static regexp, but it has a great documentation where it shows on the "main" page of its docs an example on how to use lazy_static to reduce unnecessary computations. It's nice.

Also, a working example, freshly ~copypasted from a test for anyone else who's interested:

use std::path::PathBuf;

lazy_static! {
    static ref BIN_PATH: PathBuf = assert_cmd::cargo::main_binary_path().unwrap();
}

#[test]
fn test_bin() {
    Command::new(&*BIN_PATH).assert().success();
}

@epage
Copy link
Contributor Author

epage commented Jul 25, 2018

As for why an additional API is not needed – e.g. regex crate doesn't have an additional API for creating a static regexp

The difference is the main purpose of this crate is running programs. Its a bit of a wart in the API to have functions that provide paths to programs you could run. It'd be nice if Command supported clone.

epage added a commit to epage/assert_cmd that referenced this issue Jul 27, 2018
epage added a commit to epage/assert_cmd that referenced this issue Jul 27, 2018
epage added a commit to epage/assert_cmd that referenced this issue Jul 27, 2018
mssun pushed a commit to mesalock-linux/mesabox that referenced this issue Aug 2, 2018
According to this issue: assert-rs/assert_cmd#6.
This also potentially solves lock issue in Travis.
mssun pushed a commit to mesalock-linux/mesabox that referenced this issue Aug 2, 2018
According to this issue: assert-rs/assert_cmd#6.
This also potentially solves lock issue in Travis.
@epage
Copy link
Contributor Author

epage commented Oct 6, 2018

I think at this point this is mostly kept open to track and be aware of the slow down. We have workarounds but thats all they are.

@killercup
Copy link
Contributor

killercup commented Oct 7, 2018 via email

@rcoh
Copy link

rcoh commented Oct 7, 2018

@killercup , I just reran the original example that started everything. On the same laptop with nightly, it takes 125ms, so twice as fast as before. A big enough change that it actually feels way faster 👍

cargo 1.31.0-nightly (ad6e5c003 2018-09-28)

@epage
Copy link
Contributor Author

epage commented Oct 8, 2018

Good idea. I should add a benchmark that compares running the underlying program against running it via cargo.

@epage
Copy link
Contributor Author

epage commented Oct 10, 2018

More data

test escargot_rebuild ... bench: 368,686,700 ns/iter (+/- 64,925,719)

@sharkdp
Copy link

sharkdp commented Nov 1, 2018

I think we might have run into a related issue in bat. I tried to implement the workaround but couldn't quite figure it out as some of the referenced functions are not available anymore(?). Is there still a workaround for this?

@epage
Copy link
Contributor Author

epage commented Nov 1, 2018

@sharkdp sorry, I have been maintaining the work around in the docs but forgot to update this issue. I've done so now.

@sharkdp
Copy link

sharkdp commented Nov 2, 2018

@epage Thank you very much! Sorry for not checking the documentation.

If I understand this correctly, this will still potentially compile (part of) the project in the first unit test, right?

(link to my current implementation: sharkdp/bat#398)

@epage
Copy link
Contributor Author

epage commented Nov 2, 2018

If I understand this correctly, this will still potentially compile (part of) the project in the first unit test, right?

To get the path, it will still need to call into cargo. Whether anything builds is a different question. If you match target/release with what you are building, then it should reuse what was built before.

I recommend passing in current_release. An unfortunate thing is if you pass in current_target and you did not pass --target into cargo test, then it will rebuild everything on first test. There was no good answer between correctness and performance, so the default for Command::main_bin and the workaround in the docs is current_target

@sharkdp
Copy link

sharkdp commented Nov 4, 2018

@epage Thank you very much for the explanation.

@sourcefrog
Copy link

sourcefrog commented Nov 4, 2018

On Windows, for my program conserve, switching to assert_cmd from my own hacky code seems to have increased the overall test time from ~3:00 to ~4:00.

https://ci.appveyor.com/project/sourcefrog/conserve/builds/20036005

I think it'd at least be nice if this was more prominent in the docs top-level page, where there are examples of using the crate.

@epage epage changed the title main_binary takes ~300ms to run 1 invocation main_binary takes ~300ms per invocation Nov 5, 2018
@epage
Copy link
Contributor Author

epage commented Nov 5, 2018

@sourcefrog looking at your log, it looks like you are more so having problems with #57 (realized I should create a dedicated issue rather than pointing people to #4).

#57 does need to be mentioned in the docs but I'm unsure if the top-level docs are appropriate for each workaround or special case. I also noticed that this issue's workaround is only mentioned in the cargo module and not on the trait or functions. If someone jumps straight to one of those, they need to be aware of these workarounds.

I've created #58 to document the workaround and try to find a way to improve visibility.

epage added a commit to epage/assert_cmd that referenced this issue Jan 26, 2019
This is an experiemnt in a new direction in trying to resolve
- Cargo overhead (assert-rs#6)
- Compile times from mismatched `--target` (assert-rs#57)
- Suprising behavior if `--target <triplet>` isn't specified (assert-rs#4)

The new downsides this introduces
- No `main_binary` or `cargo_example`
- Can only work within integration tests

We're recommending the use of `escargot` in these cases which I think
might be reasonable because instead of making policy decisions for the
user, and no one ever being happy, the user can choose which policy they
want.  Plus, in more complex cases they should already be using
`escargot` so they can cache.

Fixes assert-rs#6
Fixes assert-rs#57
epage added a commit to epage/assert_cmd that referenced this issue Jan 26, 2019
This is an experiemnt in a new direction in trying to resolve
- Cargo overhead (assert-rs#6)
- Compile times from mismatched `--target` (assert-rs#57)
- Suprising behavior if `--target <triplet>` isn't specified (assert-rs#4)

The new downsides this introduces
- No `main_binary` or `cargo_example`
- Can only work within integration tests

We're recommending the use of `escargot` in these cases which I think
might be reasonable because instead of making policy decisions for the
user, and no one ever being happy, the user can choose which policy they
want.  Plus, in more complex cases they should already be using
`escargot` so they can cache.

Fixes assert-rs#6
Fixes assert-rs#57

BREAKING CHANGE: `main_binary` / `cargo_example` no longer exist.  Also,
successfully running `cargo_bin` has been restricted to integration
tests.
@epage epage closed this as completed in #69 Jan 27, 2019
epage added a commit that referenced this issue Oct 5, 2023
…holder

README.md 'Crates Status' icon link
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Not as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants