-
Notifications
You must be signed in to change notification settings - Fork 45
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
Running skeptic tests are slow #8
Comments
Hi @Marwes. Thanks for the report. The first thing that can be done is have That should prevent cargo from regenerating the tests each invocation, and in turn building the generated tests. That won't help the scenario where you change one markdown file and all the tests get regenerated and then rebuilt. Fixing that would require some design tweaks: basically the single Figuring out how to create that design without imposing too much burden on the end-user (i.e. without requiring them to create a |
Seems simple enough but I don't think that is enough to prevent recompilation if the markdown is not changed as the generated test is actually an executable which generates the tests which will be recompiled. Looking at this excerpt from the generated tests.
And run_test when running Why is the tests generated (from the already generated file) instead of just existing in the first file?
Yeah that seems trickier and having fast rebuilds after modifying documentation does not seem as important so I will probably skip that. |
Or is the reason for generating the tests individually to keep compilation errors from different tests from interacting from each other? Maybe just compile tests should be generated in that case? |
Ah, I forgot that the tests recompiled dynamically. Yeah, I believe you are right that the reason it is that way is so that failure to compile the test cases are themselves errors at runtime and cause test failures, not compile-time failures. AFAIK this is how rustdoc deals with its test cases as well, for the same reason, but I could be misremembering. I wonder if you've noticed a difference in perceived performance between rustdoc and rust-skeptic.
Can you expand on this? I don't quite understand what 'compile tests' or 'that case' refer to here. If we keep this model where the test cases are recompiled each test run, the simplest way I see to avoid the recompile is to have |
Tests that check if code compiles or not ie compile_test instead of |
Rustdoc does the same thing. I actually remember being annoyed at that in combine which has 44 doc tests which all get recompiled every time. It was still less noticeable there however as that library is much smaller than gluon. In gluon I don't really have that many doc tests at the moment so I hadn't noticed it. |
Haha, of course. Does my previous suggestion for how to fix this with caching sound reasonable? Are you interested in implementing? |
I think I will at least make the change to add Caching for |
Implemented a partial fix in #9. I do not cache the artifacts generated by the generated test file. The reason for that is that it would both be quite a bit more complicated since it can't piggyback on the caching that cargo does. Also, a large part of that overhead is that each test is generated separately. I tried changing it so that normal #[test] fn readme_0() {
<test>
} instead of #[test] fn readme_0() {
let ref s = format!(<template string>, <test string>);
skeptic::rt::run_test(r#"C:\Users\Markus\Dropbox\Programming\gluon\c-api\target\debug\build\gluon-a225c2b4679cfb91\out"#, s);
} |
This fixes two major issues with skeptic's current implementation at the cost of losing compile-fail tests. For many crates I expect this to be a worthwhile tradeoff. It is possible to restore compile-tests but they would be forced to use the same shelling out approach as before this PR so they would suffer from the same problem. As such I prefer to keep them out instead. No longer shells out to rustc and attempts to emulate cargo's dependency resolution. Fixes budziq#18 Tests are now in a normal test module letting cargo cache and reuse compilation artifacts as normal. Fixes budziq#8 BREAKING CHANGE - Handlebars templates are now used instead of `format!` Since there is no intermediate step we need a way to dynamically template. Handlebars is well known and well supported. - Compile tests that expect panics are not supported Since code is generated inline, these tests would cause test compilation to fail
I think an improvement we can make here is to parse the manifest file just once. Currently, every single (There are at least 3 invocations, and I think there are several more.) |
@Phlosioneer I doubt that is a big problem, as I measured, it is the fact that rustc gets invoked once for each skeptic test and therefore generates one executable for each tests which makes it so slow. |
Alright, as long as it's been checked. |
Yep while the current manifest handling scheme is suboptimal it does not contribute significantly to the whole test execution time. As @Marwes mentioned, the rustc invocations are the killer here. But if anyone would like to take a stab at rewriting the manifest handling logic, I'm all for it :) |
I've started hacking on a fix for #18 that I thought would fix this, but looks like it won't. The "every test case is an executable" behavior of skeptic is something that I value, because it ensures that every test case is something a reader can copy-paste directly into their own main.rs. Maintaining that while also not invoking rustc for every test case is a challenging problem. The fix in the above link works by turning every test case into its own cargo project, sharing the target-dir with the parent project. That alone probably won't improve anything (and will actually add a cargo invocation on top of the work already being done). One way I can imagine speeding up the compilation of the test cases is by dynamic linking. Another way I can imagine is by compiling every test case (project) as its own library, then linking them all into one "super-binary" that can masquerade as each test case as though it were an independent binary. It cuts out the exe link time, which tends to be significant. That should work for most cases that expect to be run as standalone executables. |
I've posted a branch prototype fix for #18. It doesn't improve testing times yet, but I think it will when it's done. |
This is perhaps not noticeable with only a few tests but I currently have 29 tests which are generated by skeptic which now take up a non-negligible amount of time. From what I can tell from the source and the generated tests this is because all tests are recompiled every time
cargo test
is run and they are also all individually compiled. Is there any good reason for this and could it be changed? I'd be happy to implement the change if it is not to problematic.The text was updated successfully, but these errors were encountered: