94 lines
4.2 KiB
Python
94 lines
4.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Presentation checks runnable without a Proxmox host."""
|
|
import contextlib
|
|
import importlib.util
|
|
import io
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import unittest
|
|
from unittest.mock import patch
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
spec = importlib.util.spec_from_file_location('disks', ROOT / 'inc/orphan-disks.py')
|
|
disks = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(disks)
|
|
|
|
|
|
class UITests(unittest.TestCase):
|
|
def shell(self, script, width=80):
|
|
result = subprocess.run(['bash', '-c', 'source "$UI_FILE"\nTAPM_UI_INIT\n' + script],
|
|
capture_output=True, text=True,
|
|
env=dict(os.environ, UI_FILE=str(ROOT / 'inc/ui.inc'),
|
|
COLUMNS=str(width), TERM='xterm', NO_COLOR='1'))
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
self.assertEqual(result.stderr, '')
|
|
self.assertNotIn('\x1b', result.stdout)
|
|
return result.stdout
|
|
|
|
def test_plain_wrapped_menu_and_task(self):
|
|
output = self.shell('''
|
|
TAPM_UI_RULE
|
|
TAPM_UI_MENU_META 'Cluster & Maintenance' orphan_disks
|
|
TAPM_UI_MENU_ROW 5 $'Find \\e[36morphaned\\e[39m and unused disks [Read-only]' 1
|
|
TAPM_UI_TASK 'Find orphaned and unused disks'
|
|
''', width=40)
|
|
self.assertIn('> 5', output)
|
|
self.assertIn('Starting:', output)
|
|
self.assertTrue(all(len(line) <= 40 for line in output.splitlines()))
|
|
|
|
def test_submenus_and_choices_do_not_start_tasks(self):
|
|
cases = [('Main Menu', 'cluster', 'submenu'),
|
|
('Cluster & Maintenance', 'services', 'submenu'),
|
|
('Select ISO Storage', 'local', 'choice'),
|
|
('Customize TAPM Host Profile', 'utilities', 'choice'),
|
|
('Customize TAPM Host Profile', 'apply', 'task'),
|
|
('Cluster & Maintenance', 'orphan_disks', 'task'),
|
|
('Cluster & Maintenance', 'back', 'navigation')]
|
|
for title, value, expected in cases:
|
|
with self.subTest(title=title, value=value):
|
|
output = self.shell(f"TAPM_UI_MENU_META '{title}' '{value}'\nprintf '%s' \"$TAPM_UI_KIND\"")
|
|
self.assertEqual(output, expected)
|
|
|
|
def test_header_widths(self):
|
|
source = (ROOT / 'proxmenu-scripts.sh').read_text()
|
|
header = 'MENU_HEADER() {' + source.split('MENU_HEADER() {', 1)[1].split('\nSELECT_MENU()', 1)[0]
|
|
for width in (40, 80, 120):
|
|
with self.subTest(width=width):
|
|
output = self.shell('''
|
|
TAPM_LOAD_HEADER_INFO() { TAPM_HEADER_PVE_VERSION=9.2.20; TAPM_HEADER_CLUSTER=Home-Cluster; }
|
|
LOAD_UPDATE_STATUS() { :; }
|
|
hostname() { printf ids-vms2; }
|
|
UPDATE_STATUS=current VERS=2026.9.22-15 RNIP=10.10.2.12
|
|
''' + header + '\nMENU_HEADER', width=width)
|
|
self.assertIn('TA-ProxMenu', output)
|
|
self.assertIn('Home-Cluster', output)
|
|
self.assertIn('Up to date', output)
|
|
self.assertTrue(all(len(line) <= min(width, 75) for line in output.splitlines()))
|
|
|
|
def test_report_is_plain_when_redirected(self):
|
|
rows = [dict(node='shared (via ids-vms1)', storage='iSCSI-Datastore2',
|
|
volume='iSCSI-Datastore2:vm-139-disk-0.qcow2',
|
|
size_bytes=25 * 1024 ** 3, size_is_approximate=True,
|
|
status='Unused disk', detail='Webserver-Node1 (VM 139)')]
|
|
output = io.StringIO()
|
|
with patch.dict(os.environ, {'COLUMNS': '52'}), contextlib.redirect_stdout(output):
|
|
disks.render(rows, ['ids-vms3: offline; storage not scanned'], ['one store'])
|
|
text = output.getvalue()
|
|
self.assertNotIn('\x1b', text)
|
|
self.assertIn('Scan finished — incomplete coverage', text)
|
|
self.assertIn('Webserver-Node1 (VM 139)', text)
|
|
self.assertIn('~25.00 GiB', text)
|
|
self.assertTrue(all(len(line) <= 52 for line in text.splitlines()))
|
|
|
|
def test_no_color_on_terminal_when_requested(self):
|
|
output = io.StringIO()
|
|
output.isatty = lambda: True
|
|
with patch.dict(os.environ, {'TERM': 'xterm', 'NO_COLOR': '1'}):
|
|
disks.ReportDisplay(output).line('Results', 'bold')
|
|
self.assertNotIn('\x1b', output.getvalue())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|