-
Notifications
You must be signed in to change notification settings - Fork 37.7k
test: Add unit & functional test coverage for blockstore #27850
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
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. 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. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
b58d3fa
to
4daeaa5
Compare
ba8547f
to
38bc463
Compare
Concept ACK |
6f7499a
to
e01ac84
Compare
e01ac84
to
f88b87b
Compare
f37e904
to
da1f187
Compare
I fixed the CI failures by skipping tasks that are run as root. Root privileges override the read-only file permissions and the test fails because we expect an error that doesn't throw (can not open read-only file in write mode). There are 6 tasks that skip this test for this reason: [ASan + LSan + UBSan + integer, no depends, USDT] [lunar] |
689448d
to
ae4d5f5
Compare
Ready for review now, CI is passing modulo #27879 |
Just curious, did you try using Seems a shame to miss linux out. |
ae4d5f5
to
5bc5150
Compare
Bold strategy, Cotton let's see if it pays off: cd394b6 |
cd394b6
to
1dd0dfd
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.
ACK 9791b31
// First two blocks are written as expected | ||
// Errors are expected because block data is junk, thrown AFTER successful read | ||
CBlock read_block; | ||
{ |
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.
259889d Maybe assert the value here before the read, to ensure that it changed with the BOOST_CHECK_EQUAL(read_block.nVersion, 1);
check that follows.
CBlock read_block;
+ BOOST_CHECK_EQUAL(read_block.nVersion, 0);
{
pass | ||
|
||
if not used_chattr: | ||
self.log.info("Can not make file immutable with chattr, trying chmod instead") |
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.
- suggest making the other added logs
info
, or this logdebug
s/Can not/Cannot/
and mention that chattr is platform-specific to linux (see suggestion)- missing line breaks
@@ -11,6 +11,7 @@ import stat
from test_framework.test_framework import BitcoinTestFramework
+
class BlockstoreReindexTest(BitcoinTestFramework):
@@ -41,7 +42,7 @@ class BlockstoreReindexTest(BitcoinTestFramework):
if not used_chattr:
- self.log.info("Can not make file immutable with chattr, trying chmod instead")
+ self.log.debug("Cannot make file read-only with chattr (which is linux-only), using chmod instead")
@@ -57,5 +58,6 @@ class BlockstoreReindexTest(BitcoinTestFramework):
self.reindex_readonly()
+
if __name__ == '__main__':
BlockstoreReindexTest().main()
$ pycodestyle test/functional/feature_reindex_readonly.py
test/functional/feature_reindex_readonly.py:14:1: E302 expected 2 blank lines, found 1
test/functional/feature_reindex_readonly.py:60:1: E305 expected 2 blank lines after class or function definition, found 1
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 generally prefer chatty tests, which makes it easier to see progress and see what the test is currently doing, as long as the output is not high-frequent. So I think the log level can be left as-is.
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.
re-ACK 9791b31 🕕
Show signature
Signature:
untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: re-ACK 9791b3182514a2571a7c1cdb38b59338c24d974d 🕕
Yj2uRwzpT1GD2q/ibV1KkO+mrHtJd2SSWN8t4DWILeAQrpp52zK2SWHQFhk/iD04RqlyGEtI32q3lRbj3NNvBg==
@@ -31,7 +31,9 @@ if [ -z "$DANGER_RUN_CI_ON_HOST" ]; then | |||
fi | |||
|
|||
# shellcheck disable=SC2086 | |||
CI_CONTAINER_ID=$(docker run $CI_CONTAINER_CAP --rm --interactive --detach --tty \ | |||
|
|||
|
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.
why two
newlines?
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: I think this wasn't addressed?
self.log.debug("Make the first block file read-only") | ||
(self.nodes[0].chain_path / "blocks" / "blk00000.dat").chmod(stat.S_IREAD) | ||
|
||
filename = self.nodes[0].chain_path / "blocks" / "blk00000.dat" |
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.
Any reason to add an alias, but not use it consistently?
|
||
if not used_chattr: | ||
self.log.info("Can not make file immutable with chattr, trying chmod instead") | ||
(self.nodes[0].chain_path / "blocks" / "blk00000.dat").chmod(stat.S_IREAD) |
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.
Why is this needed, when the same call was already done unconditionally, which seems preferable than a conditional call?
|
||
if used_chattr: | ||
subprocess.check_call(['chattr', '-i', filename]) | ||
else: |
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.
Any reason for the else
? Seems better to also do this unconditionally, because setting it was done unconditionally.
Otherwise it may cause edge cause test failures on some machines/configs only.
@@ -0,0 +1,61 @@ | |||
#!/usr/bin/env python3 | |||
# Copyright (c) 2023 The Bitcoin Core developers |
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.
# Copyright (c) 2023 The Bitcoin Core developers | |
# Copyright (c) 2023-present The Bitcoin Core developers |
nit: For new code could use -present
(or omit the year) to avoid having to ever touch it again.
9791b31
to
f1264f9
Compare
Thanks again @MarcoFalke and @jonatack I addressed all your feedback |
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 f1264f9
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.
re-ACK f1264f9 🍦
Show signature
Signature:
untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: re-ACK f1264f9baca4207c4c530f01d90fcdc841368126 🍦
G5HM6LhMQyxLvXfOSzHbPsljWaZ9XpmswhOHqpwakw2n06WWG+7NyED+63/6l0Lcy6tPvu6axWBFhHvMZKAMAA==
ACK f1264f9 |
try: | ||
subprocess.check_call(['chattr', '+i', filename]) | ||
used_chattr = True | ||
self.log.info("Made file immutable with chattr") | ||
except Exception: | ||
pass |
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.
When this test is run as non-root, this results in something being written to stderr which will cause the test runner to always fail. That's really annoying for testing locally.
try: | |
subprocess.check_call(['chattr', '+i', filename]) | |
used_chattr = True | |
self.log.info("Made file immutable with chattr") | |
except Exception: | |
pass | |
try: | |
subprocess.run(['chattr', '+i', filename], capture_output=True, check=True) | |
used_chattr = True | |
self.log.info("Made file immutable with chattr") | |
except subprocess.CalledProcessError as e: | |
self.log.warning(str(e)) | |
if e.stdout: | |
self.log.warning(f"stdout: {e.stdout}") | |
if e.stderr: | |
self.log.warning(f"stderr: {e.stderr}") |
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! thanks for the patch
Co-authored-by: Andrew Chow <github@achow101.com>
f1264f9
to
de8f912
Compare
ACK de8f912 tested on macOS, but not on Linux for the Linux-related change in the last push |
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.
lgtm ACK de8f912 📶
Show signature
Signature:
untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: lgtm ACK de8f9123afbecc3b4f59fa80af8148bc865d0588 📶
aCT7KL7/lymQNqrfkzsZyKFtz7sH6ZgYVwranWjN6pDe/m5Cd47wdd2X8+yokXAAQkqj7TMxrlrauXR514LfBw==
ACK de8f912 |
…ockstore de8f912 test: cover read-only blockstore (Matthew Zipkin) 5c2185b ci: enable chattr +i capability inside containers (Matthew Zipkin) e573f24 unit test: add coverage for BlockManager (Matthew Zipkin) Pull request description: This PR adds unit and functional tests to cover the behavior described in bitcoin#2039. In particular, that bitcoind will crash on startup if a reindex is requested but the `blk` files are read-only. Eventually this behavior can be updated with bitcoin#27039. This PR just commits the test coverage from bitcoin#27039 as suggested in bitcoin#27039 (comment) ACKs for top commit: jonatack: ACK de8f912 modulo suggestions in bitcoin#27850 (comment), tested on macOS, but not on Linux for the Linux-related change in the last push achow101: ACK de8f912 MarcoFalke: lgtm ACK de8f912 📶 Tree-SHA512: b9bd684035dcea11c901b649fc39f397a2155a9a8459f3348e67947e387e45312fddeccb52981aef486f8a31deebb5356a7901c1bb94b78f82c24192a369af73
filename.chmod(stat.S_IREAD) | ||
|
||
used_chattr = False | ||
if platform.system() == "Linux": |
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 guess this test will also fail on freebsd when running as root
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.
A solution may be to check for freebsd and chflags
?
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 have an OpenBSD server I can run the test on, will follow up with a PR this week
5a0688a test: enable reindex readonly test on *BSD and macOS as root (Matthew Zipkin) Pull request description: see bitcoin/bitcoin#27850 (comment) OpenBSD and FreeBSD don't have `chattr` but they do have `chflags`, use that method to make the block file immutable for the reindex_readonly test. Written and tested on a VPS running FreeBSD: ``` FreeBSD freebsd-13-1 13.2-RELEASE-p4 FreeBSD 13.2-RELEASE-p4 GENERIC amd64 ``` ACKs for top commit: maflcko: re-cr-lgtm-ACK 5a0688a jonatack: ACK 5a0688a tested on macOS only theStack: ACK 5a0688a Tree-SHA512: 8c88d282d09c00355d22c4c504b779f60e420327a5e07bcf80fa77b97fefcb04952af9ceaf439d9033a0a2448cb26a02663fe6bddcd4a74792857cfbaf1c5162
5a0688a test: enable reindex readonly test on *BSD and macOS as root (Matthew Zipkin) Pull request description: see bitcoin#27850 (comment) OpenBSD and FreeBSD don't have `chattr` but they do have `chflags`, use that method to make the block file immutable for the reindex_readonly test. Written and tested on a VPS running FreeBSD: ``` FreeBSD freebsd-13-1 13.2-RELEASE-p4 FreeBSD 13.2-RELEASE-p4 GENERIC amd64 ``` ACKs for top commit: maflcko: re-cr-lgtm-ACK 5a0688a jonatack: ACK 5a0688a tested on macOS only theStack: ACK 5a0688a Tree-SHA512: 8c88d282d09c00355d22c4c504b779f60e420327a5e07bcf80fa77b97fefcb04952af9ceaf439d9033a0a2448cb26a02663fe6bddcd4a74792857cfbaf1c5162
This PR adds unit and functional tests to cover the behavior described in #2039. In particular, that bitcoind will crash on startup if a reindex is requested but the
blk
files are read-only. Eventually this behavior can be updated with #27039. This PR just commits the test coverage from #27039 as suggested in #27039 (comment)