qa: Make wallet_multiwallet.py Windows crossbuild-compatible #34418

pull hodlinator wants to merge 10 commits into bitcoin:master from hodlinator:2026/01/31409_fix changing 3 files +200 βˆ’138
  1. hodlinator commented at 12:35 pm on January 27, 2026: contributor

    Makes the functional test compatible with Linux->Windows cross-built executables.

    Main parts:

    • Commit “qa: Check for platform-independent part of error message” switches to match on platform-independent part of error message.
    • Commit “qa: Test scanning errors individually” disentangles code causing the same error message substring, based on #31410.
    • Commit “qa: Disable parts of the test when running under Windows or root” enables the test to be run on Windows, based in part on #31410 (comment).

    Also:

    • Removes unused option in wallet_multiwallet.py.
    • Breaks apart wallet_multiwallet.py’s run_test() into smaller test functions.
    • Improves assert_equal() output for dicts.

    Fixes #31409.

  2. DrahtBot added the label Tests on Jan 27, 2026
  3. DrahtBot commented at 12:35 pm on January 27, 2026: contributor

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

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34418.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK janb84
    Concept ACK hebasto
    Approach ACK w0xlt

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34544 (wallet: Disallow wallet names that are paths including .. and . elements by achow101)
    • #34439 (qa: Drop recursive deletes from test code, add lint checks. by davidgumberg)
    • #32138 (wallet, rpc: remove settxfee and paytxfee by polespinasa)

    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.

  4. hodlinator renamed this:
    qa: Make `wallet_multiwallet.py` Windows-compatible
    qa: Make wallet_multiwallet.py Windows-compatible
    on Jan 27, 2026
  5. hebasto commented at 3:29 pm on January 27, 2026: member

    Concept ACK.

    Thanks for taking this over!

  6. w0xlt commented at 10:22 pm on January 27, 2026: contributor
    Approach ACK. I’ll review it more closely soon.
  7. in test/functional/test_framework/util.py:81 in 596752a06d outdated
    74@@ -75,7 +75,10 @@ def summarise_dict_differences(thing1, thing2):
    75 def assert_equal(thing1, thing2, *args):
    76     if thing1 != thing2 and not args and isinstance(thing1, dict) and isinstance(thing2, dict):
    77         d1,d2 = summarise_dict_differences(thing1, thing2)
    78-        raise AssertionError("not(%s == %s)\n  in particular not(%s == %s)" % (thing1, thing2, d1, d2))
    79+        if d1 != thing1 or d2 != thing2:
    80+            raise AssertionError(f"not({thing1!s} == {thing2!s})\n  in particular not({d1!s} == {d2!s})")
    81+        else:
    82+            raise AssertionError(f"not({thing1!s} == {thing2!s})")
    


    janb84 commented at 4:49 pm on February 3, 2026:

    Given the test on line 76 , we only enter if thing1 and thing2 are not equal. And and summarise_dict_differences filters to show only differences, we’ll always have either d1 != thing1 or d2 != thing2 or both !=

    What am I missing so that we hit the else case (L80-81)?


    hodlinator commented at 8:48 am on February 5, 2026:

    Say you have:

    0thing1 = {"name": "Alice", "age": 30}
    1thing2 = {}
    

    summarise_dict_differences() will not boil away any similarities between the two, so we’ll end up with:

    0d1 = {"name": "Alice", "age": 30}
    1d2 = {}
    

    so master would print the same values twice, but there’s no need to have the “in particular” part.


    This however:

    0thing1 = {"name": "Alice", "age": 30}
    1thing2 = {"name": "Alice"}
    

    would hopefully result in:

    0d1 = {"age": 30}
    1d2 = {}
    

    so we would want the “in particular” part.


    janb84 commented at 9:22 am on February 5, 2026:
    I’m sorry, I missed the {} collection option. Thanks for the explanation.
  8. janb84 commented at 10:46 am on February 6, 2026: contributor

    ACK 596752a06d530918fafc84110195a7067835e949

    EDIT: I made the wrong judgement on the difference in loggin (seeing more tests) as enough proof that the PR is an improvement next to an code-review. Will re-vist this PR.

    This PR makes wallet_multiwallet.py Windows-compatible. Tested it on windows 11, msvc build (vs 2022)

     02026-02-06T10:25:48.016394Z TestFramework (INFO): PRNG seed is: 3924437959039469419
     12026-02-06T10:25:48.049997Z TestFramework (INFO): Initializing test directory C:\Users\user\AppData\Local\Temp\bitcoin_func_test_nylizqfb
     22026-02-06T10:25:48.550233Z TestFramework (WARNING): Skipping chmod+symlink checks on Windows: chmod works differently due to how access rights work and symlink behavior with regard to the standard library is non-standard on cross-built binaries.
     32026-02-06T10:25:48.756512Z TestFramework (INFO): Test mixed wallets
     42026-02-06T10:25:49.850237Z TestFramework (INFO): Test initialization
     52026-02-06T10:25:52.819255Z TestFramework (INFO): Test balances and fees
     62026-02-06T10:25:54.266821Z TestFramework (INFO): Check for per-wallet settxfee call
     72026-02-06T10:25:54.270096Z TestFramework (INFO): Test dynamic wallet loading
     82026-02-06T10:25:54.748885Z TestFramework (INFO): Load first wallet
     92026-02-06T10:25:54.760269Z TestFramework (INFO): Load second wallet
    102026-02-06T10:25:54.769925Z TestFramework (INFO): Concurrent wallet loading
    112026-02-06T10:25:54.803331Z TestFramework (INFO): Load remaining wallets
    122026-02-06T10:25:54.856230Z TestFramework (INFO): Test dynamic wallet creation
    132026-02-06T10:25:54.929120Z TestFramework (INFO): Test dynamic wallet unloading
    142026-02-06T10:25:56.604190Z TestFramework (INFO): Test wallet backup and restore
    152026-02-06T10:25:57.908829Z TestFramework (INFO): Test wallet lock file is closed
    162026-02-06T10:25:58.309178Z TestFramework (INFO): Stopping nodes
    172026-02-06T10:25:58.464283Z TestFramework (INFO): Cleaning up C:\Users\user\AppData\Local\Temp\bitcoin_func_test_nylizqfb on exit
    182026-02-06T10:25:58.464577Z TestFramework (INFO): Tests successful
    
     02026-02-06T10:44:32.520149Z TestFramework (INFO): PRNG seed is: 9079423242423824445
     12026-02-06T10:44:32.557824Z TestFramework (INFO): Initializing test directory C:\Users\user\AppData\Local\Temp\bitcoin_func_test_3ac39i27
     22026-02-06T10:44:33.134825Z TestFramework (INFO): Verify warning is emitted when failing to scan the wallets directory
     32026-02-06T10:44:33.135065Z TestFramework (WARNING): Skipping test involving chmod as Windows does not support it.
     42026-02-06T10:44:38.490235Z TestFramework (INFO): Check for per-wallet settxfee call
     52026-02-06T10:44:38.492665Z TestFramework (INFO): Test dynamic wallet loading
     62026-02-06T10:44:38.978126Z TestFramework (INFO): Load first wallet
     72026-02-06T10:44:38.990162Z TestFramework (INFO): Load second wallet
     82026-02-06T10:44:38.999576Z TestFramework (INFO): Concurrent wallet loading
     92026-02-06T10:44:39.036463Z TestFramework (INFO): Load remaining wallets
    102026-02-06T10:44:39.087449Z TestFramework (INFO): Test dynamic wallet creation.
    112026-02-06T10:44:39.150340Z TestFramework (INFO): Test dynamic wallet unloading
    122026-02-06T10:44:40.821876Z TestFramework (INFO): Test wallet backup
    132026-02-06T10:44:42.673883Z TestFramework (INFO): Stopping nodes
    142026-02-06T10:44:42.828266Z TestFramework (INFO): Cleaning up C:\Users\user\AppData\Local\Temp\bitcoin_func_test_3ac39i27 on exit
    152026-02-06T10:44:42.828464Z TestFramework (INFO): Tests successful
    

    Test also still works on nix-shell/aarch64

  9. DrahtBot requested review from hebasto on Feb 6, 2026
  10. DrahtBot requested review from w0xlt on Feb 6, 2026
  11. in test/functional/wallet_multiwallet.py:76 in 596752a06d
    82+        self.check_chmod = True
    83+        self.check_symlinks = True
    84+        if platform.system() == 'Windows':
    85+            # Additional context:
    86+            # - chmod: Posix has one user per file while Windows has an ACL approach
    87+            # - symlinks: GCC 13 has FIXME notes for symlinks under Windows:
    


    fanquake commented at 11:59 am on February 6, 2026:

    GCC 13 has FIXME notes for symlinks under Windows:

    I wonder if this will change. The FIXME has existed since 2018, when std::filesystem support for Windows was first added: https://github.com/gcc-mirror/gcc/commit/9534a5e62dc2b81d001f98f1ed582bc3f1d39c80.


    hodlinator commented at 10:15 am on February 9, 2026:

    Updated the comment to document that it’s still the case in latest release instead: https://github.com/bitcoin/bitcoin/blob/9a7b72560ec5b854c036cea8b19c5941650ed968/test/functional/wallet_multiwallet.py#L74-L79

    Hopefully that’s slightly better for maintainability.

    Also dropped the comment about chmod as I don’t think it really added anything relevant to this test beyond what the warning below already states.

  12. hodlinator commented at 10:31 am on February 7, 2026: contributor
    Thanks for your review @janb84! At first I was astonished that the test succeeds for you on master. Then I realized that this PR actually makes the test work for Linux->Windows cross builds. Will make it clearer in the title/PR description.
  13. hodlinator renamed this:
    qa: Make wallet_multiwallet.py Windows-compatible
    qa: Make wallet_multiwallet.py Windows crossbuild-compatible
    on Feb 7, 2026
  14. hodlinator force-pushed on Feb 9, 2026
  15. DrahtBot added the label CI failed on Feb 9, 2026
  16. DrahtBot commented at 11:29 am on February 9, 2026: contributor

    🚧 At least one of the CI tasks failed. Task Alpine (musl): https://github.com/bitcoin/bitcoin/actions/runs/21820908595/job/62953694277 LLM reason (✨ experimental): mptest timed out (Timeout) causing the CI failure.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  17. janb84 commented at 12:46 pm on February 9, 2026: contributor

    ACK 9a7b72560ec5b854c036cea8b19c5941650ed968

    I revisited the PR, now using a cross compilation build. Using gcc, the master branch functional test will indeed fail to run:

      0Temporary test directory at C:\Users\user\AppData\Local\Temp/test_runner_β‚Ώ_πŸƒ_20260209_120146
      1Remaining jobs: [wallet_multiwallet.py, wallet_multiwallet.py --usecli]
      21/2 - wallet_multiwallet.py failed, Duration: 4 s
      3
      4stdout:
      52026-02-09T11:01:50.077850Z TestFramework (INFO): PRNG seed is: 4370893628585504645
      62026-02-09T11:01:50.136334Z TestFramework (INFO): Initializing test directory C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_1
      72026-02-09T11:01:51.071252Z TestFramework (INFO): Verify warning is emitted when failing to scan the wallets directory
      82026-02-09T11:01:51.071428Z TestFramework (WARNING): Skipping test involving chmod as Windows does not support it.
      92026-02-09T11:01:54.529466Z TestFramework (ERROR): Unexpected exception
     10Traceback (most recent call last):
     11  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_framework.py", line 142, in main
     12    self.run_test()
     13    ~~~~~~~~~~~~~^^
     14  File "C:\Users\user\bitcoin\build\/test/functional/wallet_multiwallet.py", line 150, in run_test
     15    with self.nodes[0].assert_debug_log(expected_msgs=["Error while scanning wallet dir"]):
     16         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     17  File "C:\Users\user\AppData\Local\Programs\Python\Python314\Lib\contextlib.py", line 148, in __exit__
     18    next(self.gen)
     19    ~~~~^^^^^^^^^^
     20  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_node.py", line 584, in assert_debug_log
     21    self._raise_assertion_error(f'Expected message(s) {remaining_expected!s} '
     22    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     23                                f'not found in log:\n\n{join_log(log)}\n\n')
     24                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     25  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_node.py", line 229, in _raise_assertion_error
     26    raise AssertionError(self._node_msg(msg))
     27AssertionError: [node 0] Expected message(s) ['Error while scanning wallet dir'] not found in log:
     28
     29 - 2026-02-09T11:01:52.527937Z [http] [httpserver.cpp:307] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:59769
     30 - 2026-02-09T11:01:52.528211Z [httpworker.0] [rpc/request.cpp:243] [parse] [rpc] ThreadRPCServer method=listwalletdir user=__cookie__
     31 - 2026-02-09T11:01:52.623421Z [httpworker.0] [wallet/db.cpp:69] [ListDatabases] [warning] Error scanning directory entries under C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_1\node0\regtest\wallets: No such file or directory
     32
     33
     342026-02-09T11:01:54.584969Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.
     352026-02-09T11:01:54.585174Z TestFramework (WARNING): Not cleaning up dir C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_1
     362026-02-09T11:01:54.585290Z TestFramework (ERROR): Test failed. Test logging available at C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_1/test_framework.log
     372026-02-09T11:01:54.585616Z TestFramework (ERROR):
     382026-02-09T11:01:54.586080Z TestFramework (ERROR): Hint: Call C:\Users\user\bitcoin\build\test\functional\combine_logs.py 'C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_1' to consolidate all logs
     392026-02-09T11:01:54.586260Z TestFramework (ERROR):
     402026-02-09T11:01:54.586372Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.
     412026-02-09T11:01:54.586471Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues
     422026-02-09T11:01:54.586540Z TestFramework (ERROR):
     43
     44
     45stderr:
     46[node 0] Cleaning up leftover process
     47
     48
     49Remaining jobs: [wallet_multiwallet.py --usecli]
     502/2 - wallet_multiwallet.py --usecli failed, Duration: 6 s
     51
     52stdout:
     532026-02-09T11:01:50.088312Z TestFramework (INFO): PRNG seed is: 8248417181429283859
     542026-02-09T11:01:50.138382Z TestFramework (INFO): Initializing test directory C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_0
     552026-02-09T11:01:51.977816Z TestFramework (INFO): Verify warning is emitted when failing to scan the wallets directory
     562026-02-09T11:01:51.978010Z TestFramework (WARNING): Skipping test involving chmod as Windows does not support it.
     572026-02-09T11:01:55.794679Z TestFramework (ERROR): Unexpected exception
     58Traceback (most recent call last):
     59  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_framework.py", line 142, in main
     60    self.run_test()
     61    ~~~~~~~~~~~~~^^
     62  File "C:\Users\user\bitcoin\build\/test/functional/wallet_multiwallet.py", line 150, in run_test
     63    with self.nodes[0].assert_debug_log(expected_msgs=["Error while scanning wallet dir"]):
     64         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     65  File "C:\Users\user\AppData\Local\Programs\Python\Python314\Lib\contextlib.py", line 148, in __exit__
     66    next(self.gen)
     67    ~~~~^^^^^^^^^^
     68  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_node.py", line 584, in assert_debug_log
     69    self._raise_assertion_error(f'Expected message(s) {remaining_expected!s} '
     70    ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     71                                f'not found in log:\n\n{join_log(log)}\n\n')
     72                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     73  File "C:\Users\user\bitcoin\build\test\functional\test_framework\test_node.py", line 229, in _raise_assertion_error
     74    raise AssertionError(self._node_msg(msg))
     75AssertionError: [node 0] Expected message(s) ['Error while scanning wallet dir'] not found in log:
     76
     77 - 2026-02-09T11:01:53.850291Z [http] [httpserver.cpp:307] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:59814
     78 - 2026-02-09T11:01:53.850472Z [httpworker.1] [rpc/request.cpp:243] [parse] [rpc] ThreadRPCServer method=listwalletdir user=__cookie__
     79 - 2026-02-09T11:01:53.936116Z [httpworker.1] [wallet/db.cpp:69] [ListDatabases] [warning] Error scanning directory entries under C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_0\node0\regtest\wallets: No such file or directory
     80
     81
     822026-02-09T11:01:55.850081Z TestFramework (INFO): Not stopping nodes as test failed. The dangling processes will be cleaned up later.
     832026-02-09T11:01:55.850322Z TestFramework (WARNING): Not cleaning up dir C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_0
     842026-02-09T11:01:55.850430Z TestFramework (ERROR): Test failed. Test logging available at C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_0/test_framework.log
     852026-02-09T11:01:55.850616Z TestFramework (ERROR):
     862026-02-09T11:01:55.851275Z TestFramework (ERROR): Hint: Call C:\Users\user\bitcoin\build\test\functional\combine_logs.py 'C:\Users\user\AppData\Local\Temp\test_runner_β‚Ώ_πŸƒ_20260209_120146\wallet_multiwallet_0' to consolidate all logs
     872026-02-09T11:01:55.851362Z TestFramework (ERROR):
     882026-02-09T11:01:55.851432Z TestFramework (ERROR): If this failure happened unexpectedly or intermittently, please file a bug and provide a link or upload of the combined log.
     892026-02-09T11:01:55.851523Z TestFramework (ERROR): https://github.com/bitcoin/bitcoin/issues
     902026-02-09T11:01:55.851626Z TestFramework (ERROR):
     91
     92
     93stderr:
     94[node 0] Cleaning up leftover process
     95
     96
     97
     98TEST                           | STATUS    | DURATION
     99
    100wallet_multiwallet.py          | βœ– Failed  | 4 s
    101wallet_multiwallet.py --usecli | βœ– Failed  | 6 s
    102
    103ALL                            | βœ– Failed  | 10 s (accumulated)
    

    Using the same cross compilation build, this PR fixes the functional test:

     0python .\build\test\functional\test_runner.py wallet_multiwallet.py
     1Temporary test directory at C:\Users\user\AppData\Local\Temp/test_runner_β‚Ώ_πŸƒ_20260209_132101
     2Remaining jobs: [wallet_multiwallet.py, wallet_multiwallet.py --usecli]
     31/2 - wallet_multiwallet.py passed, Duration: 14 s
     4Remaining jobs: [wallet_multiwallet.py --usecli]
     52/2 - wallet_multiwallet.py --usecli passed, Duration: 24 s
     6
     7TEST                           | STATUS    | DURATION
     8
     9wallet_multiwallet.py          | βœ“ Passed  | 14 s
    10wallet_multiwallet.py --usecli | βœ“ Passed  | 24 s
    11
    12ALL                            | βœ“ Passed  | 38 s (accumulated)
    13Runtime: 24 s
    
  18. DrahtBot removed the label CI failed on Feb 10, 2026
  19. DrahtBot added the label Needs rebase on Feb 13, 2026
  20. refactor(qa): Remove unused option
    Last use was removed in 0d32d661481f099af572e7a08a50e17bcc165c44.
    ad1448431f
  21. scripted-diff: self.nodes[0] => node
    -BEGIN VERIFY SCRIPT-
    sed --in-place 's/self\.nodes\[0\]/node/g; s/node \= node/node \= self\.nodes\[0\]/' ./test/functional/wallet_multiwallet.py
    -END VERIFY SCRIPT-
    d37a3eaa63
  22. refactor(qa): Lift out functions to outer scopes
    This prepares for later breaking apart of run_test().
    
    Note that the "wallet" lambda was renamed to "get_wallet" since otherwise the Python interpreter emitted:
    "UnboundLocalError: cannot access local variable 'wallet' where it is not associated with a value"
    ab56e24d6e
  23. move-only(qa): Move wallet creation check down to others
    Makes the functions broken out from run_test() in the next commit more cohesive.
    992fc207cc
  24. refactor(qa): Break apart ginormous run_test() 8f632acfee
  25. qa: Check for platform-independent part of error message
    On Windows one gets different exception messages depending on whether running a native build or cross build.
    f5ace0aa39
  26. qa: Test scanning errors individually
    This change ensures that each condition potentially triggering the
    "Error while scanning" log message is tested independently, avoiding
    false positives.
    
    Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
    f012f1158a
  27. qa: Disable parts of the test when running under Windows or root
    test_scanning_sub_dir():
    - Remove try/finally - we don't need to clean up after a failed test (done in this commit to maintain indentation).
    
    Regarding symlinks: https://github.com/bitcoin/bitcoin/pull/31410#issuecomment-3554721014
    
    Co-authored-by: Ava Chow <github@achow101.com>
    2bcb81d117
  28. ci: Enable `wallet_multiwallet.py` in "Windows, test cross-built" job
    Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
    1e1f42bcd8
  29. qa: Avoid duplicating output in case the diff is the same 022b6e7c59
  30. hodlinator force-pushed on Feb 13, 2026
  31. hodlinator commented at 8:29 pm on February 13, 2026: contributor
    Latest push resolves conflict with master where exclusion of wallet_multiwallet.py was moved from ci.yml to ci-windows-cross.py.
  32. DrahtBot removed the label Needs rebase on Feb 13, 2026
  33. janb84 commented at 1:49 pm on February 16, 2026: contributor
    re ACK 022b6e7c594dfa0a90aa1865e70160aa1317523d
  34. in test/functional/wallet_multiwallet.py:128 in 022b6e7c59
    160+        self.log.info("Test mixed wallets")
    161         # create symlink to verify wallet directory path can be referenced
    162         # through symlink
    163-        os.mkdir(wallet_dir('w7'))
    164-        os.symlink('w7', wallet_dir('w7_symlink'))
    165+        os.mkdir(wallet_dir(node, 'w7'))
    


    w0xlt commented at 2:33 am on February 18, 2026:

    nit: not tested, but symlink-specific setup and checks could be skipped when symlink creation isn’t supported.

     0     def test_mixed_wallets(self, node):
     1         self.log.info("Test mixed wallets")
     2-        # create symlink to verify wallet directory path can be referenced
     3-        # through symlink
     4-        os.mkdir(wallet_dir(node, 'w7'))
     5-        os.symlink('w7', wallet_dir(node, 'w7_symlink'))
     6-
     7         if self.check_symlinks:
     8+            # Create symlink to verify wallet directory path can be referenced through symlink.
     9+            os.mkdir(wallet_dir(node, 'w7'))
    10-        os.mkdir(wallet_dir(node, 'w7'))
    11-        os.symlink('w7', wallet_dir(node, 'w7_symlink'))
    12-
    13         if self.check_symlinks:
    14+            # Create symlink to verify wallet directory path can be referenced through symlink.
    15+            os.mkdir(wallet_dir(node, 'w7'))
    16+            os.symlink('w7', wallet_dir(node, 'w7_symlink'))
    17             os.symlink('..', wallet_dir(node, 'recursive_dir_symlink'))
    18 
    19         # rename wallet.dat to make sure plain wallet file paths (as opposed to
    20@@ -153,12 +147,15 @@ class MultiWalletTest(BitcoinTestFramework):
    21         #   w          - to verify wallet name matching works when one wallet path is prefix of another
    22         #   sub/w5     - to verify relative wallet path is created correctly
    23         #   extern/w6  - to verify absolute wallet path is created correctly
    24-        #   w7_symlink - to verify symlinked wallet path is initialized correctly
    25+        #   w7_symlink - to verify symlinked wallet path is initialized correctly (symlink-capable platforms only)
    26         #   w8         - to verify existing wallet file is loaded correctly. Not tested for SQLite wallets as this is a deprecated BDB behavior.
    27         #   ''         - to verify default wallet file is created correctly
    28-        to_create = ['w1', 'w2', 'w3', 'w', 'sub/w5', 'w7_symlink']
    29+        to_create = ['w1', 'w2', 'w3', 'w', 'sub/w5']
    30+        if self.check_symlinks:
    31+            to_create.append('w7_symlink')
    32         in_wallet_dir = [w.replace('/', os.path.sep) for w in to_create]  # Wallets in the wallet dir
    33-        in_wallet_dir.append('w7')  # w7 is not loaded or created, but will be listed by listwalletdir because w7_symlink
    34+        if self.check_symlinks:
    35+            in_wallet_dir.append('w7')  # w7 is not loaded or created, but will be listed by listwalletdir because w7_symlink
    36         to_create.append(os.path.join(self.options.tmpdir, 'extern/w6'))  # External, not in the wallet dir, so we need to avoid adding it to in_wallet_dir
    37         to_load = [self.default_wallet_name]
    38:
    39-        os.mkdir(wallet_dir(node, 'w7'))
    40-        os.symlink('w7', wallet_dir(node, 'w7_symlink'))
    41-
    42         if self.check_symlinks:
    43+            # Create symlink to verify wallet directory path can be referenced through symlink.
    44+            os.mkdir(wallet_dir(node, 'w7'))
    45+            os.symlink('w7', wallet_dir(node, 'w7_symlink'))
    46             os.symlink('..', wallet_dir(node, 'recursive_dir_symlink'))
    47 
    48         # rename wallet.dat to make sure plain wallet file paths (as opposed to
    49@@ -153,12 +147,15 @@ class MultiWalletTest(BitcoinTestFramework):
    50         #   w          - to verify wallet name matching works when one wallet path is prefix of another
    51         #   sub/w5     - to verify relative wallet path is created correctly
    52         #   extern/w6  - to verify absolute wallet path is created correctly
    53-        #   w7_symlink - to verify symlinked wallet path is initialized correctly
    54+        #   w7_symlink - to verify symlinked wallet path is initialized correctly (symlink-capable platforms only)
    55         #   w8         - to verify existing wallet file is loaded correctly. Not tested for SQLite wallets as this is a deprecated BDB behavior.
    56         #   ''         - to verify default wallet file is created correctly
    57-        to_create = ['w1', 'w2', 'w3', 'w', 'sub/w5', 'w7_symlink']
    58+        to_create = ['w1', 'w2', 'w3', 'w', 'sub/w5']
    59+        if self.check_symlinks:
    60+            to_create.append('w7_symlink')
    61         in_wallet_dir = [w.replace('/', os.path.sep) for w in to_create]  # Wallets in the wallet dir
    62-        in_wallet_dir.append('w7')  # w7 is not loaded or created, but will be listed by listwalletdir because w7_symlink
    63+        if self.check_symlinks:
    64+            in_wallet_dir.append('w7')  # w7 is not loaded or created, but will be listed by listwalletdir because w7_symlink
    65         to_create.append(os.path.join(self.options.tmpdir, 'extern/w6'))  # External, not in the wallet dir, so we need to avoid adding it to in_wallet_dir
    66         to_load = [self.default_wallet_name]
    

    maflcko commented at 10:16 am on February 18, 2026:

    nit: not tested, but symlink-specific setup and checks could be skipped when symlink creation isn’t supported.

    Why would that be better? That just makes it harder to enable in the future: E.g via commit 677297e8522a81225bc537795f51468e49d85f5a

  35. DrahtBot requested review from w0xlt on Feb 18, 2026
  36. gniumg-source referenced this in commit a93cf6c8d2 on Feb 18, 2026
  37. gniumg-source referenced this in commit e73f089772 on Feb 18, 2026

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-02-18 12:12 UTC

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