it seems that all other functional tests that have such unit tests are all in test/functional/test_framework instead.
<details>
<summary>Details</summary>
test % grep -r 'unittest.TestCase' .
./functional/feature_framework_unit_tests.py:# the output of `git grep unittest.TestCase ./test/functional/test_framework`
./functional/test_framework/address.py:class TestFrameworkScript(unittest.TestCase):
./functional/test_framework/crypto/ellswift.py:class TestFrameworkEllSwift(unittest.TestCase):
./functional/test_framework/crypto/muhash.py:class TestFrameworkMuhash(unittest.TestCase):
./functional/test_framework/crypto/poly1305.py:class TestFrameworkPoly1305(unittest.TestCase):
./functional/test_framework/crypto/chacha20.py:class TestFrameworkChacha(unittest.TestCase):
./functional/test_framework/crypto/ripemd160.py:class TestFrameworkKey(unittest.TestCase):
./functional/test_framework/crypto/bip324_cipher.py:class TestFrameworkAEAD(unittest.TestCase):
./functional/test_framework/crypto/secp256k1.py:class TestFrameworkSecp256k1(unittest.TestCase):
./functional/test_framework/key.py:class TestFrameworkKey(unittest.TestCase):
./functional/test_framework/script_util.py:class TestFrameworkScriptUtil(unittest.TestCase):
./functional/test_framework/wallet_util.py:class TestFrameworkWalletUtil(unittest.TestCase):
./functional/test_framework/segwit_addr.py:class TestFrameworkScript(unittest.TestCase):
./functional/test_framework/blocktools.py:class TestFrameworkBlockTools(unittest.TestCase):
./functional/test_framework/messages.py:class TestFrameworkScript(unittest.TestCase):
./functional/test_framework/compressor.py:class TestFrameworkCompressor(unittest.TestCase):
./functional/test_framework/script.py:class TestFrameworkScript(unittest.TestCase):
./functional/tool_rpcauth.py:class TestRPCAuth(unittest.TestCase):
</details>
But instead of moving the new test there - given that all other tool_* tests are in the same place -, we could change the test structure instead to correspond to the other ones in the same category
<details>
<summary>Details</summary>
git ls-files test/functional/tool_*.py
test/functional/tool_bitcoin_chainstate.py
test/functional/tool_rpcauth.py
test/functional/tool_signet_miner.py
test/functional/tool_utils.py
test/functional/tool_utxo_to_sqlite.py
test/functional/tool_wallet.py
</details>
I was thinking something like this:
#!/usr/bin/env python3
# Copyright (c) 2015-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test share/rpcauth/rpcauth.py
"""
import hmac
import re
from hashlib import sha256
from importlib.util import spec_from_file_location, module_from_spec
from test_framework.test_framework import BitcoinTestFramework
class ToolRPCAuthTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 0 # No node/datadir needed
def setup_network(self):
pass # nothing to start
def run_test(self):
spec = spec_from_file_location('rpcauth', self.config['environment']['RPCAUTH'])
spec.loader.exec_module(rpcauth := module_from_spec(spec))
self.log.info("Verify generate_salt() returns hex of correct length")
for i in range(16, 32 + 1):
assert len(rpcauth.generate_salt(i)) == i * 2
self.log.info("Test that generated passwords only consist of urlsafe characters")
assert re.fullmatch(r"[-\w]+", rpcauth.generate_password(), flags=re.ASCII)
self.log.info("Verify password_to_hmac() matches SHA-256 HMAC")
salt = rpcauth.generate_salt(16)
pwd = rpcauth.generate_password()
expected = hmac.new(salt.encode(), pwd.encode(), sha256).hexdigest()
assert rpcauth.password_to_hmac(salt, pwd) == expected
if __name__ == '__main__':
ToolRPCAuthTest(__file__).main()