Esempio n. 1
0
 def test_load_empty_file_results_in_empty_config(self):
     config_file = os.path.join(self.make_dir(), "config")
     with open(config_file, "w"):
         pass  # Write nothing to the file.
     config = ConfigurationFile(config_file)
     config.load()
     self.assertItemsEqual(set(config), set())
Esempio n. 2
0
 def test_opened_configuration_file_saves_on_exit(self):
     # ConfigurationFile.open() returns a context manager that will save an
     # updated configuration on a clean exit.
     config_file = os.path.join(self.make_dir(), "config")
     config_key = factory.make_name("key")
     config_value = factory.make_name("value")
     with ConfigurationFile.open_for_update(config_file) as config:
         config[config_key] = config_value
         self.assertEqual({config_key: config_value}, config.config)
         self.assertTrue(config.dirty)
     with ConfigurationFile.open(config_file) as config:
         self.assertEqual(config_value, config[config_key])
Esempio n. 3
0
 def test_opened_configuration_file_does_not_save_on_unclean_exit(self):
     config_file = os.path.join(self.make_dir(), "config")
     config_key = factory.make_name("key")
     config_value = factory.make_name("value")
     exception_type = factory.make_exception_type()
     # Set a configuration option, then crash.
     with ExpectedException(exception_type):
         with ConfigurationFile.open_for_update(config_file) as config:
             config[config_key] = config_value
             raise exception_type()
     # No value has been saved for `config_key`.
     with ConfigurationFile.open(config_file) as config:
         self.assertRaises(KeyError, lambda: config[config_key])
Esempio n. 4
0
 def test_open_takes_exclusive_lock(self):
     config_file = os.path.join(self.make_dir(), "config")
     config_lock = RunLock(config_file)
     self.assertFalse(config_lock.is_locked())
     with ConfigurationFile.open_for_update(config_file):
         self.assertTrue(config_lock.is_locked())
     self.assertFalse(config_lock.is_locked())
Esempio n. 5
0
 def test_replacing_configuration_option(self):
     config = ConfigurationFile(sentinel.filename, mutable=True)
     config["alice"] = {"abc": 123}
     config["alice"] = {"def": 456}
     self.assertEqual({"alice"}, set(config))
     self.assertEqual({"def": 456}, config["alice"])
     self.assertTrue(config.dirty)
Esempio n. 6
0
 def test_open_permissions_new_database(self):
     # ConfigurationFile.open() applies restrictive file permissions to
     # newly created configuration databases.
     config_file = os.path.join(self.make_dir(), "config")
     with ConfigurationFile.open(config_file):
         perms = FilePath(config_file).getPermissions()
         self.assertEqual("rw-r-----", perms.shorthand())
Esempio n. 7
0
 def test_configuration_pristine(self):
     # A pristine configuration has no entries.
     config = ConfigurationFile(sentinel.filename)
     self.assertThat(
         config,
         MatchesStructure.byEquality(config={},
                                     dirty=False,
                                     path=sentinel.filename))
Esempio n. 8
0
 def test_open_yields_immutable_backend(self):
     config_file = os.path.join(self.make_dir(), "config")
     config_key = factory.make_name("key")
     with ConfigurationFile.open(config_file) as config:
         with ExpectedException(ConfigurationImmutable):
             config[config_key] = factory.make_name("value")
         with ExpectedException(ConfigurationImmutable):
             del config[config_key]
Esempio n. 9
0
 def test_load_file_with_non_mapping_crashes(self):
     config_file = os.path.join(self.make_dir(), "config")
     with open(config_file, "w") as fd:
         yaml.safe_dump([1, 2, 3], stream=fd)
     config = ConfigurationFile(config_file)
     error = self.assertRaises(ValueError, config.load)
     self.assertDocTestMatches(
         "Configuration in /.../config is not a mapping: [1, 2, 3]",
         str(error))
Esempio n. 10
0
 def test_open_and_close(self):
     # ConfigurationFile.open() returns a context manager.
     config_file = os.path.join(self.make_dir(), "config")
     config_ctx = ConfigurationFile.open(config_file)
     self.assertIsInstance(config_ctx, contextlib._GeneratorContextManager)
     with config_ctx as config:
         self.assertIsInstance(config, ConfigurationFile)
         self.assertThat(config_file, FileExists())
         self.assertEqual({}, config.config)
         self.assertFalse(config.dirty)
     self.assertThat(config_file, FileContains(""))
Esempio n. 11
0
 def test_unmodified_database_retains_permissions(self):
     # ConfigurationFile.open() leaves the file permissions of existing
     # configuration databases if they're not modified.
     config_file = os.path.join(self.make_dir(), "config")
     open(config_file, "wb").close()  # touch.
     os.chmod(config_file, 0o644)  # u=rw,go=r
     with ConfigurationFile.open_for_update(config_file):
         perms = FilePath(config_file).getPermissions()
         self.assertEqual("rw-r--r--", perms.shorthand())
     perms = FilePath(config_file).getPermissions()
     self.assertEqual("rw-r--r--", perms.shorthand())
Esempio n. 12
0
 def test_modified_database_uses_safe_permissions_if_file_missing(self):
     # ConfigurationFile.open() uses a sensible u=rw,g=r file mode when
     # saving if the database file has been inexplicably removed. This is
     # the same mode as used when opening a new database.
     config_file = os.path.join(self.make_dir(), "config")
     open(config_file, "wb").close()  # touch.
     os.chmod(config_file, 0o644)  # u=rw,go=r
     with ConfigurationFile.open_for_update(config_file) as config:
         config["foobar"] = "I am a modification"
         os.unlink(config_file)
     perms = FilePath(config_file).getPermissions()
     self.assertEqual("rw-r-----", perms.shorthand())
Esempio n. 13
0
 def test_mutable(self):
     config_file = os.path.join(self.make_dir(), "config")
     config = ConfigurationFile(config_file, mutable=True)
     config["alice"] = 1234
     del config["alice"]
Esempio n. 14
0
 def test_immutable(self):
     config_file = os.path.join(self.make_dir(), "config")
     config = ConfigurationFile(config_file, mutable=False)
     self.assertRaises(ConfigurationImmutable, setitem, config, "alice", 1)
     self.assertRaises(ConfigurationImmutable, delitem, config, "alice")
Esempio n. 15
0
 def test_as_string(self):
     config_file = os.path.join(self.make_dir(), "config")
     config = ConfigurationFile(config_file)
     self.assertThat(str(config),
                     Equals("ConfigurationFile(%r)" % config_file))
Esempio n. 16
0
 def test_getting_configuration_option(self):
     config = ConfigurationFile(sentinel.filename, mutable=True)
     config["alice"] = {"abc": 123}
     self.assertEqual({"abc": 123}, config["alice"])
Esempio n. 17
0
 def test_getting_non_existent_configuration_option(self):
     config = ConfigurationFile(sentinel.filename)
     self.assertRaises(KeyError, lambda: config["alice"])
Esempio n. 18
0
 def test_removing_configuration_option(self):
     config = ConfigurationFile(sentinel.filename, mutable=True)
     config["alice"] = {"abc": 123}
     del config["alice"]
     self.assertEqual(set(), set(config))
     self.assertTrue(config.dirty)
Esempio n. 19
0
 def test_load_non_existent_file_crashes(self):
     config_file = os.path.join(self.make_dir(), "config")
     config = ConfigurationFile(config_file)
     self.assertRaises(IOError, config.load)
Esempio n. 20
0
 def test_open_for_update_yields_mutable_backend(self):
     config_file = os.path.join(self.make_dir(), "config")
     config_key = factory.make_name("key")
     with ConfigurationFile.open_for_update(config_file) as config:
         config[config_key] = factory.make_name("value")
         del config[config_key]
Esempio n. 21
0
 def make_file_store(self):
     return ConfigurationFile(self.make_file(), mutable=True)