|
| 1 | +import time |
| 2 | +from unittest.mock import MagicMock, patch |
| 3 | +import importlib |
| 4 | +import pytest |
| 5 | +from substrateinterface.base import ( |
| 6 | + SubstrateInterface, |
| 7 | + GenericExtrinsic, |
| 8 | + SubstrateRequestException, |
| 9 | +) |
| 10 | + |
| 11 | +from bittensor.core.extrinsics import utils |
| 12 | + |
| 13 | + |
| 14 | +@pytest.fixture |
| 15 | +def set_extrinsics_timeout_env(monkeypatch): |
| 16 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1") |
| 17 | + |
| 18 | + |
| 19 | +def test_submit_extrinsic_timeout(): |
| 20 | + timeout = 1 |
| 21 | + |
| 22 | + def wait(extrinsic, wait_for_inclusion, wait_for_finalization): |
| 23 | + time.sleep(timeout + 0.01) |
| 24 | + return True |
| 25 | + |
| 26 | + mock_substrate = MagicMock(autospec=SubstrateInterface) |
| 27 | + mock_substrate.submit_extrinsic = wait |
| 28 | + mock_extrinsic = MagicMock(autospec=GenericExtrinsic) |
| 29 | + with patch.object(utils, "EXTRINSIC_SUBMISSION_TIMEOUT", timeout): |
| 30 | + with pytest.raises(SubstrateRequestException): |
| 31 | + utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True) |
| 32 | + |
| 33 | + |
| 34 | +def test_submit_extrinsic_success(): |
| 35 | + mock_substrate = MagicMock(autospec=SubstrateInterface) |
| 36 | + mock_substrate.submit_extrinsic.return_value = True |
| 37 | + mock_extrinsic = MagicMock(autospec=GenericExtrinsic) |
| 38 | + result = utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True) |
| 39 | + assert result is True |
| 40 | + |
| 41 | + |
| 42 | +def test_submit_extrinsic_timeout_env(set_extrinsics_timeout_env): |
| 43 | + importlib.reload(utils) |
| 44 | + timeout = utils.EXTRINSIC_SUBMISSION_TIMEOUT |
| 45 | + assert timeout < 5 # should be less than 5 seconds as taken from test env var |
| 46 | + |
| 47 | + def wait(extrinsic, wait_for_inclusion, wait_for_finalization): |
| 48 | + time.sleep(timeout + 1) |
| 49 | + return True |
| 50 | + |
| 51 | + mock_substrate = MagicMock(autospec=SubstrateInterface) |
| 52 | + mock_substrate.submit_extrinsic = wait |
| 53 | + mock_extrinsic = MagicMock(autospec=GenericExtrinsic) |
| 54 | + with pytest.raises(SubstrateRequestException): |
| 55 | + utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True) |
| 56 | + |
| 57 | + |
| 58 | +def test_submit_extrinsic_success_env(set_extrinsics_timeout_env): |
| 59 | + importlib.reload(utils) |
| 60 | + mock_substrate = MagicMock(autospec=SubstrateInterface) |
| 61 | + mock_substrate.submit_extrinsic.return_value = True |
| 62 | + mock_extrinsic = MagicMock(autospec=GenericExtrinsic) |
| 63 | + result = utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True) |
| 64 | + assert result is True |
| 65 | + |
| 66 | + |
| 67 | +def test_submit_extrinsic_timeout_env_float(monkeypatch): |
| 68 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1.45") # use float |
| 69 | + |
| 70 | + importlib.reload(utils) |
| 71 | + timeout = utils.EXTRINSIC_SUBMISSION_TIMEOUT |
| 72 | + |
| 73 | + assert timeout == 1.45 # parsed correctly |
| 74 | + |
| 75 | + def wait(extrinsic, wait_for_inclusion, wait_for_finalization): |
| 76 | + time.sleep(timeout + 0.3) # sleep longer by float |
| 77 | + return True |
| 78 | + |
| 79 | + mock_substrate = MagicMock(autospec=SubstrateInterface) |
| 80 | + mock_substrate.submit_extrinsic = wait |
| 81 | + mock_extrinsic = MagicMock(autospec=GenericExtrinsic) |
| 82 | + with pytest.raises(SubstrateRequestException): |
| 83 | + utils.submit_extrinsic(mock_substrate, mock_extrinsic, True, True) |
| 84 | + |
| 85 | + |
| 86 | +def test_import_timeout_env_parse(monkeypatch): |
| 87 | + # int |
| 88 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1") |
| 89 | + importlib.reload(utils) |
| 90 | + assert utils.EXTRINSIC_SUBMISSION_TIMEOUT == 1 # parsed correctly |
| 91 | + |
| 92 | + # float |
| 93 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "1.45") # use float |
| 94 | + importlib.reload(utils) |
| 95 | + assert utils.EXTRINSIC_SUBMISSION_TIMEOUT == 1.45 # parsed correctly |
| 96 | + |
| 97 | + # invalid |
| 98 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "not_an_int") |
| 99 | + with pytest.raises(ValueError) as e: |
| 100 | + importlib.reload(utils) |
| 101 | + assert "must be a float" in str(e.value) |
| 102 | + |
| 103 | + # negative |
| 104 | + monkeypatch.setenv("EXTRINSIC_SUBMISSION_TIMEOUT", "-1") |
| 105 | + with pytest.raises(ValueError) as e: |
| 106 | + importlib.reload(utils) |
| 107 | + assert "cannot be negative" in str(e.value) |
| 108 | + |
| 109 | + # default (not checking exact value, just that it's a value) |
| 110 | + monkeypatch.delenv("EXTRINSIC_SUBMISSION_TIMEOUT") |
| 111 | + importlib.reload(utils) |
| 112 | + assert isinstance(utils.EXTRINSIC_SUBMISSION_TIMEOUT, float) # has a default value |
| 113 | + assert utils.EXTRINSIC_SUBMISSION_TIMEOUT > 0 # is positive |
0 commit comments