Merge remote-tracking branch 'origin/develop' into HEAD

# Conflicts:
#	.github/workflows/test-oci-registries.yml
This commit is contained in:
MacRimi
2026-10-18 10:16:34 +02:00
76 changed files with 4239 additions and 376 deletions
@@ -38,6 +38,18 @@ DEFAULT_CONTEXT = "Context: Technical message for Proxmox and IT. Translate:"
# provider, then restore the exact source spelling afterwards. Keep longer
# terms first so ``gasket`` cannot consume part of ``gasket-dkms``.
PROTECTED_TECHNICAL_TERMS = (
# Product names, kept whole. Left to a translator, "Proxmox Backup Server"
# became "Proxmox Sicherungsserver" and "Serveur de sauvegarde Proxmox",
# and when a provider rightly handed it back unchanged the string was
# retried and then dropped as untranslated.
"Proxmox Backup Server",
"Proxmox Datacenter Manager",
"Proxmox Mail Gateway",
"Proxmox VE",
"ProxMenux Monitor",
"ProxMenux Optimizations",
"Secure Gateway",
"Tailscale",
"google/gasket-driver",
"feranick/gasket-driver",
"libedgetpu1-std",
@@ -5,6 +5,7 @@ import json
from pathlib import Path
import re
import runpy
import subprocess
import sys
import tempfile
from types import ModuleType, SimpleNamespace
@@ -52,7 +53,8 @@ class InventoryMessages(unittest.TestCase):
state = ModuleType('oci_installation_state')
state.parse_config = lambda raw: dict(line.split(': ', 1) for line in raw.decode().splitlines())
scope = {'sys': SimpleNamespace(path=[]), 'source_text': lambda text: text or '',
'translate': translate, 're': re}
'translate': translate, 're': re, 'subprocess': subprocess,
'_selected_configuration': remover.guest_config}
summary = extracted(MENU, '_removal_summary', scope)
with patch.dict(sys.modules, {'oci_instances': instances, 'oci_remove': remover,
'oci_installation_state': state}):
@@ -56,7 +56,8 @@ class RemovalWordings(unittest.TestCase):
state = ModuleType('oci_installation_state')
state.parse_config = lambda raw: {}
scope = {'sys': SimpleNamespace(path=[]), 'source_text': lambda value: value or '',
'translate': translated or (lambda value: value), 're': re}
'translate': translated or (lambda value: value), 're': re,
'_selected_configuration': remover.guest_config, 'subprocess': subprocess}
with patch.dict(sys.modules, {'oci_instances': instances, 'oci_remove': remover,
'oci_installation_state': state}):
return extract(MENU, '_removal_summary', scope)(Path('/inert'), 101)
@@ -87,7 +88,8 @@ class RemovalWordings(unittest.TestCase):
with patch.dict(sys.modules, {'oci_instances': instances, 'oci_remove': remover,
'oci_installation_state': state}):
scope = {'sys': SimpleNamespace(path=[]), 'source_text': lambda value: value or '',
'translate': lambda value: value, 're': re}
'translate': lambda value: value, 're': re,
'_selected_configuration': remover.guest_config, 'subprocess': subprocess}
preview = extract(MENU, '_removal_summary', scope)(Path('/inert'), 102)
self.assertIn(WHOLE, preview)
@@ -42,13 +42,13 @@ class SelectionSetupWording(TestCase):
shutil=SimpleNamespace(which=lambda _: '/fake/pct'), saved_inventory=lambda _: [],
_clean_orphans=lambda project: None,
recover_automatically=lambda project: None, offer_recovery=lambda project, ui: None,
carry_records=lambda project, **options: {},
carry_records=lambda project, **options: {}, _records_unread=lambda project: False,
translate=lambda s: s)
fn(Path('/fixture'), ui)
ui.message.assert_called_once_with(EMPTY, 'OCI management')
ui.choose.assert_not_called()
def _menu(self, inventories, selections):
def _menu(self, inventories, selections, unread=True):
rows = iter(inventories)
ui = SimpleNamespace(message=Mock(), choose=Mock(side_effect=selections))
refresh = Mock(return_value={})
@@ -57,7 +57,8 @@ class SelectionSetupWording(TestCase):
shutil=SimpleNamespace(which=lambda _: '/fake/pct'), saved_inventory=lambda _: next(rows),
_clean_orphans=lambda project: None,
recover_automatically=lambda project: None, offer_recovery=lambda project, ui: None,
carry_records=refresh, manage_instance=manage, menu_size=lambda: 10,
carry_records=refresh, _records_unread=lambda project: unread,
manage_instance=manage, menu_size=lambda: 10,
STATUS_LABELS={}, translate=lambda s: s)
fn(Path('/fixture'), ui)
return ui, refresh, manage
@@ -67,7 +68,14 @@ class SelectionSetupWording(TestCase):
ui, refresh, manage = self._menu([[row], [row]], ['101', None])
self.assertEqual(ui.choose.call_count, 2)
manage.assert_called_once()
refresh.assert_called_once_with(Path('/fixture'), mount_stopped=False, shown=True)
refresh.assert_called_once_with(Path('/fixture'), mount_stopped=False, shown=True,
heading='Manage installed OCI applications')
def test_the_list_opens_without_the_sync_notice_once_every_configuration_is_cached(self):
row = {'vmid': 101, 'title': 'Jellyfin', 'hostname': 'jellyfin', 'status': 'installed', 'image': 'jellyfin/jellyfin'}
_, refresh, _ = self._menu([[row]], [None], unread=False)
refresh.assert_called_once_with(Path('/fixture'), mount_stopped=False, shown=False,
heading='Manage installed OCI applications')
def test_removing_the_last_application_returns_without_a_message(self):
row = {'vmid': 101, 'title': 'Jellyfin', 'hostname': 'jellyfin', 'status': 'installed', 'image': 'jellyfin/jellyfin'}
@@ -130,6 +130,7 @@ class UpdateWording(unittest.TestCase):
reconcile.propose = lambda *args: None
scope = {'sys': SimpleNamespace(path=[], executable='python3'),
'translate': lambda text: text, 'check_selected': lambda project, row: row,
'_selected_configuration': lambda vmid: instances.command('pct', 'config', str(vmid)),
'images': SimpleNamespace(offer_removal=lambda *args: None),
'carry_records': lambda project, **options: {},
'_work_backup_ready': lambda project, ui, vmid: True,
+39
View File
@@ -37,7 +37,46 @@ jobs:
python3 -m unittest discover -s oci/tests -p test_modify_review.py -v
python3 -m unittest discover -s oci/tests -p test_modify_review_transaction.py -v
python3 -m unittest discover -s oci/tests -p test_stage_release.py -v
- name: Run carried record, recovery and configuration cache regressions
env:
PYTHONDONTWRITEBYTECODE: '1'
run: |
python3 -m unittest discover -s oci/tests -p 'test_carried*.py' -v
python3 -m unittest discover -s oci/tests -p test_restore_recovery.py -v
- name: Run read-only volume preparation regressions
env:
PYTHONDONTWRITEBYTECODE: '1'
run: |
test -x /bin/bash
test -x /usr/bin/jq
python3 -m unittest discover -s oci/tests -p test_readonly_volume_preparation.py -v
- name: Run offline registry account tests
env:
PYTHONDONTWRITEBYTECODE: '1'
run: python3 -m unittest discover -s oci/tests -p 'test_registry_*.py' -v
- name: Run OCI Modify latency regressions
env:
PYTHONDONTWRITEBYTECODE: '1'
run: |
python3 -m unittest discover -s oci/tests -p test_modify_latency.py -v
python3 -m unittest discover -s oci/tests -p test_menu_performance.py -v
python3 -m unittest discover -s oci/tests -p test_dialog_escape.py -v
python3 -m unittest discover -s oci/tests -p test_work_backup.py -v
python3 -m unittest discover -s oci/tests -p test_recreation.py -v
- name: Run OCI modification menu regressions
env:
PYTHONDONTWRITEBYTECODE: '1'
run: |
python3 -m unittest discover -s oci/tests -p test_modify_menu.py -v
python3 -m unittest discover -s oci/tests -p test_manage_sync_notice.py -v
python3 -m unittest discover -s oci/tests -p test_recreation.py -v
python3 -m unittest discover -s oci/tests -p test_shared_directories.py -v
python3 -m unittest discover -s oci/tests -p 'test_wizard*.py' -v
- name: Run external OCI settings regressions
env:
PYTHONDONTWRITEBYTECODE: '1'
run: |
python3 -m unittest discover -s oci/tests -p 'test_external_tags.py' -v
python3 -m unittest discover -s oci/tests -p 'test_instance_reconcile.py' -v
python3 -m unittest discover -s oci/tests -p 'test_guessed_endpoint_healthcheck.py' -v
python3 -m unittest discover -s oci/tests -p 'test_runtime_home_*.py' -v
+4 -1
View File
@@ -17,6 +17,9 @@ on:
- 'scripts/global/repository-functions.sh'
- 'scripts/menus/pbs_menu.sh'
- 'scripts/utilities/pbs_update.sh'
- 'scripts/global/update-pbs.sh'
- 'scripts/menus/menu_post_install.sh'
- 'scripts/post_install/*.sh'
push:
branches: [main, develop]
paths:
@@ -49,7 +52,7 @@ jobs:
run: |
python -B -m unittest discover -s AppImage/scripts/tests -p test_pbs.py -v
python -B -m unittest discover -s AppImage/scripts/tests -p test_auth_manager_ssl_reload.py -v
for script in scripts/global/platform-functions.sh scripts/global/repository-functions.sh scripts/menus/pbs_menu.sh scripts/utilities/pbs_update.sh scripts/menus/main_menu.sh scripts/post_install/auto_post_install.sh scripts/post_install/customizable_post_install.sh; do
for script in scripts/global/platform-functions.sh scripts/global/repository-functions.sh scripts/menus/pbs_menu.sh scripts/utilities/pbs_update.sh scripts/menus/main_menu.sh scripts/post_install/auto_post_install.sh scripts/post_install/customizable_post_install.sh scripts/post_install/uninstall-tools.sh scripts/global/update-pbs.sh scripts/menus/menu_post_install.sh; do
bash -n "$script"
done
- uses: actions/setup-node@v6