feat(hub): add auto-update switches for on/off & acquisition modes and remove manual download buttons from webui
CI Test Suite / Run Component Tests & Pipeline Verification (push) Successful in 2m21s

This commit is contained in:
2026-10-04 01:15:20 +02:00
parent 8f8a605c98
commit f0f6eba53b
5 changed files with 319 additions and 45 deletions
+49 -18
View File
@@ -32,7 +32,10 @@ class TestUpdateSystem(unittest.TestCase):
Server.init_db(self.test_db)
self.update_mgr = ServerUpdateManager(update_dir=self.test_updates_dir, check_enabled=False)
Server.SERVER_STATE["update_manager"] = self.update_mgr
Server.SERVER_STATE["config"] = {"db_path": self.test_db}
Server.SERVER_STATE["config"] = {
"db_path": self.test_db,
"config_file_path": os.path.join(self.test_dir, "test_server_config.json")
}
def tearDown(self):
import shutil
@@ -194,27 +197,55 @@ class TestUpdateSystem(unittest.TestCase):
self.assertIn("tabPane-updates", html)
self.assertIn("Client Package Distribution Repository", html)
def test_update_memoization_and_cache_invalidation(self):
"""Tests that package info is served from memory cache and invalidates on update."""
dummy_pkg = os.path.join(self.test_dir, "LOGAR_Client_Linux")
def test_auto_update_switches_and_modes(self):
"""Tests On/Off toggle, Auto vs Manual modes, and config API endpoint."""
import sqlite3
conn = sqlite3.connect(self.test_db)
conn.execute("UPDATE license_config SET license_status = 'active', features = '[\"auto_update\"]' WHERE id = 1")
conn.commit()
conn.close()
dummy_pkg = os.path.join(self.test_dir, "LOGAR_Client_Setup.exe")
with open(dummy_pkg, "wb") as f:
f.write(b"LINUX_CLIENT_PAYLOAD_V1")
f.write(b"WIN_CLIENT_V0360")
self.update_mgr.register_client_package("windows", dummy_pkg, version="0.3.6.0")
self.update_mgr.register_client_package("linux", dummy_pkg, version="0.3.6.0")
pkgs_1 = self.update_mgr.get_hosted_packages()
sha1 = pkgs_1["linux"]["sha256"]
# 1. Active & auto mode -> update offered
chk1 = Server.check_client_update(client_id="win-node", os="windows", current_version="0.3.5.2")
self.assertTrue(chk1["update_available"])
# Repeated call should hit memory cache with identical hash
pkgs_2 = self.update_mgr.get_hosted_packages()
self.assertEqual(pkgs_2["linux"]["sha256"], sha1)
# 2. Toggle Auto-Update OFF via API
from server_models import ServerUpdateConfigRequest
cfg_req = ServerUpdateConfigRequest(auto_update_enabled=False, update_mode="manual")
res = Server.update_server_update_config(req=cfg_req, auth_user="admin")
self.assertEqual(res["status"], "success")
self.assertFalse(self.update_mgr.auto_update_enabled)
self.assertEqual(self.update_mgr.update_mode, "manual")
# Invalidate cache on new registration
with open(dummy_pkg, "wb") as f:
f.write(b"LINUX_CLIENT_PAYLOAD_V2_UPDATED")
self.update_mgr.register_client_package("linux", dummy_pkg, version="0.3.7.0")
pkgs_3 = self.update_mgr.get_hosted_packages()
self.assertEqual(pkgs_3["linux"]["version"], "0.3.7.0")
self.assertNotEqual(pkgs_3["linux"]["sha256"], sha1)
# Client update check while OFF -> blocked
chk2 = Server.check_client_update(client_id="win-node", os="windows", current_version="0.3.5.2")
self.assertFalse(chk2["update_available"])
self.assertIn("disabled", chk2.get("reason", ""))
# 3. Toggle back ON with 'auto' mode
cfg_req2 = ServerUpdateConfigRequest(auto_update_enabled=True, update_mode="auto")
res2 = Server.update_server_update_config(req=cfg_req2, auth_user="admin")
self.assertEqual(res2["status"], "success")
self.assertTrue(self.update_mgr.auto_update_enabled)
self.assertEqual(self.update_mgr.update_mode, "auto")
# 4. Verify WebUI renders without download buttons in packages table
html = Server.WebUIRenderer.render_dashboard_html(
server_state=Server.SERVER_STATE,
ingest_queue=Server.INGEST_QUEUE
)
self.assertNotIn("/api/client/update/download?os=windows", html)
self.assertNotIn("/api/client/update/download?os=linux", html)
self.assertIn("Fleet Auto-Update Service", html)
self.assertIn("Image Acquisition & Hosting Mode", html)
self.assertIn("autoUpdateEnabledRadio", html)
self.assertIn("updateModeRadio", html)
self.assertIn("✅ Hosted & Ready for Fleet", html)
if __name__ == "__main__":