Skip to content

Add a utility to assist manually testing an exercise #381

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

Merged
merged 3 commits into from
Nov 8, 2017

Conversation

coriolinus
Copy link
Member

Instead of having to manually enable tests, copy the examples, and
clean up, this script automates all that.

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

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

What I think should happen next is that https://github.com/exercism/rust/blob/master/_test/check-exercises.sh should simply run this script. That way there is less duplicate code and we know that what we use to test locally is the same as what Travis uses.

# run tests
cargo test

# reset
Copy link
Member

Choose a reason for hiding this comment

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

optionally, all this reset business may move into a trap so that it will be run even if the script gets Ctrl-C in the middle of the cargo test run

I don't require it because perhaps that will be a rare occurrence.

One can see an example at https://github.com/exercism/go/blob/master/bin/test-without-stubs#L24-L39

@coriolinus
Copy link
Member Author

Agree with both comments. I'll update in the morning.

@coriolinus
Copy link
Member Author

Delaying this because today was crazy. Will come back to it later. Integrating it into check-exercises.sh properly is a bigger task than it looked at first.

@petertseng
Copy link
Member

Yes, it seems to be bigger because check-exercises operates in separate modes: run the tests, compile the tests with warnings, and run benchmarks. Will have to figure that out

@coriolinus
Copy link
Member Author

That's interesting:

$ ./_test/check-exercises.sh
./_test/check-exercises.sh: line 41: bin/test-exercise: Permission denied
The command "./_test/check-exercises.sh" exited with 1.

Not sure what that means; there are no crazy permissions on test-exercise. Looking into it.

@coriolinus
Copy link
Member Author

Test fail, but it's not the fault of this PR:

$ ./_test/check-exercises.sh
The command "./_test/check-exercises.sh" exited with 0.
0.05s$ sh ./_test/ensure-lib-src-rs-exist.sh
The command "sh ./_test/ensure-lib-src-rs-exist.sh" exited with 0.
7.65s$ sh ./_test/ensure-stubs-compile.sh
error: unused variable: `puzzle`
 --> src/lib.rs:4:14
  |
4 | pub fn solve(puzzle: &str) -> Option<HashMap<char, u8>> {
  |              ^^^^^^
  |
note: lint level defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(warnings)]
  |         ^^^^^^^^
  = note: #[deny(unused_variables)] implied by #[deny(warnings)]
  = note: to disable this warning, consider using `_puzzle` instead
error: aborting due to previous error
error: unused variable: `puzzle`
 --> src/lib.rs:4:14
  |
4 | pub fn solve(puzzle: &str) -> Option<HashMap<char, u8>> {
  |              ^^^^^^
  |
note: lint level defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(warnings)]
  |         ^^^^^^^^
  = note: #[deny(unused_variables)] implied by #[deny(warnings)]
  = note: to disable this warning, consider using `_puzzle` instead
error: aborting due to previous error
To learn more, run the command again with --verbose.
alphametics's stub does not compile; please make it compile or remove all non-commented lines
decimal's stub is allowed to not compile
Exercises that don't compile:
alphametics
The command "sh ./_test/ensure-stubs-compile.sh" exited with 1.

We should update alphametics, but I believe that a different PR should handle that.

directory=$(dirname "${exercise}");

if [ -n "$DENYWARNINGS" ]; then
sed -i -e '1i #![deny(warnings)]' "$directory/src/lib.rs"
Copy link
Member

Choose a reason for hiding this comment

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

This places a [deny(warnings)] line in each stub file, which promptly gets replaced by each example file. Therefore, no [deny(warnings)] line is present in any file that gets compiled by cargo.

The original script placed a [deny(warnings)] in each example file instead, and I believe that being in the example file is the desired behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch; I'll need to change that.

else
files=exercises/*/tests
release="--release"
Copy link
Member

Choose a reason for hiding this comment

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

I proposed this change in #241 and it was rejected, for the reason:

A reason to not use release mode: it will skip overflow checks

I support this change. Please be aware of the reasons for the previous rejection.

Copy link
Member Author

Choose a reason for hiding this comment

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

I put that in to support testing of the script locally, but I'm only moderately in favor of it. It makes sense to ensure that nothing overflows in the tests, so I'll need to get rid of that.

Copy link
Member

Choose a reason for hiding this comment

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

A possible nice change to make would to test in release mode if .meta/test-in-release-mode is present, or something along those lines.

./bin/test-exercise $directory $release
fi
# as the test-exercise command is the last one run in all cases,
# its exit code is preserved automatically
Copy link
Member

Choose a reason for hiding this comment

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

true statement, but we do not have -e in DENYWARNINGS mode, therefore the exit code is the exit code of that of the last exercise, is it not? Thus, we would only get a nonzero exit if the very last exercise has any warnings, and all other exercises' warnings are ignored, I think?

Copy link
Member Author

Choose a reason for hiding this comment

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

I see. Just tested, and you're correct. I'll update that.

@coriolinus coriolinus force-pushed the add-test-exercise-script branch from 35d473d to c9c1e67 Compare November 8, 2017 00:55
@coriolinus
Copy link
Member Author

coriolinus commented Nov 8, 2017 via email

if [ -n "$BENCHMARK" ]; then
files=exercises/*/benches
# cargo bench --release is an invalid command
Copy link
Member

Choose a reason for hiding this comment

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

this comment is no longer makes sense since --release is not being added here

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

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

Conditional on removing that comment that no longer makes sense in #381 (comment).

I tested this by running it locally on one exercise, but I did not test:

  • other exercises
  • BENCHMARK
  • DENYWARNINGS

because my allotted time has elapsed therefore I do not have the time to test these things thoroughly.

The comments associated with this review are comments on existing code that got moved by this PR, not new code or change in behaviour.

fi
# This assumes that exercises are only one directory deep
# and that the primary module is named the same as the directory
directory=$(dirname "${exercise}");
Copy link
Member

Choose a reason for hiding this comment

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

this line is not yours (you only unindented it) so I think the change should come later, but I note that the semicolon is unnecessary.


# eliminate #[ignore] lines from tests
for test in "$exercise/tests/*.rs"; do
sed -i '/\[ignore\]/d' $test
Copy link
Member

Choose a reason for hiding this comment

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

this line is also not yours (you only moved it from one file to another), so shouldn't get fixed here, but it's worth noting that on BSD seds, this gets a:

sed: 1: "exercises/accumulate/te ...": invalid command code e

Whereas it would work if a -e were added, or the -i were changed to -i ''.

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

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

I think in my ideal world I would squash in such a way that the final product contains two commits:

  • One that moves existing functionality into bin/test-exercise, at which point all observable behaviour is expected to remain the same.
  • One that adds the .meta/test-in-release-mode file and associated code and functionality.

If a different sequence of commits seems to make sense, say the word.

@coriolinus coriolinus force-pushed the add-test-exercise-script branch from 835e1e1 to acee1d7 Compare November 8, 2017 08:15
@coriolinus
Copy link
Member Author

Ok, I think that squash takes us most of the way there. There's one deviation from the desired end state: removing the extraneous comment is in the second commit instead of the first, because git rebase -i can squash commits but cannot move changes between commits.

I'm going to add one more commit to this, to take care of the nitpicks regarding lines copied from the previous implementation, and then I think this will be ready to merge.

Copy link
Member

@petertseng petertseng left a comment

Choose a reason for hiding this comment

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

I agree with what you say.

were it up to me, I would rebase -i again and edit the first commit deleting the comment lines:

    # cargo bench --release is an invalid command

and

   # as the test-exercise command is the last one run in all cases,
   # its exit code is preserved automatically

I think that would be the most ideal, to make commits contain exactly what they say and no more.

I suppose if asked the question I wouldn't mind taking it as is, but since we are close to what seems like an ideal, might as well go all the way there, I feel?

Instead of having to manually enable tests, copy the examples, and
clean up, this script automates all that.

- Take optional exercise path argument
- Express all paths in terms of exercise path
- Pass further arguments through to cargo
- Use arrays to simplify file/dir preservation and reset
- Use trap to ensure reset occurs on ctrl-c
- Express check-exercises.sh in terms of bin/test-exercise
- Add debug tests to check-exercises in case of remote execution failure
- Move $![deny(warnings)] insertion into test-exercise.
   - Give the feature to people testing the exercise on its own
   - Clean up properly after
- Return the bitwise OR of individual exercises' return values

That last one wants some commenting. If a bunch of values fail in
different ways, this is of limited utility; your return code won't
be 0, and Travis will fail, but you won't get the info you expected
from the return codes. However, this does have some useful properties:
   - if a bunch of things fail in the same way, or only one thing
     fails, you get Cargo's return code back directly
   - you discard less overall information than the naïve implementation
     ( if [ $? != 0 ]; then return_code=1; fi )
   - always returns zero or non-zero appropriately without branching
- Compile in release mode if .meta/test-in-release-mode exists
- Add note to README documenting the above feature
- Add .meta/test-in-release-mode to alphametics, which is the sore
  spot for debug-mode tests
@coriolinus coriolinus force-pushed the add-test-exercise-script branch from 6fdc183 to 0691ef3 Compare November 8, 2017 13:21
@coriolinus
Copy link
Member Author

We've gone all the way there! I'll merge as soon as this passes Travis.

@coriolinus coriolinus merged commit 44be03a into exercism:master Nov 8, 2017
@coriolinus coriolinus deleted the add-test-exercise-script branch November 8, 2017 13:32
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.

2 participants