Skip to content

Commit b3f7e85

Browse files
basfromanthewhalekingcamfairchild
authored
[Tests] AsyncSubtensor (Part 5) (#2411)
* added tests from `AsyncSubtensor.get_netuids_for_hotkey` until `AsyncSubtensor.neurons_lite` * ruff * move out `_decode_hex_identity_dict` from inner function * added tests until `AsyncSubtensor.query_identity` * added tests until `AsyncSubtensor.get_hotkey_owner` * Handle new PasswordError from btwallet (#2406) * Handles new PasswordError from btwallet. * Ruff, docstrings. * Fixes hotkey unlock rather than coldkey * Added unit test. * Added unit test. Add integration test. * Removed coldkeypub * Opinions. * More tests * grammar * Update test_utils.py * bump up btwallet version * fix wording * fix wording * Update tests/unit_tests/utils/test_utils.py Co-authored-by: Cameron Fairchild <[email protected]> --------- Co-authored-by: Roman <[email protected]> Co-authored-by: Roman <[email protected]> Co-authored-by: Cameron Fairchild <[email protected]> * [Tests] AsyncSubtensor (Part 4) (#2410) * added tests from `AsyncSubtensor.get_netuids_for_hotkey` until `AsyncSubtensor.neurons_lite` * ruff * move out `_decode_hex_identity_dict` from inner function * added tests until `AsyncSubtensor.query_identity` * added tests from `AsyncSubtensor.get_netuids_for_hotkey` until `AsyncSubtensor.neurons_lite` * fix * ruff --------- Co-authored-by: Benjamin Himes <[email protected]> Co-authored-by: Cameron Fairchild <[email protected]>
1 parent 8aefb55 commit b3f7e85

File tree

1 file changed

+233
-8
lines changed

1 file changed

+233
-8
lines changed

tests/unit_tests/test_async_subtensor.py

Lines changed: 233 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,7 +1083,7 @@ async def test_get_delegated_no_block_hash_no_reuse(subtensor, mocker):
10831083
fake_coldkey_ss58 = "fake_ss58_address"
10841084

10851085
mocked_ss58_to_vec_u8 = mocker.Mock(return_value=b"encoded_coldkey")
1086-
mocker.patch("bittensor.core.async_subtensor.ss58_to_vec_u8", mocked_ss58_to_vec_u8)
1086+
mocker.patch.object(async_subtensor, "ss58_to_vec_u8", mocked_ss58_to_vec_u8)
10871087

10881088
mocked_rpc_request = mocker.AsyncMock(return_value={"result": b"mocked_result"})
10891089
subtensor.substrate.rpc_request = mocked_rpc_request
@@ -1113,7 +1113,7 @@ async def test_get_delegated_with_block_hash(subtensor, mocker):
11131113
fake_block_hash = "fake_block_hash"
11141114

11151115
mocked_ss58_to_vec_u8 = mocker.Mock(return_value=b"encoded_coldkey")
1116-
mocker.patch("bittensor.core.async_subtensor.ss58_to_vec_u8", mocked_ss58_to_vec_u8)
1116+
mocker.patch.object(async_subtensor, "ss58_to_vec_u8", mocked_ss58_to_vec_u8)
11171117

11181118
mocked_rpc_request = mocker.AsyncMock(return_value={"result": b"mocked_result"})
11191119
subtensor.substrate.rpc_request = mocked_rpc_request
@@ -1145,7 +1145,7 @@ async def test_get_delegated_with_reuse_block(subtensor, mocker):
11451145
subtensor.substrate.last_block_hash = "last_block_hash"
11461146

11471147
mocked_ss58_to_vec_u8 = mocker.Mock(return_value=b"encoded_coldkey")
1148-
mocker.patch("bittensor.core.async_subtensor.ss58_to_vec_u8", mocked_ss58_to_vec_u8)
1148+
mocker.patch.object(async_subtensor, "ss58_to_vec_u8", mocked_ss58_to_vec_u8)
11491149

11501150
mocked_rpc_request = mocker.AsyncMock(return_value={"result": b"mocked_result"})
11511151
subtensor.substrate.rpc_request = mocked_rpc_request
@@ -1177,7 +1177,7 @@ async def test_get_delegated_with_empty_result(subtensor, mocker):
11771177
fake_coldkey_ss58 = "fake_ss58_address"
11781178

11791179
mocked_ss58_to_vec_u8 = mocker.Mock(return_value=b"encoded_coldkey")
1180-
mocker.patch("bittensor.core.async_subtensor.ss58_to_vec_u8", mocked_ss58_to_vec_u8)
1180+
mocker.patch.object(async_subtensor, "ss58_to_vec_u8", mocked_ss58_to_vec_u8)
11811181

11821182
mocked_rpc_request = mocker.AsyncMock(return_value={})
11831183
subtensor.substrate.rpc_request = mocked_rpc_request
@@ -1204,8 +1204,9 @@ async def test_query_identity_successful(subtensor, mocker):
12041204
mocked_query = mocker.AsyncMock(return_value=fake_identity_info)
12051205
subtensor.substrate.query = mocked_query
12061206

1207-
mocker.patch(
1208-
"bittensor.core.async_subtensor._decode_hex_identity_dict",
1207+
mocker.patch.object(
1208+
async_subtensor,
1209+
"_decode_hex_identity_dict",
12091210
return_value={"stake": "01 02"},
12101211
)
12111212

@@ -1256,8 +1257,9 @@ async def test_query_identity_type_error(subtensor, mocker):
12561257
mocked_query = mocker.AsyncMock(return_value=fake_identity_info)
12571258
subtensor.substrate.query = mocked_query
12581259

1259-
mocker.patch(
1260-
"bittensor.core.async_subtensor._decode_hex_identity_dict",
1260+
mocker.patch.object(
1261+
async_subtensor,
1262+
"_decode_hex_identity_dict",
12611263
side_effect=TypeError,
12621264
)
12631265

@@ -1273,3 +1275,226 @@ async def test_query_identity_type_error(subtensor, mocker):
12731275
reuse_block_hash=False,
12741276
)
12751277
assert result == {}
1278+
1279+
1280+
@pytest.mark.asyncio
1281+
async def test_weights_successful(subtensor, mocker):
1282+
"""Tests weights method with successful weight distribution retrieval."""
1283+
# Preps
1284+
fake_netuid = 1
1285+
fake_block_hash = "block_hash"
1286+
fake_weights = [
1287+
(0, [(1, 10), (2, 20)]),
1288+
(1, [(0, 15), (2, 25)]),
1289+
]
1290+
1291+
async def mock_query_map(**_):
1292+
for uid, w in fake_weights:
1293+
yield uid, w
1294+
1295+
mocker.patch.object(subtensor.substrate, "query_map", side_effect=mock_query_map)
1296+
1297+
# Call
1298+
result = await subtensor.weights(netuid=fake_netuid, block_hash=fake_block_hash)
1299+
1300+
# Asserts
1301+
subtensor.substrate.query_map.assert_called_once_with(
1302+
module="SubtensorModule",
1303+
storage_function="Weights",
1304+
params=[fake_netuid],
1305+
block_hash=fake_block_hash,
1306+
)
1307+
assert result == fake_weights
1308+
1309+
1310+
@pytest.mark.asyncio
1311+
async def test_bonds(subtensor, mocker):
1312+
"""Tests bonds method with successful bond distribution retrieval."""
1313+
# Preps
1314+
fake_netuid = 1
1315+
fake_block_hash = "block_hash"
1316+
fake_bonds = [
1317+
(0, [(1, 100), (2, 200)]),
1318+
(1, [(0, 150), (2, 250)]),
1319+
]
1320+
1321+
async def mock_query_map(**_):
1322+
for uid, b in fake_bonds:
1323+
yield uid, b
1324+
1325+
mocker.patch.object(subtensor.substrate, "query_map", side_effect=mock_query_map)
1326+
1327+
# Call
1328+
result = await subtensor.bonds(netuid=fake_netuid, block_hash=fake_block_hash)
1329+
1330+
# Asserts
1331+
subtensor.substrate.query_map.assert_called_once_with(
1332+
module="SubtensorModule",
1333+
storage_function="Bonds",
1334+
params=[fake_netuid],
1335+
block_hash=fake_block_hash,
1336+
)
1337+
assert result == fake_bonds
1338+
1339+
1340+
@pytest.mark.asyncio
1341+
async def test_does_hotkey_exist_true(subtensor, mocker):
1342+
"""Tests does_hotkey_exist method when the hotkey exists and is valid."""
1343+
# Preps
1344+
fake_hotkey_ss58 = "valid_hotkey"
1345+
fake_block_hash = "block_hash"
1346+
fake_query_result = ["decoded_account_id"]
1347+
1348+
mocked_query = mocker.AsyncMock(return_value=fake_query_result)
1349+
subtensor.substrate.query = mocked_query
1350+
1351+
mocked_decode_account_id = mocker.Mock(return_value="another_account_id")
1352+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
1353+
1354+
# Call
1355+
result = await subtensor.does_hotkey_exist(
1356+
hotkey_ss58=fake_hotkey_ss58, block_hash=fake_block_hash
1357+
)
1358+
1359+
# Asserts
1360+
mocked_query.assert_called_once_with(
1361+
module="SubtensorModule",
1362+
storage_function="Owner",
1363+
params=[fake_hotkey_ss58],
1364+
block_hash=fake_block_hash,
1365+
reuse_block_hash=False,
1366+
)
1367+
mocked_decode_account_id.assert_called_once_with(fake_query_result[0])
1368+
assert result is True
1369+
1370+
1371+
@pytest.mark.asyncio
1372+
async def test_does_hotkey_exist_false_for_specific_account(subtensor, mocker):
1373+
"""Tests does_hotkey_exist method when the hotkey exists but matches the specific account ID to ignore."""
1374+
# Preps
1375+
fake_hotkey_ss58 = "ignored_hotkey"
1376+
fake_query_result = ["ignored_account_id"]
1377+
1378+
mocked_query = mocker.AsyncMock(return_value=fake_query_result)
1379+
subtensor.substrate.query = mocked_query
1380+
1381+
# Mock the decode_account_id function to return the specific account ID that should be ignored
1382+
mocked_decode_account_id = mocker.Mock(
1383+
return_value="5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM"
1384+
)
1385+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
1386+
1387+
# Call
1388+
result = await subtensor.does_hotkey_exist(hotkey_ss58=fake_hotkey_ss58)
1389+
1390+
# Asserts
1391+
mocked_query.assert_called_once_with(
1392+
module="SubtensorModule",
1393+
storage_function="Owner",
1394+
params=[fake_hotkey_ss58],
1395+
block_hash=None,
1396+
reuse_block_hash=False,
1397+
)
1398+
mocked_decode_account_id.assert_called_once_with(fake_query_result[0])
1399+
assert result is False
1400+
1401+
1402+
@pytest.mark.asyncio
1403+
async def test_get_hotkey_owner_successful(subtensor, mocker):
1404+
"""Tests get_hotkey_owner method when the hotkey exists and has an owner."""
1405+
# Preps
1406+
fake_hotkey_ss58 = "valid_hotkey"
1407+
fake_block_hash = "block_hash"
1408+
fake_owner_account_id = "owner_account_id"
1409+
1410+
mocked_query = mocker.AsyncMock(return_value=[fake_owner_account_id])
1411+
subtensor.substrate.query = mocked_query
1412+
1413+
mocked_decode_account_id = mocker.Mock(return_value="decoded_owner_account_id")
1414+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
1415+
1416+
mocked_does_hotkey_exist = mocker.AsyncMock(return_value=True)
1417+
subtensor.does_hotkey_exist = mocked_does_hotkey_exist
1418+
1419+
# Call
1420+
result = await subtensor.get_hotkey_owner(
1421+
hotkey_ss58=fake_hotkey_ss58, block_hash=fake_block_hash
1422+
)
1423+
1424+
# Asserts
1425+
mocked_query.assert_called_once_with(
1426+
module="SubtensorModule",
1427+
storage_function="Owner",
1428+
params=[fake_hotkey_ss58],
1429+
block_hash=fake_block_hash,
1430+
)
1431+
mocked_decode_account_id.assert_called_once_with(fake_owner_account_id)
1432+
mocked_does_hotkey_exist.assert_awaited_once_with(
1433+
fake_hotkey_ss58, block_hash=fake_block_hash
1434+
)
1435+
assert result == "decoded_owner_account_id"
1436+
1437+
1438+
@pytest.mark.asyncio
1439+
async def test_get_hotkey_owner_non_existent_hotkey(subtensor, mocker):
1440+
"""Tests get_hotkey_owner method when the hotkey does not exist in the query result."""
1441+
# Preps
1442+
fake_hotkey_ss58 = "non_existent_hotkey"
1443+
fake_block_hash = "block_hash"
1444+
1445+
mocked_query = mocker.AsyncMock(return_value=[None])
1446+
subtensor.substrate.query = mocked_query
1447+
1448+
mocked_decode_account_id = mocker.Mock(return_value=None)
1449+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
1450+
1451+
# Call
1452+
result = await subtensor.get_hotkey_owner(
1453+
hotkey_ss58=fake_hotkey_ss58, block_hash=fake_block_hash
1454+
)
1455+
1456+
# Asserts
1457+
mocked_query.assert_called_once_with(
1458+
module="SubtensorModule",
1459+
storage_function="Owner",
1460+
params=[fake_hotkey_ss58],
1461+
block_hash=fake_block_hash,
1462+
)
1463+
mocked_decode_account_id.assert_called_once_with(None)
1464+
assert result is None
1465+
1466+
1467+
@pytest.mark.asyncio
1468+
async def test_get_hotkey_owner_exists_but_does_not_exist_flag_false(subtensor, mocker):
1469+
"""Tests get_hotkey_owner method when decode_account_id returns a value but does_hotkey_exist returns False."""
1470+
# Preps
1471+
fake_hotkey_ss58 = "valid_hotkey"
1472+
fake_block_hash = "block_hash"
1473+
fake_owner_account_id = "owner_account_id"
1474+
1475+
mocked_query = mocker.AsyncMock(return_value=[fake_owner_account_id])
1476+
subtensor.substrate.query = mocked_query
1477+
1478+
mocked_decode_account_id = mocker.Mock(return_value="decoded_owner_account_id")
1479+
mocker.patch.object(async_subtensor, "decode_account_id", mocked_decode_account_id)
1480+
1481+
mocked_does_hotkey_exist = mocker.AsyncMock(return_value=False)
1482+
subtensor.does_hotkey_exist = mocked_does_hotkey_exist
1483+
1484+
# Call
1485+
result = await subtensor.get_hotkey_owner(
1486+
hotkey_ss58=fake_hotkey_ss58, block_hash=fake_block_hash
1487+
)
1488+
1489+
# Asserts
1490+
mocked_query.assert_called_once_with(
1491+
module="SubtensorModule",
1492+
storage_function="Owner",
1493+
params=[fake_hotkey_ss58],
1494+
block_hash=fake_block_hash,
1495+
)
1496+
mocked_decode_account_id.assert_called_once_with(fake_owner_account_id)
1497+
mocked_does_hotkey_exist.assert_awaited_once_with(
1498+
fake_hotkey_ss58, block_hash=fake_block_hash
1499+
)
1500+
assert result is None

0 commit comments

Comments
 (0)