From 0c4b024ca989a7c051988013d1ba30f9d78a9968 Mon Sep 17 00:00:00 2001 From: Kevin Bates Date: Thu, 2 May 2019 13:50:39 -0700 Subject: [PATCH] Add test for dynamic updates, keep timestamps as floats --- traitlets/config/application.py | 4 +- traitlets/config/tests/test_application.py | 48 +++++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/traitlets/config/application.py b/traitlets/config/application.py index 3f920263..eadaaab5 100644 --- a/traitlets/config/application.py +++ b/traitlets/config/application.py @@ -316,7 +316,7 @@ def __init__(self, **kwargs): else: self.classes.insert(0, self.__class__) - self.last_config_update = int(time.time()) + self.last_config_update = time.time() self.dynamic_configurables = {} @observe('config') @@ -832,7 +832,7 @@ def _config_files_updated(self): """ updated = False for file in self._loaded_config_files: - mod_time = int(os.path.getmtime(file)) + mod_time = os.path.getmtime(file) if mod_time > self.last_config_update: self.log.debug("Config file was updated: {}!".format(file)) self.last_config_update = mod_time diff --git a/traitlets/config/tests/test_application.py b/traitlets/config/tests/test_application.py index bf66eb71..ae847ba1 100644 --- a/traitlets/config/tests/test_application.py +++ b/traitlets/config/tests/test_application.py @@ -12,6 +12,7 @@ import logging import os import sys +import time from io import StringIO from unittest import TestCase, skip @@ -358,7 +359,6 @@ def test_warn_autocorrect(self): self.assertIn("warn_typo", stream.getvalue()) self.assertIn("warn_tpyo", stream.getvalue()) - def test_flatten_flags(self): cfg = Config() cfg.MyApp.log_level = logging.WARN @@ -547,6 +547,52 @@ def test_subcommands_instanciation(self): self.assertIs(app.subapp.parent, app) self.assertIs(app.subapp.subapp.parent, app.subapp) # Set by factory. + def test_dynamic_updates(self): + app = MyApp() + s1 = time.time() + app.log = logging.getLogger() + name = 'config.py' + with TemporaryDirectory('_1') as td1: + with open(pjoin(td1, name), 'w') as f: + f.writelines([ + "c.MyApp.running = True\n", + "c.MyApp.Bar.b = 1\n" + ]) + + app.load_config_file(name, path=[td1]) + app.init_bar() + app.add_dynamic_configurable("MyApp", app) + app.add_dynamic_configurable("Bar", app.bar) + with self.assertRaises(RuntimeError): + app.add_dynamic_configurable("Bogus", app.log) + + app.start() + self.assertEqual(app.running, True) + self.assertEqual(app.bar.b, 1) + + # Ensure file update doesn't happen during same second as initial value. + # This is necessary on test systems that don't have finer-grained + # timestamps (of less than a second). + s2 = time.time() + if s2 - s1 < 1.0: + time.sleep(1.0 - (s2-s1)) + # update config file + with open(pjoin(td1, name), 'w') as f: + f.writelines([ + "c.MyApp.running = False\n", + "c.MyApp.Bar.b = 2\n" + ]) + + # trigger reload and verify updates + app.update_dynamic_configurables() + self.assertEqual(app.running, False) + self.assertEqual(app.bar.b, 2) + + # repeat to ensure no unexpected changes occurred + app.update_dynamic_configurables() + self.assertEqual(app.running, False) + self.assertEqual(app.bar.b, 2) + class Root(Application): subcommands = {