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

test suite: Do not generate identical expectation files #598

Merged
merged 2 commits into from Oct 20, 2020

Conversation

petrochenkov
Copy link
Contributor

For C code the test suite runs cbindgen multiple times with different settings of --cpp-compat and --style.
These runs may generate identical code if the original Rust file doesn't have language constructions relevant to those options.

With this PR we no longer save duplicate cbindgen outputs into files and don't run C or C++ compiler on them.
This saves some testing time (around 10% on my machine) and makes reviewing of new test cases easier, new tests are less likely to add a wall of text half of which is duplicated.

It will also help to add less test files in #590 (--style makes sense for Cython too).

Copy link
Collaborator

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I'm not sure how I feel about this, I tend to think tests should try to be as dumb as possible... On the other hand it's nice that this removes almost 3k lines (and I guess this is worse for cython and that's why you want this?)

Either way I have a few nits etc.

if cbindgen_outputs.contains(&cbindgen_output) {
// We already generated an identical file previously.
return;
} else {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: No else after return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what do you mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restructured the code slightly to avoid return.

cbindgen_path,
path,
&generated_file,
language,
cpp_compat,
style,
);
if cbindgen_outputs.contains(&cbindgen_output) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should assert that generated_file doesn't exist in CBINDGEN_TEST_VERIFY mode, and remove it if it does otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

command.arg("-o").arg(output);

if env::var("CBINDGEN_TEST_VERIFY").is_ok() {
command.arg("--verify");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove this flag if we're doing this, probably.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a reasonable thing to use on CI if cbindgen is used offline rather than from a build script, I'd keep it.
(Also it's a public cbindgen's interface after all, someone else is probably using it.)

for cpp_compat in &[true, false] {
// Run tests in deduplication priority order. C++ compatibility tests are run first,
// otherwise we would lose the C++ compiler run if they were deduplicated.
let mut cbindgen_outputs = HashSet::new();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I wonder how much peak memory does this use, guess not too much given the size of the test-cases so no big deal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the files are small, the largest one is tests\expectations\destructor-and-copy-ctor.cpp with 13kb, it's nothing.

tests/tests.rs Outdated
fs::write(&generated_file, &cbindgen_output).unwrap();
}
cbindgen_outputs.insert(cbindgen_output);
}

compile(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I feel a bit uneasy about this work being skipped generally... But I guess it's mostly fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are only skipping identical compiler runs ("compile as C") on files with identical contents, since we are not deduplicating "accross languages".

@petrochenkov
Copy link
Contributor Author

@emilio

So I'm not sure how I feel about this, I tend to think tests should try to be as dumb as possible...

So, I had an idea how to increase "obviousness" of the deduplication and also improve the test suite in general.

Right now expectation files generated from the same Rust file are located far from each other, in different directories (tag, both, etc). This directory structure was introduced in #112 and not discussed.

I suggest to place different outputs from the same file next to each other instead, and make them differ only by extensions (this is how it's done in rustc test suite).
I also suggest to add suffixes in the order of deduplication priority, so it's clear that if my_test.foo.bar is missing, then it should be identical to mytest.foo.

So, the outputs from annotation.rs would be:

annotation.c
annotation.both.c
annotation.tag.c
annotation.nocompat.c
annotation.nocompat.both.c
annotation.nocompat.tag.c

and deduplicated outputs could look like

# c++ compat mode is not relevant to this test (but we are still running both c and c++ compiler!)
annotation.c
annotation.both.c
annotation.tag.c

or

# struct definition styles are not relevant to this test
annotation.c
annotation.nocompat.c

@petrochenkov
Copy link
Contributor Author

The suggestion is implemented in #602.

I don't quite like the .nocompat part though, since cpp-compat is not the default.
Perhaps

# c++ compat mode is not relevant to this test (but we are still running both c and c++ compiler!)
annotation.compat.c
annotation.compat.both.c
annotation.compat.tag.c

after deduplication is clear enough even if we deduplicate in favor of a longer suffix.

@emilio emilio merged commit 050863a into mozilla:master Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants