Skip to content

Commit 2a1a9d2

Browse files
author
Roman
committed
add async unit tests
1 parent de3dc0c commit 2a1a9d2

File tree

1 file changed

+107
-4
lines changed

1 file changed

+107
-4
lines changed

tests/unit_tests/test_async_subtensor.py

Lines changed: 107 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
from bittensor import u64_normalized_float
99
from bittensor.core import async_subtensor
1010
from bittensor.core.async_subtensor import AsyncSubtensor
11-
from bittensor.core.chain_data.chain_identity import ChainIdentity
12-
from bittensor.core.chain_data.neuron_info import NeuronInfo
13-
from bittensor.core.chain_data.stake_info import StakeInfo
14-
from bittensor.core.chain_data import proposal_vote_data
11+
from bittensor.core.chain_data import (
12+
proposal_vote_data,
13+
ChainIdentity,
14+
NeuronInfo,
15+
StakeInfo,
16+
SelectiveMetagraphIndex,
17+
)
1518
from bittensor.utils import U64_MAX
1619
from bittensor.utils.balance import Balance
1720
from tests.helpers.helpers import assert_submit_signed_extrinsic
@@ -3059,3 +3062,103 @@ async def test_start_call(subtensor, mocker):
30593062
wait_for_finalization=False,
30603063
)
30613064
assert result == mocked_extrinsic.return_value
3065+
3066+
3067+
@pytest.mark.asyncio
3068+
async def test_get_metagraph_info_all_fields(subtensor, mocker):
3069+
"""Test get_metagraph_info with all fields (default behavior)."""
3070+
# Preps
3071+
netuid = 1
3072+
mock_value = {"mock": "data"}
3073+
3074+
mock_runtime_call = mocker.patch.object(
3075+
subtensor.substrate,
3076+
"runtime_call",
3077+
return_value=mocker.AsyncMock(value=mock_value),
3078+
)
3079+
mock_from_dict = mocker.patch.object(
3080+
async_subtensor.MetagraphInfo, "from_dict", return_value="parsed_metagraph"
3081+
)
3082+
3083+
# Call
3084+
result = await subtensor.get_metagraph_info(netuid=netuid)
3085+
3086+
# Asserts
3087+
assert result == "parsed_metagraph"
3088+
mock_runtime_call.assert_awaited_once_with(
3089+
"SubnetInfoRuntimeApi",
3090+
"get_selective_metagraph",
3091+
params=[netuid, SelectiveMetagraphIndex.all_indices()],
3092+
block_hash=await subtensor.determine_block_hash(None),
3093+
)
3094+
mock_from_dict.assert_called_once_with(mock_value)
3095+
3096+
3097+
@pytest.mark.asyncio
3098+
async def test_get_metagraph_info_specific_fields(subtensor, mocker):
3099+
"""Test get_metagraph_info with specific fields."""
3100+
# Preps
3101+
netuid = 1
3102+
mock_value = {"mock": "data"}
3103+
fields = [SelectiveMetagraphIndex.Name, SelectiveMetagraphIndex.OwnerHotkey]
3104+
3105+
mock_runtime_call = mocker.patch.object(
3106+
subtensor.substrate,
3107+
"runtime_call",
3108+
return_value=mocker.AsyncMock(value=mock_value),
3109+
)
3110+
mock_from_dict = mocker.patch.object(
3111+
async_subtensor.MetagraphInfo, "from_dict", return_value="parsed_metagraph"
3112+
)
3113+
3114+
# Call
3115+
result = await subtensor.get_metagraph_info(netuid=netuid, field_indices=fields)
3116+
3117+
# Asserts
3118+
assert result == "parsed_metagraph"
3119+
mock_runtime_call.assert_awaited_once_with(
3120+
"SubnetInfoRuntimeApi",
3121+
"get_selective_metagraph",
3122+
params=[netuid, [f.value for f in fields]],
3123+
block_hash=await subtensor.determine_block_hash(None),
3124+
)
3125+
mock_from_dict.assert_called_once_with(mock_value)
3126+
3127+
3128+
@pytest.mark.parametrize(
3129+
"wrong_fields",
3130+
[
3131+
[
3132+
"invalid",
3133+
],
3134+
[SelectiveMetagraphIndex.Active, 1],
3135+
[1, 2, 3],
3136+
],
3137+
)
3138+
@pytest.mark.asyncio
3139+
async def test_get_metagraph_info_invalid_field_indices(subtensor, wrong_fields):
3140+
"""Test get_metagraph_info raises ValueError on invalid field_indices."""
3141+
with pytest.raises(
3142+
ValueError,
3143+
match="`field_indices` must be a list of SelectiveMetagraphIndex items.",
3144+
):
3145+
await subtensor.get_metagraph_info(netuid=1, field_indices=wrong_fields)
3146+
3147+
3148+
@pytest.mark.asyncio
3149+
async def test_get_metagraph_info_subnet_not_exist(subtensor, mocker):
3150+
"""Test get_metagraph_info returns None when subnet doesn't exist."""
3151+
netuid = 1
3152+
mocker.patch.object(
3153+
subtensor.substrate,
3154+
"runtime_call",
3155+
return_value=mocker.AsyncMock(value=None),
3156+
)
3157+
3158+
mocked_logger = mocker.Mock()
3159+
mocker.patch("bittensor.core.subtensor.logging.error", new=mocked_logger)
3160+
3161+
result = await subtensor.get_metagraph_info(netuid=netuid)
3162+
3163+
assert result is None
3164+
mocked_logger.assert_called_once_with(f"Subnet {netuid} does not exist.")

0 commit comments

Comments
 (0)