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

Add a test that an odd capacity BufEncoder does not compile #157

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

jamillambert
Copy link
Contributor

@jamillambert jamillambert commented Feb 19, 2025

An even capacity BufEncoder is now enforced and should be tested to make sure it does not compile if an odd capacity is used.

Adds a crate in tests that uses an odd capacity BufEncoder.

Adds a CI test that passes if the odd capacity crate fails to compile.

Close #155

config.src_base = PathBuf::from("tests/compiletest");
config.target_rustcflags = Some("-L target/debug/deps".to_string());
compiletest::run_tests(&config);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks quite complicated. Why not simply have a new CI step to run if cargo check --something; then exit 1; fi?

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 wasn't sure about adding a CI step just for this one, should be simple, test. But it does work, and there might be reasons in the future to add to the compile tests?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's probably worthwhile to do this in a general way (modifying CI). If we had the means to add compile-tests I'll bet we'd add a lot of them.

Copy link
Member

Choose a reason for hiding this comment

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

+1 this would be useful for the api test files. And also for corepc.

Copy link
Collaborator

@Kixunil Kixunil Feb 20, 2025

Choose a reason for hiding this comment

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

I prefer not to take dev dependency if the same can be done in CI reasonably simply.

@jamillambert jamillambert force-pushed the 0219-compile-test branch 3 times, most recently from 7e295d7 to 3394da3 Compare February 19, 2025 21:18
@jamillambert jamillambert marked this pull request as ready for review February 19, 2025 21:19
@tcharding
Copy link
Member

Cool, looking good. I think this should be called odd-capacity instead of compiletest because we can only ever have a single test in it (since one cannot prove two build failures at the same time). And for that reason perhaps inline the function into main.

FTR I changed the 3 to a 4 and the crate builds - to check for no false positives. This crate risks going stale consider this:

  1. We change the import path of BufEncode - now the test crate does not build because of that
  2. We change the BufEncode type accidentally so that odd value builds - now the test does not catch it.

@jamillambert jamillambert force-pushed the 0219-compile-test branch 2 times, most recently from ed6b613 to 5a70ac4 Compare February 21, 2025 09:04
@jamillambert
Copy link
Contributor Author

I have changed it so that there are two compile checks now. First it checks that an even capacity compiles, then it checks that the odd capacity doesn't. The only difference between the two is changing the capacity from 4 to 3.

I also moved them to a sub directory in tests called compiletests so it is a bit tidier, especially if more are going to be added.

@apoelstra
Copy link
Member

apoelstra commented Feb 23, 2025

Can you add a further subdirectory level tests/compiletest/pass/ and .../fail/ and have the script use the directory names to figure out whether this should be a pass or fail test?

@jamillambert
Copy link
Contributor Author

I have changed the script to be general using the two sub directories pass/ and fail/.

I added the BufEncoder capacity evenness check as a separate commit.

@tcharding
Copy link
Member

Looks good, few bash things specific to the rust-bitcoin org

  • We use #!/usr/bin/env bash so that Nix users can run the script (they don't typically have /bin/bash I'm told)
  • Tend to use set -euo pipefail unless some reason not to
  • Try to lint scripts with shellcheck foo.sh https://www.shellcheck.net/
  • Tend to use REPO_DIR=$(git rev-parse --show-toplevel) to get at the repo directory
  • If you feel like it (but its mainly only me that does it) you can use a bunch of helper functions that were originally written by the Rust project a long time ago. They are in various shell scripts around the place, bitcoin/contrib/check-for-api-changes.rs has them)

@tcharding
Copy link
Member

tcharding commented Feb 25, 2025

Can you put a - separator in compiletests directory please mate. Based on that famous made-up saying "Uniformity is close to Godliness"

@jamillambert
Copy link
Contributor Author

Made the changes to the shell script and directory name.

for dir in pass/*; do
if [ -d "$dir" ]; then
pushd "$dir" > /dev/null
if ! cargo run > /dev/null 2>&1; then
Copy link
Collaborator

Choose a reason for hiding this comment

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

The test says "compile" but it uses run. Also we should keep the output here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to build. I have also made it so that it only outputs if the test failed, otherwise for all the shouldn't compile cases there will be a list of compile errors when everything is working as intended.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is the pass branch though.

if [ "$all_passed" = true ]; then
return 0
else
return 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps just define result = 0 at the beginning and assign it to 1 on fail and just return "$result" to get rid of if.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, this is a nicer way of doing it. I have changed it as suggested.

for dir in fail/*; do
if [ -d "$dir" ]; then
pushd "$dir" > /dev/null
if cargo run > /dev/null 2>&1; then
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also it should be build, not run.

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

if [ "$all_failed" = true ]; then
return 0
else
return 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same as above.

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

for dir in pass/*; do
if [ -d "$dir" ]; then
pushd "$dir" > /dev/null
output=$(cargo build 2>&1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This shouldn't be needed but I guess it's OK. I don't expect the output to be too large.

pushd "$dir" > /dev/null
output=$(cargo build 2>&1)
if [ $? -eq 0 ]; then
echo "$output"
Copy link
Collaborator

Choose a reason for hiding this comment

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

If compilation succeeded and it shouldn't there will be no useful information printed by cargo. I'd rather get rid of it.

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 have removed the cargo output for this case

@jamillambert
Copy link
Contributor Author

Looking at the script again I noticed the two functions are now basically identical. I have refactored it to have a single function that handles both cases.

Create a script `contrib/compile-tests.sh` the checks that all crates in
`tests/compiletests/` do compile if in `pass/` and fail to compile if in
`fail/`

Add a CI step to run the script
Add two compile test crates that are identical except for the capacity
of `BufEncoder`.  Odd capacity in `fail/` that must not compile and even
capacity in `pass/` that must compile.
echo "Compiling $dir"
output=$(cargo build 2>&1)
if [ "$?" -ne "$expected_status" ]; then
if [ "$expected_status" -eq 0 ]; then
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why have another argument if it can be inferred from the first one and you're not comparing them anyway?

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 started to change it, but it's more flexible the way it is. I'm not sure we need to but it's possible to check directories other than pass/ and fail/ by passing a different argument to the function.

But if you prefer I can hard code the directory names and exit codes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Too many possibilities that we're not using are just complicating the code. Honestly, I think even having the pass option is a stretch (normal tests do that already!) but I understand it's for the symmetry since there are related test (one for 3, other 4) so I'm accepting it. I was really expecting this to be one line in the workflow file.

Copy link
Member

@tcharding tcharding left a comment

Choose a reason for hiding this comment

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

ACK 853f493

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.

4 participants