Repository: bitcoin/bitcoin
File: test/functional/wallet_multiwallet.py (Python)

Code before:
        wallet_dir = lambda *p: data_dir('wallets', *p)
        wallet = lambda name: node.get_wallet_rpc(name)

        def wallet_file(name):
            if name == self.default_wallet_name:
                return wallet_dir(self.default_wallet_name, self.wallet_data_filename)
            if os.path.isdir(wallet_dir(name)):
                return wallet_dir(name, "wallet.dat")
            return wallet_dir(name)

        assert_equal(self.nodes[0].listwalletdir(), {'wallets': [{'name': self.default_wallet_name, "warnings": []}]})

        # check wallet.dat is created
        self.stop_nodes()
        assert_equal(os.path.isfile(wallet_dir(self.default_wallet_name, self.wallet_data_filename)), True)

        # create symlink to verify wallet directory path can be referenced
        # through symlink
        os.mkdir(wallet_dir('w7'))
        os.symlink('w7', wallet_dir('w7_symlink'))

        os.symlink('..', wallet_dir('recursive_dir_symlink'))

        os.mkdir(wallet_dir('self_walletdat_symlink'))
        os.symlink('wallet.dat', wallet_dir('self_walletdat_symlink/wallet.dat'))

        # rename wallet.dat to make sure plain wallet file paths (as opposed to
        # directory paths) can be loaded
        # create another dummy wallet for use in testing backups later
        self.start_node(0)
        node.createwallet("empty")
        node.createwallet("plain")
        node.createwallet("created")
        self.stop_nodes()
        empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat')
        os.rename(wallet_file("empty"), empty_wallet)
        shutil.rmtree(wallet_dir("empty"))
        empty_created_wallet = os.path.join(self.options.tmpdir, 'empty.created.dat')
        os.rename(wallet_dir("created", self.wallet_data_filename), empty_created_wallet)
        shutil.rmtree(wallet_dir("created"))
        os.rename(wallet_file("plain"), wallet_dir("w8"))
        shutil.rmtree(wallet_dir("plain"))

        # restart node with a mix of wallet names:
        #   w1, w2, w3 - to verify new wallets created when non-existing paths specified
        #   w          - to verify wallet name matching works when one wallet path is prefix of another
        #   sub/w5     - to verify relative wallet path is created correctly
        #   extern/w6  - to verify absolute wallet path is created correctly
        #   w7_symlink - to verify symlinked wallet path is initialized correctly
        #   w8         - to verify existing wallet file is loaded correctly. Not tested for SQLite wallets as this is a deprecated BDB behavior.
        #   ''         - to verify default wallet file is created correctly

Review comment (bug):
why discard the result. It should be expected to be empty, no?


nit: If you want to take an extra step, it could make sense to pass up the warnings into the result dict as `"warnings": ["...",]`, instead of relying on the debug log

Code after:
        wallet_dir = lambda *p: data_dir('wallets', *p)
        wallet = lambda name: node.get_wallet_rpc(name)

        def wallet_file(name):
            if name == self.default_wallet_name:
                return wallet_dir(self.default_wallet_name, self.wallet_data_filename)
            if os.path.isdir(wallet_dir(name)):
                return wallet_dir(name, "wallet.dat")
            return wallet_dir(name)

        assert_equal(self.nodes[0].listwalletdir(), {'wallets': [{'name': self.default_wallet_name, "warnings": []}]})

        # check wallet.dat is created
        self.stop_nodes()
        assert_equal(os.path.isfile(wallet_dir(self.default_wallet_name, self.wallet_data_filename)), True)

        self.log.info("Verify warning is emitted when failing to scan the wallets directory")
        if platform.system() == 'Windows':
            self.log.warning('Skipping test involving chmod as Windows does not support it.')
        elif os.geteuid() == 0:
            self.log.warning('Skipping test involving chmod as it requires a non-root user.')
        else:
            self.start_node(0)
            with self.nodes[0].assert_debug_log(unexpected_msgs=['Error scanning directory entries under'], expected_msgs=[]):
                result = self.nodes[0].listwalletdir()
                assert_equal(result, {'wallets': [{'name': 'default_wallet', 'warnings': []}]})
            os.chmod(data_dir('wallets'), 0)
            with self.nodes[0].assert_debug_log(expected_msgs=['Error scanning directory entries under']):
                result = self.nodes[0].listwalletdir()
                assert_equal(result, {'wallets': []})
            self.stop_node(0)
            # Restore permissions
            os.chmod(data_dir('wallets'), stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)

        # create symlink to verify wallet directory path can be referenced
        # through symlink
        os.mkdir(wallet_dir('w7'))
        os.symlink('w7', wallet_dir('w7_symlink'))

        os.symlink('..', wallet_dir('recursive_dir_symlink'))

        os.mkdir(wallet_dir('self_walletdat_symlink'))
        os.symlink('wallet.dat', wallet_dir('self_walletdat_symlink/wallet.dat'))

        # rename wallet.dat to make sure plain wallet file paths (as opposed to
        # directory paths) can be loaded
        # create another dummy wallet for use in testing backups later
        self.start_node(0)
        node.createwallet("empty")
        node.createwallet("plain")
        node.createwallet("created")