test: add functional test for -startupnotify #23532

pull brunoerg wants to merge 1 commits into bitcoin:master from brunoerg:2021-11-test-startupnotify changing 2 files +42 −0
  1. brunoerg commented at 12:58 AM on November 17, 2021: member

    This PR adds a functional test for -startupnotify. It basically starts the node passing a command on -startupnotify to create a file on tmp and then, we check if the file has been successfully created.

  2. fanquake added the label Tests on Nov 17, 2021
  3. lsilva01 commented at 2:08 AM on November 17, 2021: contributor

    Concept ACK.

    Perhaps the test with valid command can create a file in test or tmp dir and checks if this file was created..

  4. DrahtBot commented at 4:29 AM on November 17, 2021: member

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #22776 (rpc/wallet: add optional transaction(s) to getbalances by kallewoof)
    • #22751 (rpc/wallet: add simulaterawtransaction RPC by kallewoof)

    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.

  5. brunoerg force-pushed on Nov 17, 2021
  6. brunoerg force-pushed on Nov 17, 2021
  7. brunoerg commented at 11:22 AM on November 17, 2021: member

    I've tried different valid commands with -startupnotify like: echo (common command for Unix system and Windows), tried a simple ls for Unix and dir for Windows and other ones, but the CI is failing for all of them. Any thoughts about it, @MarcoFalke?

  8. MarcoFalke commented at 11:29 AM on November 17, 2021: member

    You can find the error in the log:

     node0 stderr Error: The experimental syscall sandbox feature (-sandbox=<mode>) is incompatible with -startupnotify (which uses execve). 
    
  9. brunoerg commented at 11:53 AM on November 17, 2021: member

    You can find the error in the log:

     node0 stderr Error: The experimental syscall sandbox feature (-sandbox=<mode>) is incompatible with -startupnotify (which uses execve). 
    

    Sorry, I read that but didn't notice this part of the log. Thanks.

  10. brunoerg force-pushed on Nov 17, 2021
  11. brunoerg force-pushed on Nov 17, 2021
  12. theStack commented at 1:28 PM on November 17, 2021: member

    Concept ACK

  13. brunoerg commented at 5:31 PM on November 17, 2021: member

    Force-pushed with a update on expected_stderr in stop_node. I just edited the description.

  14. brunoerg force-pushed on Nov 17, 2021
  15. brunoerg force-pushed on Nov 18, 2021
  16. brunoerg force-pushed on Nov 18, 2021
  17. brunoerg commented at 6:35 PM on November 18, 2021: member

    Win64 has failed: <img width="1060" alt="Screen Shot 2021-11-18 at 10 23 47" src="https://user-images.githubusercontent.com/19480819/142430123-5ed41a77-3173-4442-85ae-6f37654921b6.png">

    I think the problem may be the breaklines. Going to work to fix it.

  18. brunoerg force-pushed on Nov 18, 2021
  19. brunoerg force-pushed on Nov 18, 2021
  20. brunoerg commented at 10:51 AM on November 19, 2021: member

    Force-pushed adding os.linesep into expected windows message.

  21. in test/functional/feature_startupnotify.py:31 in e9ebe3b96e outdated
      26 | +        self.stop_node(0)
      27 | +        self.log.info("Test the node starts with an invalid command on -startupnotify")
      28 | +        self.start_node(0, extra_args=[f"-startupnotify={INVALID_COMMAND}"])
      29 | +
      30 | +        stderrs = [f"sh: {INVALID_COMMAND}: command not found", f"sh: 1: {INVALID_COMMAND}: not found",
      31 | +        f"AssertionError: Unexpected stderr '{INVALID_COMMAND}' is not recognized as an internal or external command,{os.linesep}operable program or batch file."]
    


    stratospher commented at 6:22 PM on November 20, 2021:

    In e9ebe3b, shouldn't it be this?

            f"'{INVALID_COMMAND}' is not recognized as an internal or external command,{os.linesep}operable program or batch file."]
    

    MarcoFalke commented at 7:31 AM on November 21, 2021:

    Do we need tests for to check the operating systems exact response to an invalid command? This doesn't increase the test coverage of Bitcoin Core itself and it seems a bit painful to maintain.


    brunoerg commented at 11:17 AM on November 21, 2021:

    I agree it seems a bit painful to maintain, but if we don't pass an expected error message the test will fail. I think the stop_node could have a boolean flag when expecting error without specifing the message it would be helpful. What do you think?


    brunoerg commented at 11:38 AM on November 21, 2021:

    Not sure if the right is:
    f"'{INVALID_COMMAND}' is not recognized as an internal or external command,{os.linesep}operable program or batch file."] or f"Unexpected stderr '{INVALID_COMMAND}' is not recognized as an internal or external command,{os.linesep}operable program or batch file."

    Going to test it, thanks!


    brunoerg commented at 11:06 AM on November 22, 2021:

    Both of them didn't work.


    stratospher commented at 12:49 PM on November 24, 2021:

    It should be the first option because "AssertionError: Unexpected stderr" comes from L351. There shouldn't be a space before {os.linesep} in L31?


    brunoerg commented at 1:01 PM on November 24, 2021:

    My bad, I hadn't notice this one on L351. Going to test again, thanks!

  22. brunoerg force-pushed on Nov 21, 2021
  23. brunoerg force-pushed on Nov 21, 2021
  24. brunoerg force-pushed on Nov 21, 2021
  25. brunoerg force-pushed on Nov 24, 2021
  26. in test/functional/feature_startupnotify.py:31 in b0fc9f9e22 outdated
      26 | +        self.stop_node(0)
      27 | +        self.log.info("Test the node starts with an invalid command on -startupnotify")
      28 | +        self.start_node(0, extra_args=[f"-startupnotify={INVALID_COMMAND}"])
      29 | +
      30 | +        stderrs = [f"sh: {INVALID_COMMAND}: command not found", f"sh: 1: {INVALID_COMMAND}: not found",
      31 | +        f"'{INVALID_COMMAND}' is not recognized as an internal or external command,{os.linesep}operable program or batch file."]
    


    luke-jr commented at 7:57 PM on November 30, 2021:

    This seems shell-specific and not reliable for a test


    brunoerg commented at 1:53 PM on December 1, 2021:

    I am going to re-write this test to not considering this part.

  27. luke-jr changes_requested
  28. luke-jr commented at 7:59 PM on November 30, 2021: member

    Ideally, a test for -startupnotify should ensure that the command is executed exactly once, and when it is executed, the node is fully started (which may involve races which make it difficult to deterministically fail).

  29. brunoerg force-pushed on Dec 3, 2021
  30. brunoerg commented at 12:50 PM on December 3, 2021: member

    Force-pushed addressing the reviews, thanks everyone for them. I just changed the approach for this test (updated the description).

  31. in test/functional/feature_startupnotify.py:21 in 31931a5ab0 outdated
      16 | +        self.extra_args = [["-startupnotify=echo 'test' >> node0/test.txt"]]
      17 | +
      18 | +    def run_test(self):
      19 | +        tmpdir = os.path.join(self.options.tmpdir, "node0", "test.txt")
      20 | +
      21 | +        self.log.info("When node starts, check if test.txt exists")
    


    jonatack commented at 8:07 PM on December 7, 2021:
            self.log.info("Test -startupnotify command is run when node starts")
    

    brunoerg commented at 9:23 PM on December 7, 2021:

    Thank you for the suggestions, they are very relevant, I am going to implement them.

  32. jonatack commented at 8:12 PM on December 7, 2021: member

    ACK 31931a5ab009256bf583025939e6e3ca2f875d9a

    A couple of ideas, feel free to ignore/pick/choose:

    • Begin by testing the absence of tmpdir without -startupnotify before asserting on its presence with the option
    • Maybe abstract the magic strings to constants
     from test_framework.test_framework import BitcoinTestFramework
     
    +NODE_DIR = "node0"
    +FILE_NAME = "test_123_xyz"
     
     class StartupNotifyTest(BitcoinTestFramework):
         def set_test_params(self):
             self.num_nodes = 1
             self.disable_syscall_sandbox = True
    -        self.extra_args = [["-startupnotify=echo 'test' >> node0/test.txt"]]
     
         def run_test(self):
    -        tmpdir = os.path.join(self.options.tmpdir, "node0", "test.txt")
    +        tmpdir = os.path.join(self.options.tmpdir, NODE_DIR, FILE_NAME)
    +        assert not os.path.exists(tmpdir)
     
             self.log.info("When node starts, check if test.txt exists")
    +        self.restart_node(0, extra_args=[f"-startupnotify=echo '{FILE_NAME}' >> {NODE_DIR}/{FILE_NAME}"])
             assert os.path.exists(tmpdir)
    
  33. jonatack commented at 8:24 PM on December 7, 2021: member

    Ideally, a test for -startupnotify should ensure that the command is executed exactly once, and when it is executed, the node is fully started (which may involve races which make it difficult to deterministically fail).

    Maybe checking the expected result of an RPC (like getblockcount) could verify the node is fully up.

  34. brunoerg force-pushed on Dec 7, 2021
  35. brunoerg force-pushed on Dec 7, 2021
  36. brunoerg commented at 9:46 PM on December 7, 2021: member

    Force-pushed addressing @luke-jr and @jonatack tips. Thanks for the reviews.

  37. jonatack commented at 12:51 PM on December 8, 2021: member

    ACK, modulo unrelated code that appears to have crept into the last push?

  38. brunoerg commented at 3:57 PM on December 10, 2021: member

    ACK, modulo unrelated code that appears to have crept into the last push?

    omg, didn't understand why it happened, going to check it.

  39. brunoerg force-pushed on Dec 21, 2021
  40. brunoerg commented at 5:57 PM on December 21, 2021: member

    fixed commits! @jonatack

  41. Davidson-Souza commented at 8:02 PM on December 22, 2021: none

    tested ACK 98014c5

    OS: Arch Linux 64 bits (Linux 5.12.19-hardened1-1-hardened x86_64) System: AMD Ryzen 5 64 bits + AMD VEGA 8 with 12GB RAM Build: Compiled from source with no additional ./configure options

    Tests: Ran the test alone, it worked! image Also, all the tests with test/functional/test_runner.py, again everything is working just fine! image

  42. in test/functional/feature_startupnotify.py:29 in 98014c5a88 outdated
      24 | +        tmpdir = os.path.join(self.options.tmpdir, NODE_DIR, FILE_NAME)
      25 | +        assert not os.path.exists(tmpdir)
      26 | +
      27 | +        self.log.info("Test -startupnotify command is run when node starts")
      28 | +        self.restart_node(0, extra_args=[f"-startupnotify=echo '{FILE_NAME}' >> {NODE_DIR}/{FILE_NAME}"])
      29 | +        assert os.path.exists(tmpdir)
    


    kristapsk commented at 10:59 PM on December 22, 2021:

    Check should be added to not only existence of the file but also exact file contents, that will address @luke-jr comment about testing that -startupnotify command is executed only once.


    brunoerg commented at 5:16 PM on December 23, 2021:

    Done, thanks!

  43. in test/functional/feature_startupnotify.py:24 in 98014c5a88 outdated
      19 | +    def set_test_params(self):
      20 | +        self.num_nodes = 1
      21 | +        self.disable_syscall_sandbox = True
      22 | +
      23 | +    def run_test(self):
      24 | +        tmpdir = os.path.join(self.options.tmpdir, NODE_DIR, FILE_NAME)
    


    kristapsk commented at 11:06 PM on December 22, 2021:

    Why the variable is called tmpdir if it's actually filename?


    brunoerg commented at 2:47 PM on December 23, 2021:

    this is the temporary directory where the file is...

  44. brunoerg force-pushed on Dec 23, 2021
  45. brunoerg commented at 5:17 PM on December 23, 2021: member

    force-pushed addressing @luke-jr and @kristapsk reviews (check if the command is executed once).

  46. kristapsk approved
  47. kristapsk commented at 7:16 PM on December 23, 2021: contributor

    ACK dbdcc783e39794d54c2f17040d248539b1ca46b0

  48. lsilva01 approved
  49. lsilva01 commented at 11:35 PM on December 23, 2021: contributor

    reACK dbdcc78

    Nice addition to test coverage.

  50. MarcoFalke commented at 9:29 AM on December 24, 2021: member
    feature_startupnotify.py                           | ✖ Failed  | 2 s
    
  51. test: add functional test for -startupnotify 126853214a
  52. brunoerg force-pushed on Dec 24, 2021
  53. brunoerg commented at 1:57 PM on December 24, 2021: member
    feature_startupnotify.py                           | ✖ Failed  | 2 s
    

    Fixed!

  54. theStack approved
  55. theStack commented at 2:45 AM on December 31, 2021: member

    Tested ACK 126853214a490ee840e83ca17c717c40cfbe6837 (run on OpenBSD 7.0)

  56. kristapsk approved
  57. kristapsk commented at 6:14 PM on December 31, 2021: contributor

    re-ACK 126853214a490ee840e83ca17c717c40cfbe6837

  58. MarcoFalke merged this on Jan 3, 2022
  59. MarcoFalke closed this on Jan 3, 2022

  60. sidhujag referenced this in commit 33f09a2e2a on Jan 4, 2022
  61. seaona commented at 4:25 PM on January 27, 2022: contributor

    Concept and approach ACK. Tested and working fine :) I saw that startupnotify uses execve and I was wondering if that could be checked on the test, somehow like: in case of using sandbox (if defined(USE_SYSCALL_SANDBOX), startupnotify will not throw?

  62. DrahtBot locked this on Jan 27, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-05-02 03:14 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me