Skip to content
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 end-to-end tests for CConnman and PeerManager #26812

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

vasild
Copy link
Contributor

@vasild vasild commented Jan 4, 2023

Add unit tests that write data to a mocked socket and inspect what CConnman/PeerManager have written back to the socket, or check the internal state to verify that the behavior is as expected.

This is now possible, after most of #21878 has been merged - we don't do any syscalls (e.g. connect(), recv()) from the high level code and using a mocked socket allows testing the entire networking stack without opening actual network connections.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 4, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK jonatack
Concept ACK Sjors

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #30205 (test: add mocked Sock that can read/write custom data and/or CNetMessages by vasild)

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.

@DrahtBot DrahtBot added the Tests label Jan 4, 2023
debug_log.EndAndThrowIfNotFound(30s);
}

BOOST_AUTO_TEST_CASE(ping)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is inspired by #25515

Copy link
Member

Choose a reason for hiding this comment

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

Key difference in #25515 is that it is testing net processing in isolation (at least isolated from CConnman), which imo is something we definitely should be doing. We already have e2e tests i.e. the functional tests, so I don't see the benefit to your approach here (besides the c++ tests being faster than the python ones).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, both testing in isolation and e2e is good to have. The difference between the tests included in this PR and the functional tests is that when the test code runs inside the same process:

  • it has greater control and observability - the test can read any global or member variable and can call arbitrary functions
  • it can do fuzzing

I think all those tests are complementary, not mutually exclusive.

Copy link
Member

Choose a reason for hiding this comment

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

The unit tests are what I run locally over and over, as they run so much more quickly. IIRC there was a project idea a few years ago to convert the functional tests in Python to C++. Having better unit test coverage, or shifting coverage from the Python tests to C++ ones, seems beneficial.

src/test/fuzz/netmsg.cpp Outdated Show resolved Hide resolved
debug_log.EndAndThrowIfNotFound(30s);
}

BOOST_AUTO_TEST_CASE(ping)
Copy link
Member

Choose a reason for hiding this comment

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

Key difference in #25515 is that it is testing net processing in isolation (at least isolated from CConnman), which imo is something we definitely should be doing. We already have e2e tests i.e. the functional tests, so I don't see the benefit to your approach here (besides the c++ tests being faster than the python ones).

src/test/fuzz/netmsg.cpp Outdated Show resolved Hide resolved
src/test/fuzz/netmsg.cpp Outdated Show resolved Hide resolved
src/test/fuzz/netmsg.cpp Outdated Show resolved Hide resolved
@vasild
Copy link
Contributor Author

vasild commented Jan 12, 2023

9b7e9dad27...daee83c1c5: optimize the fuzz test a bit

@vasild
Copy link
Contributor Author

vasild commented Feb 9, 2023

32ab679f54...7c591c868d: rebase due to conflicts

@vasild
Copy link
Contributor Author

vasild commented Feb 20, 2023

7c591c868d...a81fe4ff9b: rebase and put the fuzz tests in fuzz/process_message.cpp instead of in a new file, as suggested.

@vasild
Copy link
Contributor Author

vasild commented Sep 2, 2024

e0bb306436...f5fe172e85: rebase due to conflicts,

@jonatack there you go!

@vasild
Copy link
Contributor Author

vasild commented Sep 3, 2024

f5fe172e85...127c86d91f: pet clang-tidy: use = default instead of {}

…lass

This allows reusing them in other mocked implementations.

Also move the implementation (method definitions) to
`test/util/net.cpp` to make the header `test/util/net.h` easier to follow.
…o it

And also allows gradually providing the data to be returned by `Recv()`
and sending and receiving net messages (`CNetMessage`).
Throwing an exception from the destructor of a class is a bad practice
because the destructor will be called when an object of that type is
alive on the stack and another exception is thrown, which will result
in "exception during the exception". This would terminate the program
without any messages.

Instead print the message to the standard error output and call
`std::abort()`.
Extend `DebugLogHelper::~DebugLogHelper()` to be able to
optionally wait for messages, possibly logged from another thread, to
arrive before performing the final check.
…anager

Add tests that use a mocked socket to similate network IO and cover the
full `CConnman`, `PeerManager` and the interaction between them.
@vasild
Copy link
Contributor Author

vasild commented Sep 28, 2024

6d0c5247eb...752fbab26a: rebase due to conflicts

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Light ACK 752fbab per git range-diff 489e5aa 612ba17 752fbab since my previous ACK at #26812 (comment) and a quick re-read of the full changes rebased to current master. I like that the changes here are essentially limited to tests only.

@DrahtBot DrahtBot requested a review from Sjors October 10, 2024 21:55
@maflcko
Copy link
Member

maflcko commented Oct 11, 2024

The pull descriptions claims to add a fuzz test, but I can't see anything related to fuzzing

@vasild
Copy link
Contributor Author

vasild commented Oct 11, 2024

The pull descriptions claims to add a fuzz test, but I can't see anything related to fuzzing

I removed the fuzz test due to #26812 (comment) and forgot to update the PR description. Updated now, thanks!

@maflcko
Copy link
Member

maflcko commented Oct 11, 2024

I still wonder how useful this is overall. I understand that it is adding a bunch of test-framework code to mimic the functional tests at a lower level and offers a way to write tests this way in C++. However, developers may still prefer to write the tests in Python going forward, because they are used to it, and because it is more flexible, albeit a bit more expensive, because full processes need to be spun up each time. If this is merged, it will add a few redundant test cases (redundant in the sense of not increasing line coverage over the existing one), but may then end up otherwise unused/stale.

Conceptually I like the changes, but it reminds me of my attempt to "port" the functional test to C++, starting by providing functions for each RPC (fa8685d#diff-663b6e7cfa474d453c20efa49be6e3e9f5066f7fed5586e98da98f2b3dea5653R24), but that never took off either.

Often when it comes to testing P2P behavior, you'd want to spin up several peers/nodes anyway, and the functional tests have the full framework for that, so going forward developers will likely still use that for testing.

@vasild
Copy link
Contributor Author

vasild commented Oct 11, 2024

developers may still prefer to write the tests in Python going forward, because they are used to it, and because it is more flexible

I agree. This PR does not intend to replace the functional testing framework, but complement it. For example, from C++ one has greater control and observability - the test can read any global or member variable and can call arbitrary functions (repeating #26812 (comment)).

Also, when used from within C++ one does not have to re-implement the transport code in Python. From C++ we can use the existent code to parse or craft the socket data.

Wrt "how useful is this": the first part of this PR (also isolated in #30205) is already used in Sv2Transport tests.

@jonatack
Copy link
Member

from C++ one has greater control and observability - the test can read any global or member variable and can call arbitrary functions

Also, when used from within C++ one does not have to re-implement the transport code in Python. From C++ we can use the existent code to parse or craft the socket data.

For these reasons, along with the speed of running the tests and the simplicity and robustness of using the same language for tests and code, I prefer to write test code in C++ when I can, and run the C++ tests much more often locally than the functional tests. I recall there were initiatives to move functional test code to C++ as @maflcko suggests, and would be supportive of these.

@maflcko
Copy link
Member

maflcko commented Oct 11, 2024

Wrt "how useful is this": the first part of this PR (also isolated in #30205) is already used in Sv2Transport tests.

I followed the links but only found a closed pull requests: #30332 (comment)

I think it is easy to say that something will be used in the future, but I think it would be easier if the framework commits were added with non-redundant tests at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants