Skip to content

Conversation

@glozow
Copy link
Member

@glozow glozow commented Aug 25, 2020

The TestNode has a p2p property which is an alias for p2ps[0].

I think this should be removed because it can be confusing and misleading (to both the test writer and reviewer), especially if a TestNode has multiple p2ps connected (which is the case for many tests).
Another example is when a test has multiple subtests that connect 1 p2p and use the p2p property to reference it. If the subtests don't completely clean up after themselves, the subtests may affect one another.

The best way to refer to a connected p2p is use the object returned by add_p2p_connection like this:

p2p_conn = node.add_p2p_connection(P2PInterface())

A good example is p2p_invalid_locator.py, which cleans up after itself (waits in both wait_for_disconnect and in disconnect_p2ps) but wouldn't need so much complexity if it just referenced the connections directly.

If there is only one connected, it's not really that tedious to just use node.p2ps[0] instead of node.p2p (and it can always be aliased inside the test itself).

@maflcko
Copy link
Member

maflcko commented Aug 25, 2020

Heh, this one might be controversial. In theory it shouldn't be confusing if there is only exactly one p2p connection. If this pull gets Concept ACKs, that is fine. If not, it might be good to replace the assert self.p2ps with assert len(self.p2ps)==1.

@glozow
Copy link
Member Author

glozow commented Aug 25, 2020

@MarcoFalke indeed. You put this idea in my head 😂 but assert len == 1 is a good way too. I don't see any advantages to having this though.

@maflcko
Copy link
Member

maflcko commented Aug 25, 2020

Yes, I remember that. It looks like that was in reply to a performance bottleneck. Is that still observable?

@glozow
Copy link
Member Author

glozow commented Aug 25, 2020

@MarcoFalke I think the performance problems were addressed elsewhere (comment). We were talking about p2p_invalid_messages.py which has a lot of subtests that needed to wait for disconnect_p2ps before moving on.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 26, 2020

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

Conflicts

Reviewers, 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.

@theStack
Copy link
Contributor

Concept ACK
I agree that the p2p property can be quite confusing, as it is a bit too much of "implicit magic" going on.

node.add_p2p_connection(P2PInterface())
node.p2p.do_something_fancy()

is less clear than the explicit

p2p_conn = node.add_p2p_connection(P2PInterface())
p2p_conn.do_something_fancy()

in terms of readability, in my opinion. Generally, if you have a function to create an object, the handle returned by that function should be the preferred way to access that object, and not some other implicit way. (.p2ps[0] suffers from the same problem, but at least it is more obvious that it is the first connection.)

That said, I also agree to MarcoFalke that this might be controversial... if it doesn't get enough Concept ACKs, I'm also happy to ACK the variant with assert len(self.p2ps)==1 in the p2p property.

@glozow
Copy link
Member Author

glozow commented Aug 28, 2020

thanks for Concept ACK @theStack!

Agreed that's more clear, I could also just apply the explicit p2p_conn = node.add_p2p_connection(...) to all the places where p2p is used (just couldn't be a scripted-diff).

I'll wait for more people to weigh in :)

@robot-dreams
Copy link
Contributor

Yes, agreed that this seems controversial :) there was even discussion of this in the original PR: #11182 (comment)

I don't have a strong preference for p2p vs p2ps[0]. I have a mild preference for not reversing an existing style decision without new information. Maybe you can see if the original author says "I regret my decision to introduce the p2p property; let's change it"? :)

But I'm definitely in favor of assert len(self.p2ps) == 1 to avoid incorrect/confusing use of the p2p property!

@glozow
Copy link
Member Author

glozow commented Sep 1, 2020

That is true, I should have asked - @jnewbery how do you feel about this?

@jnewbery
Copy link
Contributor

jnewbery commented Sep 1, 2020

@jnewbery how do you feel about this?

I can see how TestNode.p2p could introduce subtle bugs if tests get extended and the wrong connection is used by mistake, so we should either remove the property or add an assert when it gets used.

The approach in this PR (removing the property entirely) seems fine to me. Concept ACK.

@robot-dreams
Copy link
Contributor

Concept ACK

And thanks for the motivation to learn about scripted-diff :)

Are you also on MacOS? I had to install gsed and use that in place of sed in order to run commit-script-check.sh locally, but once I did this, I was able to reproduce the CI error.

A few thoughts:

Here's a verify script that takes all of the above into account:

sed -i 's/\.p2p\b/.p2ps[0]/g' $(git grep -l "\.p2p\b" test/functional)

@glozow
Copy link
Member Author

glozow commented Sep 4, 2020

  • Should the regex be \.p2p\b (end on a word boundary instead of a dot)? e.g. it looks like test/functional/feature_versionbits_warning.py uses node.p2p without a trailing dot

@robot-dreams really good point about feature_versionbits_warning, thanks for catching that! I think the problem with using \.p2p\b is we'll also be replacing all of the test_framework.p2p imports. I'm going through and refactoring the tests to explicitly call the p2p objects returned from add_p2p_connection though, so the scripted diff will be pretty minimal.

@robot-dreams
Copy link
Contributor

robot-dreams commented Sep 4, 2020

Oops, nice catch! I forgot to actually test the script myself 😅

It's a moot point at this point since your proposed change sounds better, but I think this would've worked (don't do the replace on lines that start with from)

sed -i '/^from/!s/\.p2p\b/.p2ps[0]/g' $(git grep -l "\.p2p\b" test/functional)

@glozow glozow changed the title test: remove confusing p2p property test/refactor: reference p2p objects explicitly and remove confusing Test_Node.p2p property Sep 4, 2020
@glozow
Copy link
Member Author

glozow commented Sep 4, 2020

One day I will get the scripted-diff right on the first try... 😂

I figured 3 Concept ACKs was enough for me to put some work into this. Last push replaces p2p property with the p2p object returned from node.add_p2p_connection() instead (except for two places where it'd be a nontrivial refactor). As stated previously in the description and by @theStack, this is the clearest way to do it. It makes reviewing the PR slightly more involved, but I think it's a bigger improvement as well :) @MarcoFalke please let me know what you think?

Copy link
Contributor

@robot-dreams robot-dreams left a comment

Choose a reason for hiding this comment

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

ACK f1ccb4cc9c4457bed2cc12ff9cedb30d56a31985 aside from nits

Thanks for cleaning this up! Going through and refactoring as you did must've been a nice opportunity to learn about each test / choose reasonable variable names :)

  • Looked over change manually (note: I didn't think about the choice of variable names)
  • Did grep for remaining occurrences of p2p, made sure they were all as intended
  • Ran test/functional/test_runner.py --extended, looks good except for a local failure that didn't look related to your change at all (feature_pruning.py)
  • Ran commit-script-check.sh locally, looks good

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

Seems odd to use a local reference and self.nodes[0].p2ps to access the same p2p connection

Use object returned from add_p2p_connection to refer to
p2ps. Add a test class attribute if it needs to be used across
many methods. Don't use the p2p property.
-BEGIN VERIFY SCRIPT-
sed -i 's/\.p2p\./.p2ps[0]./g' test/functional/p2p_invalid_tx.py
-END VERIFY SCRIPT-
@glozow
Copy link
Member Author

glozow commented Sep 10, 2020

Did a little more refactoring to make feature_block.py and feature_csv_activation.py more clear, addressed @MarcoFalke's comments. Just left p2p_invalid_tx.py for the scripted-diff since it seems to want a variable number of connections in bootstrap_p2p, maybe future additions to the test could need it. Also added some stuff to the functional test README. Ready for another look :)

@robot-dreams
Copy link
Contributor

utACK 10d6150

Thanks for improving the documentation as well!

@jnewbery
Copy link
Contributor

utACK 10d6150

@glozow glozow requested a review from maflcko September 15, 2020 17:44
Copy link
Contributor

@guggero guggero left a comment

Choose a reason for hiding this comment

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

Concept ACK 10d6150.

I think the preferred way should indeed be to access the peers through the return value of add_p2p_connection whenever possible.

Perhaps we could make this PR less controversial by replacing all the index-based accesses where possible?
The two easiest examples would be:

@maflcko maflcko merged commit 78f912c into bitcoin:master Sep 25, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Sep 25, 2020
…and remove confusing Test_Node.p2p property

10d6150 [test] remove confusing p2p property (gzhao408)
549d30f scripted-diff: replace p2p with p2ps[0] in p2p_invalid_tx (gzhao408)
7a0de46 [doc] sample code for test framework p2p objects (gzhao408)
784f757 [refactor] clarify tests by referencing p2p objects directly (gzhao408)

Pull request description:

  The `TestNode` has a `p2p` property which is an alias for `p2ps[0]`.

  I think this should be removed because it can be confusing and misleading (to both the test writer and reviewer), especially if a TestNode has multiple p2ps connected (which is the case for many tests).
  Another example is when a test has multiple subtests that connect 1 p2p and use the `p2p` property to reference it. If the subtests don't completely clean up after themselves, the subtests may affect one another.

  The best way to refer to a connected p2p is use the object returned by `add_p2p_connection` like this:
  ```py
  p2p_conn = node.add_p2p_connection(P2PInterface())
  ```
  A good example is [p2p_invalid_locator.py](https://github.com/bitcoin/bitcoin/blob/master/test/functional/p2p_invalid_locator.py), which cleans up after itself (waits in both `wait_for_disconnect` and in `disconnect_p2ps`) but wouldn't need so much complexity if it just referenced the connections directly.

  If there is only one connected, it's not really that tedious to just use `node.p2ps[0]` instead of `node.p2p` (and it can always be aliased inside the test itself).

ACKs for top commit:
  robot-dreams:
    utACK 10d6150
  jnewbery:
    utACK 10d6150
  guggero:
    Concept ACK 10d6150.

Tree-SHA512: 5965548929794ec660dae03467640cb2156d7d826cefd26d3a126472cbc2494b855c1d26bbb7b412281fbdc92b9798b9765a85c27bc1a97f7798f27f64db6f13
maflcko pushed a commit that referenced this pull request Sep 26, 2020
0fcaf73 test: use explicit p2p objects where available (Oliver Gugger)

Pull request description:

  This is a follow-up patch to #19804 as suggested by MarcoFalke (#19804 (comment)).

  To make the intent of the tests easier to understand, we reference the
  p2p connection objects by their explicit names instead of the p2ps array.

ACKs for top commit:
  theStack:
    ACK 0fcaf73

Tree-SHA512: 37db22185077beeadfa7245bb768b87d6b7a2cfb906c3c859ab92ec3d657122db7301777f0838e13dfc748f37303850144fb7553e6cb6c66903e304d6e10e659
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 14, 2021
Summary:
Use object returned from add_p2p_connection to refer to
p2ps. Add a test class attribute if it needs to be used across
many methods. Don't use the p2p property.

This is a backport of [[bitcoin/bitcoin#19804 | core#19804]] [1a/4]
bitcoin/bitcoin@784f757

`abc*` test will be done separately.

Test Plan: `ninja check-functional-extended`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10320
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 14, 2021
Summary:
Use object returned from add_p2p_connection to refer to p2ps, or use `node.p2ps[0]` when it needs to be used across many methods. Don't use the p2p property.

For these files, this is best done by removing some unnecessary (and often overcomplicated) helper functions that can be replaced with a single line of code at the callsite.

This is a backport of [[bitcoin/bitcoin#19804 | core#19804]] [1b/4]

Test Plan: `ninja check-functional-extended`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10321
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 14, 2021
Summary:
This is a backport of [[bitcoin/bitcoin#19804 | core#19804]] [2/4]
bitcoin/bitcoin@7a0de46

Test Plan: Proofreading

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10322
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 14, 2021
Summary:
This is a backport of [[bitcoin/bitcoin#19804 | core#19804]] [3/4]
bitcoin/bitcoin@549d30f

Test Plan: `test/functional/test_runner.py p2p_invalid_tx`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10324
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 14, 2021
Summary:
This is a backport of [[bitcoin/bitcoin#19804 | core#19804]] [4/4]
bitcoin/bitcoin@10d6150

Depends on D10320, D10321 and D10324

Test Plan: `ninja check-functional-extended`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D10325
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants