-
Notifications
You must be signed in to change notification settings - Fork 35.5k
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: Add a few more corner cases to the base58 test suite #30035
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK for 9431bc9
Built and ran unit tests (all passed).
Left one nit, but the nit is outside the scope of this PR, so is probably better left to a separate PR.
auto leadingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : ""; | ||
auto trailingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Probably outside the scope of this PR (this PR is adding tests, so business logic changes are extraneous), but at first glance, seems like these statements could be simplified, since InsecureRandRange()
can return 0, the std::string
constructor can handle 0 count, and string operator+ can handle empty string addition. Maybe I'm missing something?
For example:
diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp
index 49ef9ff5b5..beb5ef3335 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -92,8 +92,8 @@ BOOST_AUTO_TEST_CASE(base58_random_encode_decode_with_optional_spaces)
auto zeroes = InsecureRandBool() ? InsecureRandRange(len + 1) : 0;
auto data = Cat(std::vector<unsigned char>(zeroes, '\000'), g_insecure_rand_ctx.randbytes(len - zeroes));
- auto leadingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : "";
- auto trailingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : "";
+ auto leadingSpaces = std::string(InsecureRandRange(10), ' ');
+ auto trailingSpaces = std::string(InsecureRandRange(10), ' ');
auto encoded = leadingSpaces + EncodeBase58Check(data) + trailingSpaces;
std::vector<unsigned char> decoded;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for checking @tdb3, the results would be similar, but since I assumed the spaces are rare in reality, I gave it different odds.
In my impl the probability that we won't have any leading (or trailing) spaces was 50% + 50%*10%
, in your impl it's 10%
, so spaces would be in most samples.
I'm fine with both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that's right (higher probability of no spaces over rand range alone). I don't have a preference, just an observation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like all this, but it would be better to explain in the PR description why it is important/beneficial to include this change since this increases the test complexity.
Probably would be even better to have a separate test case to check for leading and trailing spaces. This test case is intended to check for leading zeros and now it checks for three concerns (leading zeros, leading spaces, and trailing spaces) instead of one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it checks for three concerns
That's a property based test, i.e. for random valid inputs it checks that certain conditions hold - in this case a roundtrip, that decoding an encoded results in the original trimmed value.
It's meant to find corner cases that we haven't though of, that's its single concern, we have separate tests for each corner case we know about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added short explanations to the commit message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
Built and ran the unit tests.
The new messages seem to be the opposite of what the tests do, tough.
Thanks for the review @edilmedeiros, some of the existing BOOST_CHECK_MESSAGE messages are either in indicative or subjunctive grammatical moods (even in the same file, as you can see). |
I have no personal preference about it, but this is not my point. Take for instance How can (expected) |
9431bc9
to
fc0cc2d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gave another deep look at this, thanks again for submitting this PR.
Beside the specific code comments, please add to the commit message why are you adding new test cases, what they improve in the test logic (and how they help the work on #29473).
src/test/base58_tests.cpp
Outdated
} | ||
|
||
BOOST_CHECK(!DecodeBase58("invalid"s, result, 100)); | ||
BOOST_CHECK(!DecodeBase58("invalid\0"s, result, 100)); | ||
BOOST_CHECK(!DecodeBase58("\0invalid"s, result, 100)); | ||
|
||
BOOST_CHECK(DecodeBase58("good"s, result, 100)); | ||
BOOST_CHECK( DecodeBase58("good"s, result, 100)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BOOST_CHECK( DecodeBase58("good"s, result, 100)); | |
BOOST_CHECK(DecodeBase58("good"s, result, 100)); |
I understand the rational of aligning this with surrounding context, but does seem against guidelines and will look like a typo for others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file was already using this format: https://github.com/bitcoin/bitcoin/blob/master/src/test/base58_tests.cpp#L74
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks more like a typo, see lines 67 and 78.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel strongly about either, removed the space
src/test/base58_tests.cpp
Outdated
EncodeBase58(sourcedata) == base58string, | ||
strTest); | ||
EncodeBase58(sourcedata) == base58string, | ||
strTest << "\nEncoding `" << HexStr(Span(sourcedata)) << "` as `" << EncodeBase58(sourcedata) << "` should match `" << base58string << "`" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strTest << "\nEncoding `" << HexStr(Span(sourcedata)) << "` as `" << EncodeBase58(sourcedata) << "` should match `" << base58string << "`" | |
strTest << ": got \"" << EncodeBase58(sourcedata) << "\"" |
What about a little less verbose and taking advantage of the strTest
string that has both input and expected outcome?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't realize this, thanks!
test/base58_tests.cpp:40: info: check '["271F359E","zzzzy"]: got "zzzzy"' has passed
src/test/base58_tests.cpp
Outdated
BOOST_CHECK(DecodeBase58(base58string, result, 256)); | ||
BOOST_CHECK_MESSAGE( | ||
result == expected, | ||
strTest << "\nDecoding `" << base58string << "` as `" << HexStr(result) << "` should match `" << HexStr(expected) << "`" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strTest << "\nDecoding `" << base58string << "` as `" << HexStr(result) << "` should match `" << HexStr(expected) << "`" | |
strTest << ": got \"" << EncodeBase58(sourcedata) << "\"" |
Same suggestion as above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test/base58_tests.cpp:65: info: check '["271F35A1","211112"]: got XXX "271f35a1"' has passed
auto leadingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : ""; | ||
auto trailingSpaces = InsecureRandBool() ? std::string(InsecureRandRange(10), ' ') : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like all this, but it would be better to explain in the PR description why it is important/beneficial to include this change since this increases the test complexity.
Probably would be even better to have a separate test case to check for leading and trailing spaces. This test case is intended to check for leading zeros and now it checks for three concerns (leading zeros, leading spaces, and trailing spaces) instead of one.
src/test/base58_tests.cpp
Outdated
auto ok = DecodeBase58Check(encoded, decoded, len + InsecureRandRange(257 - len)); | ||
BOOST_CHECK(ok); | ||
BOOST_CHECK(data == decoded); | ||
BOOST_CHECK_MESSAGE(!DecodeBase58Check(encoded, decoded, InsecureRandRange(len)), "Decoding should fail for smaller max_ret_len"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another place where there's a random parameter that's not reported making potential debugging impossible.
Also, the text is no good since max_ret_len
is the maximum return size. Better something like Decoding exceeds xxx length.
where xxx prints the random parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, added the values to the error message:
test/base58_tests.cpp:102: error: in "base58_tests/base58_random_encode_decode_with_optional_spaces": Decoding should fail for `invalidSmallResultLength` (61)
test/base58_tests.cpp:104: error: in "base58_tests/base58_random_encode_decode_with_optional_spaces": Decoding should succeed within sufficiently large result length (134)
src/test/base58_tests.cpp
Outdated
BOOST_CHECK(ok); | ||
BOOST_CHECK(data == decoded); | ||
BOOST_CHECK_MESSAGE(!DecodeBase58Check(encoded, decoded, InsecureRandRange(len)), "Decoding should fail for smaller max_ret_len"); | ||
BOOST_CHECK_MESSAGE( DecodeBase58Check(encoded, decoded, len + InsecureRandRange(257 - len)), "Decoding should succeed within valid length range"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing about unreported random parameter in the test. This is worse yet since there's a weird logic to get the param. It's good that you submitted this PR, the original test deserved a better look already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain in the PR first comment and in the commit message why are you adding these specific test cases, what do they improve in the existing test logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your detailed review, will do that this week
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, done
aae9616
to
b1142e3
Compare
Add better errors for base58_EncodeBase58 and base58_DecodeBase58 to see the differing value in case of failure. Extended the base58_random_encode_decode_with_optional_spaces property based test - containing a simple roundtrip with decoding validation - to stress the leading and trailing space parsing as well. Also extended the base58_encode_decode.json file with a few corner cases - e.g. on a transition of power of 58 to check the boundaries. Co-authored-by: Edil Medeiros <jose.edil@gmail.com>
b1142e3
to
861ab92
Compare
Split out the additional tests from the base58 optimization PR as suggested #29473 (comment)