From d167d4be9127ec218e15f37505fe1e47c4c98d08 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Tue, 9 Sep 2025 21:06:31 +0200 Subject: [PATCH 1/3] Better type annotations --- tests/e2e_tests/conftest.py | 25 ++++++++++++++++++++----- tests/e2e_tests/utils.py | 19 ++++++++++++++++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/tests/e2e_tests/conftest.py b/tests/e2e_tests/conftest.py index 1b93ac0ae..0e1b13cc6 100644 --- a/tests/e2e_tests/conftest.py +++ b/tests/e2e_tests/conftest.py @@ -1,4 +1,5 @@ import asyncio +from collections.abc import Iterator, Callable import logging import os import re @@ -8,11 +9,13 @@ import subprocess import sys import time +from typing import Generator +import bittensor_wallet.keypair import pytest from async_substrate_interface.async_substrate import AsyncSubstrateInterface -from .utils import setup_wallet +from .utils import setup_wallet, ExecCommand LOCALNET_IMAGE_NAME = "ghcr.io/opentensor/subtensor-localnet:devnet-ready" @@ -31,7 +34,7 @@ def wait_for_node_start(process, pattern, timestamp: int = None): # Fixture for setting up and tearing down a localnet.sh chain between tests @pytest.fixture(scope="function") -def local_chain(request): +def local_chain(request) -> Iterator[AsyncSubstrateInterface]: """Determines whether to run the localnet.sh script in a subprocess or a Docker container.""" args = request.param if hasattr(request, "param") else None params = "" if args is None else f"{args}" @@ -58,7 +61,7 @@ def local_chain(request): yield from legacy_runner(request) -def legacy_runner(request): +def legacy_runner(request) -> Iterator[AsyncSubstrateInterface]: param = request.param if hasattr(request, "param") else None # Get the environment variable for the script path script_path = os.getenv("LOCALNET_SH_PATH") @@ -103,7 +106,7 @@ def legacy_runner(request): process.wait() -def docker_runner(params): +def docker_runner(params) -> Iterator[AsyncSubstrateInterface]: """Starts a Docker container before tests and gracefully terminates it after.""" def is_docker_running(): @@ -211,7 +214,19 @@ def try_start_docker(): @pytest.fixture(scope="function") -def wallet_setup(): +def wallet_setup() -> Generator[ + Callable[ + [str], + tuple[ + bittensor_wallet.Keypair, + bittensor_wallet.Wallet, + str, + ExecCommand, + ], + ], + None, + None, +]: wallet_paths = [] def _setup_wallet(uri: str): diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py index b8b729b3e..c2f80f3e1 100644 --- a/tests/e2e_tests/utils.py +++ b/tests/e2e_tests/utils.py @@ -5,9 +5,10 @@ import shutil import subprocess import sys -from typing import TYPE_CHECKING, Optional +from typing import TYPE_CHECKING, Optional, Protocol from bittensor_wallet import Keypair, Wallet +from click.testing import Result from packaging.version import parse as parse_version, Version from typer.testing import CliRunner @@ -20,7 +21,19 @@ templates_repo = "templates repository" -def setup_wallet(uri: str): +class ExecCommand(Protocol): + """Type Protocol for setup_wallet's exec_command fn""" + + def __call__( + self, + command: str, + sub_command: str, + extra_args: Optional[list[str]], + inputs: Optional[list[str]], + ) -> Result: ... + + +def setup_wallet(uri: str) -> tuple[Keypair, Wallet, str, ExecCommand]: keypair = Keypair.create_from_uri(uri) wallet_path = f"/tmp/btcli-e2e-wallet-{uri.strip('/')}" wallet = Wallet(path=wallet_path) @@ -32,7 +45,7 @@ def exec_command( command: str, sub_command: str, extra_args: Optional[list[str]] = None, - inputs: list[str] = None, + inputs: Optional[list[str]] = None, ): extra_args = extra_args or [] cli_manager = CLIManager() From b4045fd2474e2fd20ddfe2ffad45593da88650be Mon Sep 17 00:00:00 2001 From: bdhimes Date: Tue, 9 Sep 2025 21:06:51 +0200 Subject: [PATCH 2/3] Adds command to turn off hyperparams freeze window, applies it as necessary --- tests/e2e_tests/test_hyperparams_setting.py | 9 ++++++- tests/e2e_tests/test_liquidity.py | 8 +++++++ tests/e2e_tests/test_staking_sudo.py | 8 +++++++ tests/e2e_tests/utils.py | 26 +++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/e2e_tests/test_hyperparams_setting.py b/tests/e2e_tests/test_hyperparams_setting.py index 03d8616c3..ba50b09ad 100644 --- a/tests/e2e_tests/test_hyperparams_setting.py +++ b/tests/e2e_tests/test_hyperparams_setting.py @@ -1,6 +1,8 @@ +import asyncio import json from bittensor_cli.src import HYPERPARAMS +from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window """ Verify commands: @@ -18,7 +20,12 @@ def test_hyperparams_setting(local_chain, wallet_setup): keypair_alice, wallet_alice, wallet_path_alice, exec_command_alice = wallet_setup( wallet_path_alice ) - + try: + asyncio.run(turn_off_hyperparam_freeze_window(local_chain, wallet_alice)) + except ValueError: + print( + "Skipping turning off hyperparams freeze window. This indicates the call does not exist on the chain you are testing." + ) # Register a subnet with sudo as Alice result = exec_command_alice( command="subnets", diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index c8a7b7d4c..8414b5f29 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -1,7 +1,9 @@ +import asyncio import json import re from bittensor_cli.src.bittensor.balances import Balance +from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window """ Verify commands: @@ -40,6 +42,12 @@ def liquidity_list(): keypair_alice, wallet_alice, wallet_path_alice, exec_command_alice = wallet_setup( wallet_path_alice ) + try: + asyncio.run(turn_off_hyperparam_freeze_window(local_chain, wallet_alice)) + except ValueError: + print( + "Skipping turning off hyperparams freeze window. This indicates the call does not exist on the chain you are testing." + ) # Register a subnet with sudo as Alice result = exec_command_alice( diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 359fbb508..0f3d6f8d9 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -1,7 +1,9 @@ +import asyncio import json import re from bittensor_cli.src.bittensor.balances import Balance +from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window """ Verify commands: @@ -45,6 +47,12 @@ def test_staking(local_chain, wallet_setup): keypair_alice, wallet_alice, wallet_path_alice, exec_command_alice = wallet_setup( wallet_path_alice ) + try: + asyncio.run(turn_off_hyperparam_freeze_window(local_chain, wallet_alice)) + except ValueError: + print( + "Skipping turning off hyperparams freeze window. This indicates the call does not exist on the chain you are testing." + ) burn_cost = exec_command_alice( "subnets", diff --git a/tests/e2e_tests/utils.py b/tests/e2e_tests/utils.py index c2f80f3e1..9917c2c10 100644 --- a/tests/e2e_tests/utils.py +++ b/tests/e2e_tests/utils.py @@ -383,3 +383,29 @@ async def set_storage_extrinsic( print(":white_heavy_check_mark: [dark_sea_green_3]Success[/dark_sea_green_3]") return response + + +async def turn_off_hyperparam_freeze_window( + substrate: "AsyncSubstrateInterface", wallet: Wallet +): + call = await substrate.compose_call( + call_module="Sudo", + call_function="sudo", + call_params={ + "call": await substrate.compose_call( + call_module="AdminUtils", + call_function="sudo_set_admin_freeze_window", + call_params={"window": 0}, + ) + }, + ) + extrinsic = await substrate.create_signed_extrinsic( + call=call, keypair=wallet.coldkey + ) + response = await substrate.submit_extrinsic( + extrinsic, + wait_for_inclusion=True, + wait_for_finalization=True, + ) + + return await response.is_success, await response.error_message From 81401f4b334a7e69c7a6cf9681c973a4d337b4f5 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Tue, 9 Sep 2025 21:28:28 +0200 Subject: [PATCH 3/3] CI's PYTHON_PATH not set correctly. This is a bandage. --- tests/e2e_tests/test_hyperparams_setting.py | 2 +- tests/e2e_tests/test_liquidity.py | 2 +- tests/e2e_tests/test_staking_sudo.py | 2 +- tests/e2e_tests/test_unstaking.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e_tests/test_hyperparams_setting.py b/tests/e2e_tests/test_hyperparams_setting.py index ba50b09ad..3af86c140 100644 --- a/tests/e2e_tests/test_hyperparams_setting.py +++ b/tests/e2e_tests/test_hyperparams_setting.py @@ -2,7 +2,7 @@ import json from bittensor_cli.src import HYPERPARAMS -from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window +from .utils import turn_off_hyperparam_freeze_window """ Verify commands: diff --git a/tests/e2e_tests/test_liquidity.py b/tests/e2e_tests/test_liquidity.py index 8414b5f29..218ef91f0 100644 --- a/tests/e2e_tests/test_liquidity.py +++ b/tests/e2e_tests/test_liquidity.py @@ -3,7 +3,7 @@ import re from bittensor_cli.src.bittensor.balances import Balance -from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window +from .utils import turn_off_hyperparam_freeze_window """ Verify commands: diff --git a/tests/e2e_tests/test_staking_sudo.py b/tests/e2e_tests/test_staking_sudo.py index 0f3d6f8d9..9034c51da 100644 --- a/tests/e2e_tests/test_staking_sudo.py +++ b/tests/e2e_tests/test_staking_sudo.py @@ -3,7 +3,7 @@ import re from bittensor_cli.src.bittensor.balances import Balance -from tests.e2e_tests.utils import turn_off_hyperparam_freeze_window +from .utils import turn_off_hyperparam_freeze_window """ Verify commands: diff --git a/tests/e2e_tests/test_unstaking.py b/tests/e2e_tests/test_unstaking.py index 68af71087..4b7ca0765 100644 --- a/tests/e2e_tests/test_unstaking.py +++ b/tests/e2e_tests/test_unstaking.py @@ -4,7 +4,7 @@ from bittensor_cli.src.bittensor.balances import Balance -from btcli.tests.e2e_tests.utils import set_storage_extrinsic +from .utils import set_storage_extrinsic def test_unstaking(local_chain, wallet_setup):