mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
feat: add config read-modify-write update and harden file watcher
Config.update_config() applies submitted options to the main configuration file via configparser read-modify-write: unknown options are preserved, null removes an option, the merged view of all files is validated as ServerConfig before anything is written (a bad file would kill the FileWatcher polling loop), and the write is atomic (.tmp + os.replace, mode 0600). Options whose effective value is owned by a later configuration file raise ConfigConflictError instead of writing a no-op. The reload logic is factored into reload_and_notify() and the file watcher callback is exception-guarded so polling never dies.
This commit is contained in:
5 files changed
+282
-7
No files matched your search
@@ -66,3 +66,20 @@ async def test_file_watcher_list(tmpdir, strategy):
|
||||
file2.write("b")
|
||||
await asyncio.sleep(0.5)
|
||||
callback.assert_called_with(str(file2))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_file_watcher_callback_exception_does_not_stop_polling(tmpdir):
|
||||
|
||||
file = tmpdir / "test"
|
||||
file.write("a")
|
||||
callback = MagicMock(side_effect=ValueError("callback error"))
|
||||
FileWatcher(file, callback, delay=0.1)
|
||||
await asyncio.sleep(0.5)
|
||||
assert callback.call_count == 0
|
||||
file.write("b")
|
||||
await asyncio.sleep(0.5)
|
||||
assert callback.call_count == 1 # raised, but must not kill the polling loop
|
||||
file.write("c")
|
||||
await asyncio.sleep(0.5)
|
||||
assert callback.call_count == 2 # polling survived the exception
|
||||
Reference in new issue
Block a user