Skip to content

Conversation

@laanwj
Copy link
Member

@laanwj laanwj commented Oct 2, 2014

See #4845.
Trying to figure out why this breaks the tests now.

@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2014

This has to do with the order in which tests are executed.

blockv2_tests.cpp leaves the block chain in a unspecified state, which causes the miner tests to fail.

I'm going to split this up into two commits: one that introduces the UNITTEST framework and modifyiable parameters, and one that adds the block v2 test.

SergioDemianLerner and others added 2 commits October 2, 2014 13:51
UNITTEST inherites from MAIN but allows synamically changing its parameters using the ModifiableParams() interface
Treat fSkipProofOfWorkCheck the same as other parameters.
@laanwj laanwj force-pushed the 2014_09_unittest_master branch from 2ea9cfe to fbd36d8 Compare October 2, 2014 11:54
@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2014

This should pass now.

@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2014

@SergioDemianLerner I've split off this part that adds the blockv2 tests: laanwj@782f6c8
It needs some more work to leave the block chain in a usable state for the next test, or to create a new block chain for each test. This already hinted in the comments

// We don't know the state of the block-chain here: it depends on which other tests are run before this test.
// See https://github.com/bitcoin/bitcoin/pull/4688 for a patch that allows the re-creation of the block-chain
// for each testcase that requires it.

@laanwj laanwj changed the title Test rebased #4845 Switch testing framework from MAIN to new UNITTEST network (rebase) Oct 2, 2014
@laanwj laanwj merged commit fbd36d8 into bitcoin:master Oct 2, 2014
laanwj added a commit that referenced this pull request Oct 2, 2014
fbd36d8 Avoid introducing a virtual into CChainParams (Wladimir J. van der Laan)
f0fd00c Switch testing framework from MAIN to new UNITTEST network (SergioDemianLerner)
@SergioDemianLerner
Copy link
Contributor

The problem is not that the blockv2_test leaves the blockchain in a bad state. The problem is the the miner_test MUST be executed before blockv2_test because miner_tests tests v1 blocks and blockv2_test tests v2 blocks.
If the Boost test framework does not allow to specify a unique order for the tests, one way to force this is to include blockv2_test into miner_test via #include, and let both of them be contained in a single .cpp file

@SergioDemianLerner
Copy link
Contributor

Definitively, the easiest way would be that each new test that mines blocks adds an #include line into miner_test.cpp
@laanwj : I suppose I don't have write access to the rebased repo. Could you add the #include "blockv2_test.cpp" into the last line of miner_test.cpp and create a new pull request for that?

@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2014

I don't really like tests that are dependent on order, or hacking around that; let's try to do it properly. What we really need is #4688.

I can't give you write access to my branch, but if you want to edit the branch you could pull my branch and start from there.

@SergioDemianLerner
Copy link
Contributor

Yes I agree, but I'm also more pragmatic and not so purist: why not allowing both?
Some future tests could be dependent on the order and some not. The overhead of recreating the block-chain is low, but we could avoid it in some cases. Other reason to let people add block test cases to a single file is that test cases involving transactions require pre-mined coinbases. If each test must recreate the block-chain, it must start with mining 100 blocks in order to have 50 BTC mature.

As an example, most of the block tests in TheBlueMatt FullBlockTestGenerator.java are independent of order. (off-topic: nevertheless they are painfully linked together with references to previous blocks: Block b47 = createNextBlock(b46, ....), this can be avoided by an internal reference of the last tip)

So we could create a single empty file "block_tests.cpp" where people can easily add tests by including their own files using #include at the end, and at the same time, for the tests that require a new block-chain, people put them in separate files, and they clear the block-chain before each test using #4688

@SergioDemianLerner
Copy link
Contributor

If somebody were to re-write each test case of FullBlockTestGenerator.java as an independent .cpp file, the block-chain would need to be re-created 40 times in each test_bitcoin execution.

@laanwj
Copy link
Member Author

laanwj commented Oct 2, 2014

If some starting point is convenient to be used by multiple tests (like "100 blocks in order to have 50 BTC mature") it makes sense to compute that once and cache it.

I still don't see a good reason to make tests use each other's output. Then it becomes impossible to disable tests without affecting others. I think we've all worked with hairballs like that, so I'd prefer to avoid it. They are called 'unit tests' for a good reason.

The whole reason for merging this (and allowing the skip proof-of-work) was to make building blockchains extremely cheap, so unless the overhead becomes serious I'd prefer to just start from scratch for each test. But if necessary I'd prefer caching/precomputation to letting one test use the output of another.

@sipa
Copy link
Member

sipa commented Oct 2, 2014

@SergioDemianLerner Please don't confuse the unit tests (in .cpp code) and the network interaction tests (in comparison tool). The purpose of the first is to test whether the code behaves as the implementer intends it to work. The purpose of the second is to detect consensus and other cross-implementation compatibility.

I would be strongly opposed to converting comparison tool into a unit test. It means that for example a change in serialization code keeps bitcoind compatible with itself, but not with other nodes on the network (including older versions of bitcoind).

I am in favor of replacing comparison tool with a more general framework (using no Bitcoin core code), preferably in a different language, that replays scenarios of network interactions, and verifies that state running bitcoind (or other code) behaves as expected. See #4545.

@SergioDemianLerner
Copy link
Contributor

I don't say we should replace the comparison tool, since it has been very useful. It was an example of how the number of tests could grow. But some unit test can test things that are hidden from the remote nodes. I made bitcoind stress unit tests that check RAM and CPU usage, and I'm waiting to merge them when we resolve how.

@sipa
Copy link
Member

sipa commented Oct 3, 2014

Ok, good. I misinterpreted your comment it seems.

@SergioDemianLerner
Copy link
Contributor

This has been merged! I hadn't notice. Great! Thanks!

@mikehearn
Copy link
Contributor

In bitcoinj we have a large number of unit tests that create block chains and throw them away. Actually a full test run of bitcoinj runs ~5000 unit tests, although not all of those require block chains. So there's no reason to be scared of creating and throwing away chains - they are after all just in memory data structures and a UNITTEST params chain can have blocks mined more or less instantly.

The problem here is not performance or how to split things up, it's that Satoshi didn't write testable code in the first place. Lots of global variables everywhere instead of objects. Not much we can do about that except refactor it into a testable state very, very carefully.

@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants