|
8 | 8 | from bittensor import u64_normalized_float
|
9 | 9 | from bittensor.core import async_subtensor
|
10 | 10 | 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 | +) |
15 | 18 | from bittensor.utils import U64_MAX
|
16 | 19 | from bittensor.utils.balance import Balance
|
17 | 20 | from tests.helpers.helpers import assert_submit_signed_extrinsic
|
@@ -3059,3 +3062,103 @@ async def test_start_call(subtensor, mocker):
|
3059 | 3062 | wait_for_finalization=False,
|
3060 | 3063 | )
|
3061 | 3064 | 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