Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions mytonctrl/mytonctrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def inject_globals(func):

# Create user console
console.name = "MyTonCtrl"
console.startFunction = inject_globals(PreUp)
console.startFunction = inject_globals(pre_up)
console.debug = ton.GetSettings("debug")
console.local = local

Expand Down Expand Up @@ -212,13 +212,14 @@ def check_installer_user(local):
#end define


def PreUp(local: MyPyClass, ton: MyTonCore):
CheckMytonctrlUpdate(local)
check_installer_user(local)
check_vport(local, ton)
warnings(local, ton)
# CheckTonUpdate()
#end define
def pre_up(local: MyPyClass, ton: MyTonCore):
try:
check_mytonctrl_update(local)
check_installer_user(local)
check_vport(local, ton)
warnings(local, ton)
except Exception as e:
local.add_log(f'PreUp error: {e}', 'error')


Comment on lines 223 to 224
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comment marker at the end of the function. The function pre_up should end with '#end define' comment for consistency with the codebase style, as seen in other functions like check_installer_user on line 212.

Suggested change
#end define

Copilot uses AI. Check for mistakes.
def Installer(args):
Expand Down Expand Up @@ -445,12 +446,11 @@ def run_benchmark(ton, args):
print_table(table)
#end define

def CheckMytonctrlUpdate(local):
def check_mytonctrl_update(local):
git_path = local.buffer.my_dir
result = check_git_update(git_path)
if result is True:
color_print(local.translate("mytonctrl_update_available"))
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comment marker at the end of the function. The function check_mytonctrl_update should end with '#end define' comment for consistency with the codebase style, as seen on line 214 where it was removed.

Suggested change
color_print(local.translate("mytonctrl_update_available"))
color_print(local.translate("mytonctrl_update_available"))
#end define

Copilot uses AI. Check for mistakes.
#end define

def print_warning(local, warning_name: str):
color_print("============================================================================================")
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,5 @@ def cli(local, ton) -> TestMyPyConsole:
mp.setattr(MyTonCore, "using_single_nominator", lambda self: True)
Init(local, ton, console, argv=[])
mp.undo()
console.debug = True
# console.debug = True
return console
Empty file.
76 changes: 76 additions & 0 deletions tests/integration/preup/test_preup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import socket
import subprocess

from mytoncore import MyTonCore
from mytonctrl import mytonctrl
from pytest_mock import MockerFixture


def test_check_mytonctrl_update(cli, monkeypatch):
monkeypatch.setattr(mytonctrl, 'warnings', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_installer_user', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_vport', lambda *_: None)

monkeypatch.setattr(mytonctrl, 'check_git_update', lambda *_: True)
output = cli.run_pre_up()
assert 'MyTonCtrl update available' in output

monkeypatch.setattr(mytonctrl, 'check_git_update', lambda *_: False)
output = cli.run_pre_up()
assert 'MyTonCtrl update available' not in output


def test_check_installer_user(cli, monkeypatch, mocker: MockerFixture):
monkeypatch.setattr(mytonctrl, 'check_mytonctrl_update', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'warnings', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_vport', lambda *_: None)

whoami_result = mocker.Mock()
whoami_result.stdout = b'testuser\n'
ls_result = mocker.Mock()
ls_result.stdout = b'total 0\n-rw-r--r-- 1 testuser testuser 0 Jan 1 00:00 file\n'

run_mock = mocker.Mock(side_effect=[whoami_result, ls_result])
monkeypatch.setattr(subprocess, 'run', run_mock)
output = cli.run_pre_up()
assert 'mytonctrl was installed by another user' not in output

whoami_result.stdout = b'currentuser\n'
ls_result.stdout = b'total 0\n-rw-r--r-- 1 installeruser testuser 0 Jan 1 00:00 file\n'

run_mock = mocker.Mock(side_effect=[whoami_result, ls_result])
monkeypatch.setattr(subprocess, 'run', run_mock)
output = cli.run_pre_up()
assert 'mytonctrl was installed by another user' in output
assert f'launch mtc with `installeruser` user' in output


def test_check_vport(cli, monkeypatch, mocker: MockerFixture):
monkeypatch.setattr(mytonctrl, 'check_mytonctrl_update', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'warnings', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_installer_user', lambda *_: None)

monkeypatch.setattr(MyTonCore, 'GetValidatorConfig', mocker.Mock(side_effect=Exception('test error')))
output = cli.run_pre_up()
assert 'GetValidatorConfig error' in output

vconfig_mock = mocker.Mock()
addr_mock = mocker.Mock()
addr_mock.ip = 16777343 # 127.0.0.1
addr_mock.port = 8080
vconfig_mock.addrs = [addr_mock]
monkeypatch.setattr(MyTonCore, 'GetValidatorConfig', lambda *_: vconfig_mock)

socket_mock = mocker.Mock()
socket_mock.connect_ex.return_value = 0
socket_mock.__enter__ = mocker.Mock(return_value=socket_mock)
socket_mock.__exit__ = mocker.Mock()
monkeypatch.setattr(socket, 'socket', mocker.Mock(return_value=socket_mock))

output = cli.run_pre_up()
assert 'UDP port of the validator is not accessible' not in output

vconfig_mock.addrs = [addr_mock]
socket_mock.connect_ex.return_value = 1
output = cli.run_pre_up()
assert 'UDP port of the validator is not accessible' in output
198 changes: 198 additions & 0 deletions tests/integration/preup/test_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import pytest
from pytest_mock import MockerFixture

import modules
from mytoncore import MyTonCore
from mytonctrl import mytonctrl


@pytest.fixture(autouse=True)
def before_test(monkeypatch):
monkeypatch.setattr(mytonctrl, 'check_mytonctrl_update', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_installer_user', lambda *_: None)
monkeypatch.setattr(mytonctrl, 'check_vport', lambda *_: None)

def test_check_disk_usage(cli, monkeypatch):
monkeypatch.setattr(MyTonCore, 'GetDbUsage', lambda *_: 95)
output = cli.run_pre_up()
assert 'Disk is almost full, clean the TON database immediately' in output

monkeypatch.setattr(MyTonCore, 'GetDbUsage', lambda *_: 70)
output = cli.run_pre_up()
assert 'Disk is almost full' not in output


def test_check_sync(cli, monkeypatch, ton, mocker: MockerFixture):
mock = mocker.Mock()
monkeypatch.setattr(MyTonCore, 'GetValidatorStatus', mock)
output = cli.run_pre_up()
assert 'Node sync is not completed' in output

mock.return_value.initial_sync = None
mock.return_value.is_working = False
output = cli.run_pre_up()
assert 'Node is out of sync' in output

mock.return_value.is_working = True
output = cli.run_pre_up()
assert 'Node is out of sync' not in output
assert 'Node sync is not completed' not in output


def test_check_adnl(cli, monkeypatch, mocker: MockerFixture):
config_mock = mocker.Mock()

config_mock.fullnodeslaves = None
from modules.utilities import UtilitiesModule
monkeypatch.setattr(UtilitiesModule, 'check_adnl_connection', lambda *_: (False, 'ADNL connection failed'))
output = cli.run_pre_up()
assert 'ADNL connection failed' in output

config_mock.fullnodeslaves = True
monkeypatch.setattr(MyTonCore, 'GetValidatorConfig', lambda *_: config_mock)
output = cli.run_pre_up()
assert 'ADNL' not in output

config_mock.fullnodeslaves = None
monkeypatch.setattr(UtilitiesModule, 'check_adnl_connection', lambda *_: (True, None))
output = cli.run_pre_up()
assert 'ADNL connection failed' not in output


def test_check_validator_balance(cli, monkeypatch, mocker: MockerFixture):
validator_status_mock = mocker.Mock()
monkeypatch.setattr(MyTonCore, 'GetValidatorStatus', lambda *_: validator_status_mock)

account_mock = mocker.Mock()
monkeypatch.setattr(MyTonCore, 'GetAccount', lambda *_: account_mock)

validator_wallet_mock = mocker.Mock()
validator_wallet_mock.addrB64 = 'test_address'
monkeypatch.setattr(MyTonCore, 'GetValidatorWallet', lambda *_: validator_wallet_mock)

validator_status_mock.is_working = False
validator_status_mock.out_of_sync = 0
output = cli.run_pre_up()
assert 'balance' not in output

validator_status_mock.is_working = True
monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: False)
output = cli.run_pre_up()
assert 'balance' not in output

monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: True)
monkeypatch.setattr(MyTonCore, 'GetAccount', lambda *_: None)
output = cli.run_pre_up()
assert 'Failed to check validator wallet balance' in output

monkeypatch.setattr(MyTonCore, 'GetAccount', lambda *_: account_mock)
account_mock.balance = 50
output = cli.run_pre_up()
assert 'Validator wallet balance is low' in output

account_mock.balance = 150
output = cli.run_pre_up()
assert 'Validator wallet balance is low' not in output


def test_check_vps(cli, monkeypatch):
monkeypatch.setattr('mytonctrl.mytonctrl.is_host_virtual', lambda : {'virtual': True, 'product_name': 'VirtualBox'})
output = cli.run_pre_up()
assert 'Virtualization detected' in output

monkeypatch.setattr('mytonctrl.mytonctrl.is_host_virtual', lambda : {'virtual': False})
output = cli.run_pre_up()
assert 'Virtualization detected' not in output


def test_check_tg_channel(cli, monkeypatch, ton):
monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: True)
output = cli.run_pre_up()
assert 'Make sure you are subscribed to the TON validators channel' in output

ton.local.db['subscribe_tg_channel'] = True
monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: True)
output = cli.run_pre_up()
assert 'Make sure you are subscribed to the TON validators channel' not in output

monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: False)
output = cli.run_pre_up()
assert 'Make sure you are subscribed to the TON validators channel' not in output


def test_check_slashed(cli, monkeypatch, mocker: MockerFixture):
validator_status_mock = mocker.Mock()
monkeypatch.setattr(MyTonCore, 'GetValidatorStatus', lambda *_: validator_status_mock)

monkeypatch.setattr(MyTonCore, 'using_validator', lambda *_: True)
validator_status_mock.out_of_sync = 10

monkeypatch.setattr(modules.ValidatorModule, 'get_my_complaint', lambda *_: {'suggestedFine': 99})
validator_status_mock.is_working = True
output = cli.run_pre_up()
assert 'You were fined by 99 TON' in output

monkeypatch.setattr(modules.ValidatorModule, 'get_my_complaint', lambda *_: None)
validator_status_mock.is_working = True
output = cli.run_pre_up()
assert 'You were fined' not in output

validator_status_mock.is_working = False
output = cli.run_pre_up()
assert 'You were fined' not in output


def test_check_ubuntu_version(cli, monkeypatch, mocker: MockerFixture):
monkeypatch.setattr(mytonctrl.os.path, 'exists', lambda _: True)
res = '''
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
'''
mock = mocker.mock_open(read_data=res)
monkeypatch.setattr('builtins.open', mock)
output = cli.run_pre_up()
assert 'Ubuntu' not in output

monkeypatch.setattr(mytonctrl.os.path, 'exists', lambda _: True)
res = '''
PRETTY_NAME="Ubuntu 24.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.3 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
'''
mock = mocker.mock_open(read_data=res)
monkeypatch.setattr('builtins.open', mock)
output = cli.run_pre_up()
assert 'Ubuntu' not in output

res = '''
PRETTY_NAME="Ubuntu 20.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="20.04"
VERSION="20.04.4 LTS (Focal Fossa)"
VERSION_CODENAME=focal
ID=ubuntu
'''
mock = mocker.mock_open(read_data=res)
monkeypatch.setattr('builtins.open', mock)
output = cli.run_pre_up()
assert 'Ubuntu version must be 22.04 or 24.04. Found 20.04.' in output

res = '''
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
'''
mock = mocker.mock_open(read_data=res)
monkeypatch.setattr('builtins.open', mock)
output = cli.run_pre_up()
assert 'Ubuntu' not in output
10 changes: 4 additions & 6 deletions tests/integration/test_nominator_pool_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,9 @@ def fake_fift_run(args: list):
output = cli.execute(f"new_pool {pool_name} 5.5 10 10000 1000", no_color=True)
assert 'CreatePool warning: Pool already exists' in output

with pytest.raises(Exception) as e:
cli.execute(f"new_pool pool2 5.5 10 10000 1000")
output = cli.execute(f"new_pool pool2 5.5 10 10000 1000", no_color=True)
assert os.path.isfile(addr_file)
assert 'Pool with the same parameters already exists' in str(e)
assert 'Pool with the same parameters already exists' in output


def test_activate_pool(cli, ton, monkeypatch, mocker: MockerFixture):
Expand Down Expand Up @@ -90,9 +89,8 @@ def test_activate_pool(cli, ton, monkeypatch, mocker: MockerFixture):

# empty account
account.status = "empty"
with pytest.raises(Exception) as e:
cli.execute(f"activate_pool {pool_name}")
assert "account status is empty" in str(e)
output = cli.execute(f"activate_pool {pool_name}")
assert "account status is empty" in output

# already active account
account.status = "active"
Expand Down
Loading