import importlib.util from pathlib import Path import sqlite3,tempfile,unittest ROOT=Path(__file__).resolve().parents[1] spec=importlib.util.spec_from_file_location('app_deploy',ROOT/'commissioning/deploy_application.py');d=importlib.util.module_from_spec(spec);spec.loader.exec_module(d) class ApplicationDeploymentTest(unittest.TestCase): def test_backup_consistent_and_original_not_changed(self): with tempfile.TemporaryDirectory() as tmp: src=Path(tmp)/'source.sqlite';out=Path(tmp)/'backup.sqlite' with sqlite3.connect(src) as c:c.execute('CREATE TABLE sample(value)');c.execute('INSERT INTO sample VALUES(3)') before=src.read_bytes();d.backup_database(src,out) with sqlite3.connect(out) as c:self.assertEqual(c.execute('SELECT value FROM sample').fetchone()[0],3) self.assertEqual(before,src.read_bytes()) def test_backup_cannot_invent_missing_database(self): with tempfile.TemporaryDirectory() as tmp: with self.assertRaises(ValueError):d.backup_database(Path(tmp)/'missing.sqlite',Path(tmp)/'new.sqlite') def test_atomic_refuses_symlink(self): with tempfile.TemporaryDirectory() as tmp: a=Path(tmp)/'a';b=Path(tmp)/'b';a.write_text('original');b.symlink_to(a) with self.assertRaises(ValueError):d.atomic(b,b'changed') self.assertEqual(a.read_text(),'original') def test_only_two_reviewed_portal_files(self): self.assertEqual(set(d.PORTAL_FILES.values()),{'netplan-v4-bridge.mjs','public/netplan-v4.js'}) def test_build_tests_backup_before_runtime_replacement(self): s=(ROOT/'commissioning/deploy_application.py').read_text() self.assertLess(s.index("'target_python_and_portal_tests_passed'"),s.index('v4_replaced=True')) self.assertLess(s.index("'consistent_database_backup'"),s.index('v4_replaced=True')) def test_does_not_change_optimizer_or_device_permissions(self): self.assertNotIn('/settings',d.BOOTSTRAP) self.assertNotIn('trial/arm',d.BOOTSTRAP) self.assertNotIn('IPS_',d.BOOTSTRAP) self.assertIn("state['liveEnabled'] is False",d.BOOTSTRAP) def test_image_contains_application_installer_imported_by_tests(self): self.assertIn('COPY commissioning/deploy_application.py ./commissioning/deploy_application.py',(ROOT/'Dockerfile').read_text()) def test_file_bind_mount_recreated_not_only_restarted(self): s=(ROOT/'commissioning/deploy_application.py').read_text() self.assertIn("'--force-recreate','--wait','license-portal'",s) self.assertIn('additive_data_retained',s) if __name__=='__main__':unittest.main()