51 lines
2.9 KiB
Python
51 lines
2.9 KiB
Python
import ast
|
|
import hashlib
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
from tempfile import TemporaryDirectory
|
|
from unittest.mock import patch
|
|
import unittest
|
|
|
|
ROOT=Path(__file__).resolve().parents[1]
|
|
spec=importlib.util.spec_from_file_location('release_preflight_test',ROOT/'release_preflight.py')
|
|
preflight=importlib.util.module_from_spec(spec);spec.loader.exec_module(preflight)
|
|
|
|
class ReleasePreflightTest(unittest.TestCase):
|
|
def test_preflight_never_restarts_existing_services(self):
|
|
for name,args,cwd,timeout in preflight.command_list('e3a08f9e-af12-4695-99bd-8b51c0520021'):
|
|
self.assertNotIn('up',args);self.assertNotIn('restart',args);self.assertNotIn('--with-bridges',args)
|
|
self.assertGreater(timeout,0)
|
|
first=preflight.command_list('e3a08f9e-af12-4695-99bd-8b51c0520021')[0][1]
|
|
self.assertIn('--test-only',first)
|
|
def test_php_runs_without_network_or_writeable_root(self):
|
|
args=next(args for name,args,cwd,timeout in preflight.command_list('p') if name=='php83_offline')
|
|
self.assertIn('--read-only',args);self.assertEqual(args[args.index('--network')+1],'none')
|
|
self.assertEqual(args[args.index('--user')+1],'1000:1000')
|
|
def test_native_bundle_requires_same_development_source(self):
|
|
with TemporaryDirectory() as d:
|
|
root=Path(d)/'root';repo=Path(d)/'repo';out=root/'acceptance/php-src'
|
|
out.mkdir(parents=True);repo.mkdir()
|
|
source=b'<?php // test';(out/'a.php').write_bytes(source);(repo/'a.php').write_bytes(source)
|
|
(out/'SOURCE_MANIFEST.json').write_text(json.dumps({'a.php':hashlib.sha256(source).hexdigest()}))
|
|
with patch.object(preflight,'ROOT',root),patch.object(preflight,'REPO',repo):
|
|
preflight.verify_native_bundle()
|
|
(repo/'a.php').write_text('<?php // changed')
|
|
with self.assertRaises(ValueError):preflight.verify_native_bundle()
|
|
def test_native_probe_has_no_training_or_publish_calls(self):
|
|
tree=ast.parse((ROOT/'acceptance/read_native_forecasts.py').read_text())
|
|
calls={n.func.attr for n in ast.walk(tree) if isinstance(n,ast.Call) and isinstance(n.func,ast.Attribute)}
|
|
self.assertFalse(calls & {'train','run_forecast','run_forecast_isolated','get_configs','publish_forecasts','write_api'})
|
|
text=(ROOT/'acceptance/read_native_forecasts.py').read_text()
|
|
self.assertIn('?mode=ro',text);self.assertNotIn('ALTER TABLE',text)
|
|
def test_gui_labels_estimates_and_incomplete_features(self):
|
|
text=(ROOT/'gui/netplan-v4.js').read_text()
|
|
self.assertIn('SCHATTENBETRIEB',text)
|
|
self.assertIn('measurementPolicy',text)
|
|
self.assertIn('wartet weiterhin auf vergleichbare Kosten-Replays',text)
|
|
self.assertIn('forecastSource',text)
|
|
self.assertIn('trainingCadence',text)
|
|
self.assertIn('Restmonatsbewertung ist keine bereits bezahlte Peakfreigabe',text)
|
|
|
|
if __name__=='__main__':unittest.main()
|