-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Build previous releases and run functional tests #12134
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
Can you explain why exactly the patching is needed in this case? It would definitely seem better to test against unpatched previous releases if possible. |
@ryanofsky the regtest parameters were changed to activate SegWit at the genesis block, which causes nodes after #11389 to reject blocks created by v0.15.1 and older nodes (and vice versa). Maybe there's a less drastic way to change the regtest consensus params for these older releases? |
Not sure, but is passing |
@Sjors I've spent some time looking into how feasible it would be to write functional tests that would run against older versions of our software, which I think would be great if we could pull off -- for instance, I thought it would be nice in something like the However, in my experience this proved to be impractical. It seems like we periodically make changes to the RPC test framework infrastructure itself, in such ways that cause problems with backward compatibility. Here are a few examples I have run into, so you get a flavor of some of the issues:
So my takeaway from this exercise was that if we want to support running modern tests against older binaries, we need to change the way we do things, so that we (a) have a better split between the python test code, and the python utilities/RPC handlers/etc that allow us to talk to a node, and (b) come up with a way to use older python utility code when talking to older nodes. |
I don't understand why this would matter. I think the goal here is just to be able to write a small test that brings up a specific version of bitcoind (0.15) and tests a few things with it, not to be able to run large swathes of the test framework against arbitrary bitcoin releases. It doesn't seem it would require a lot of code to support this, and if the tests are run on travis it doesn't seem like whatever code is added could get broken easily. |
@ryanofsky Perhaps I phrased that sentence poorly -- my point wasn't that we'd want to run all the tests against older code (I think that would be absurd), just that we take it for granted that we can call Another way to look at it: imagine you wanted to run a test against 0.15 now, so you write one and you can even use |
This seems possible for small, limited tests which don't use the full range of test framework capabilities (for example, if we just want to test downgrading to v0.15 to test segwit wallets). As Suhas has pointed out, there are lots of reasons why this is difficult in the general case, but I think we can work around them for a targeted test cases:
Not relevant if we only want to test as far back as v0.15, but we can add a
We could be careful to not use named arguments in tests where we want to use earlier versions. Or we could add a shim to
As above.
I expect we'll only want to have tests covering the last one or two releases, so I don't see this as a huge problem.
Yes - I agree that would be almost impossible. @Sjors - if the goal is only to test official releases, why not download the binaries directly from https://bitcoincore.org/bin/ rather than building them locally? |
This is an aside if the goal here is just to make 0.15 work, but:
The change to support named args actually affected RPC invocations that don't use named args -- I think we send an empty dictionary instead of an empty list in Anyway I don't mean to be overly pessimistic if you all think we can make something work! I'm definitely in favor of the overall goal, I just haven't come across a simple solution that I thought was robust. |
I don't follow this point though -- in something like the |
Yes - my expectation is that we'd decommission that test at some point. I don't think that testing versions older than a couple of releases is something that we should do as part of travis or developer local testing (although there's nothing stopping anyone from having a custom test rig to do that sort of thing). |
cf362b5
to
f46bc95
Compare
@jnewbery compiling from source seems more flexible than fetching binaries, especially if we need to patch things. There might also be configure flags that are optimal for the functional tests. It can be expanded to fetch code from other repositories (on your own test rig). Downloading binaries would be faster, but it also involves figuring out which OS you're on and checking the checksum, so it's not necessarily easier to write a script for. That said, the one-off build is painfully slow on Travis atm, so I might add an option to just fetch a binary. @ryanofsky @sdaftuar I ran into the issue you mentioned for versions before v0.14 and added a comment to the test file to warn about that. I changed the demonstration test to simply check if old nodes sync blocks from the new node. I'll try some SegWit wallet related scenarios in a different PR. I added a commit that makes one Travis instance compile |
.travis.yml
Outdated
@@ -7,6 +7,7 @@ cache: | |||
- depends/built | |||
- depends/sdk-sources | |||
- $HOME/.ccache | |||
- build/releases |
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.
That cache should be covered by .ccache
, no?
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.
- will look into
ccache
behavior.
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.
Forget what I said. It is probably better to cache the resulting binary than the individual obj files, since we are building specific tags that don't change. For master or other branch build, the commits often only change parts of the code, so the other obj files can be cached and re-used. For tag builds everything is static, so caching the binaries works as well.
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. Just noting that every change to the rpc interface is a breaking change in compatibility tests, that potentially needs attention. So we need to run those tests in the pull request travis run.
"""Override this method to customize test node setup""" | ||
self.add_nodes(self.num_nodes, self.extra_args, None, None, [ | ||
None, | ||
"build/releases/v0.15.1/src/bitcoind", |
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.
Would be nice to be able to pass those paths in. Could overwrite add_options
in test_framework.
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.
Do you mean making --srcdir
accept multiple paths? That's probably a useful PR by itself, I made a note.
] | ||
|
||
def setup_nodes(self): | ||
"""Override this method to customize test node setup""" |
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.
Comment seems misplaced
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.
Removed.
|
||
def setup_nodes(self): | ||
"""Override this method to customize test node setup""" | ||
self.add_nodes(self.num_nodes, self.extra_args, None, None, [ |
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.
Use named args for those unnamed arguments to provide documentation and robustness against future interface changes.
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.
Concept ACK, haven't looked at the code. I think not testing with older versions is the biggest lack in our test env. |
Concept ACK, cross version testing will be a very nice addition to the testing suite IMO |
fef4581
to
bcdd3ea
Compare
bcdd3ea
to
0beb2a3
Compare
0beb2a3
to
842e4e0
Compare
842e4e0
to
6c530f5
Compare
Rebased. Reminder to self: cherry-pick Sjors@bacf559 after #18067 is merged. |
fi | ||
done | ||
} | ||
popd || exit 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 don't think we have anyone interested in tests who can also review bash scripts. Maybe rewrite this in python?
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 to my todo list, but equally happy to (see someone else) do this in a followup.
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, some style nits
if not os.path.isdir(releases_path): | ||
if os.getenv("TEST_PREVIOUS_RELEASES") == "true": | ||
raise AssertionError("TEST_PREVIOUS_RELEASES=1 but releases missing: " + releases_path) | ||
raise SkipTest("This test requires binaries for previous releases") |
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'd rather have both of these an Assertion instead of a silent 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.
That seems inconsistent with the way we skip wallet tests, i.e. the test runner calls each test file and each test file decides if needs to be skipped.
6c530f5
to
c456145
Compare
ACK c456145 🔨 Show signature and timestampSignature:
Timestamp of file with hash |
c456145 [test] add 0.19 backwards compatibility tests (Sjors Provoost) b769cd1 [test] add v0.17.1 wallet upgrade test (Sjors Provoost) 9d9390d [tests] add wallet backwards compatility tests (Sjors Provoost) c7ca630 [scripts] support release candidates of earlier releases (Sjors Provoost) 8b1460d [tests] check v0.17.1 and v0.18.1 backwards compatibility (Sjors Provoost) ae379cf [scripts] build earlier releases (Sjors Provoost) Pull request description: This PR adds binaries for 0.17, 0.18 and 0.19 to Travis and runs a basic block propagation test. Includes test for upgrading v0.17.1 wallets and opening master wallets with older versions. Usage: ```sh contrib/devtools/previous_release.sh -f -b v0.19.0.1 v0.18.1 v0.17.1 test/functional/backwards_compatibility.py ``` Travis caches these earlier releases, so it should be able to run these tests with little performance impact. Additional scenarios where it might be useful to run tests against earlier releases: * creating a wallet with #11403's segwit implementation, copying it to an older node and making sure the user didn't lose any funds (although this PR doesn't support `v0.15.1`) * future consensus changes * P2P changes (e.g. to make sure we don't accidentally ban old nodes) ACKs for top commit: MarcoFalke: ACK c456145 🔨 Tree-SHA512: 360bd870603f95b14dc0cd629532cc147344f632b808617c18e1b585dfb1f082b401e5d493a48196b719e0aeaee533ae0a773dfc9f217f704aae898576c19232
This PR adds binaries for 0.17, 0.18 and 0.19 to Travis and runs a basic block propagation test.
Includes test for upgrading v0.17.1 wallets and opening master wallets with older versions.
Usage:
Travis caches these earlier releases, so it should be able to run these tests with little performance impact.
Additional scenarios where it might be useful to run tests against earlier releases:
v0.15.1
)