def test_strict_list(self): """ Tests the case that we want to strictly merge 2 lists. """ given = ["hello", "world", 5, {"hello": "world"}, [1, 2, 3]] to_merge = ["hello", "world", 5, {"world": "hello"}, [4, 5]] expected = [ "hello", "world", 5, { "hello": "world", "world": "hello" }, [4, 5] ] actual = Merge(to_merge).into(given, strict=True) self.assertEqual(expected, actual) to_merge = ["hello", "world", 5, {"hello": "you!"}, [1, 2, 4, 5]] expected = ["hello", "world", 5, {"hello": "you!"}, [1, 2, 4, 5]] actual = Merge(to_merge).into(given, strict=True) self.assertEqual(expected, actual) to_merge = ["hello", "world", 5, {"hello": "you!"}, [1, 2, 4, 5]] expected = ["hello", "world", 5, {"hello": "you!"}, [1, 2, 4, 5]] actual = Merge(to_merge).into(given, strict=True) self.assertEqual(expected, actual)
def start(self) -> "PyFuncebleConfigUpdater": with importlib.resources.path( "PyFunceble.data.infrastructure", ".PyFunceble_production.yaml") as file_path: local_version = DictHelper(DictHelper().from_yaml_file( str(file_path))).flatten() local_version = Merge( dead_hosts.launcher.defaults.pyfunceble.CONFIGURATION).into( local_version, strict=True) if self.info_manager.custom_pyfunceble_config and isinstance( self.info_manager.custom_pyfunceble_config, dict): logging.info("Custom PyFunceble configuration given, " "appending them to the local configuration file.") local_version = Merge( self.info_manager.custom_pyfunceble_config).into(local_version, strict=True) if self.info_manager.ping: logging.info( "Ping names given, appending them to the commit message.") local_version[ "cli_testing.ci.end_commit_message"] = self.get_commit_message( local_version["cli_testing.ci.end_commit_message"], ping=self.info_manager.get_ping_for_commit(), ) local_version = Merge( dead_hosts.launcher.defaults.pyfunceble.PERSISTENT_CONFIG).into( local_version, strict=True) if FileHelper( os.path.join( self.info_manager.WORKSPACE_DIR, dead_hosts.launcher.defaults.paths.EXAMPLE_INFO_FILENAME, )).exists(): local_version["cli_testing.ci.active"] = False # Default behavior of PyFunceble since 4.0.0b12. local_version["cli_testing.autocontinue"] = False local_version = DictHelper(local_version).unflatten() DictHelper(local_version).to_yaml_file( self.pyfunceble_config_file_instance.path) logging.debug("Configuration:\n%s", self.pyfunceble_config_file_instance.read()) return self
def test_strict_simple_dict(self): """ Tests the case that we want to strictly merge 2 simple dict. """ given = { "world": "Fun Ilrys", "hello_world": { "author": "funilrys", "name": "Fun" }, "hello": ["This is PyFunceble!", "Uhh!"], } to_merge = { "hello_world": { "author": "nobody", "surname": "body" }, "hello": ["hello", "Uhh"], } expected = { "hello_world": { "author": "nobody", "name": "Fun", "surname": "body" }, "world": "Fun Ilrys", "hello": ["hello", "Uhh"], } actual = Merge(to_merge).into(given, strict=True) self.assertEqual(expected, actual)
def start(self) -> "ConfigLoader": """ Starts the loading processIs. """ config = self.get_config_file_content() if self.custom_config: config = Merge(self.custom_config).into(config) config = self.conditional_switch(config) PyFunceble.storage.CONFIGURATION = Box( config, ) PyFunceble.storage.FLATTEN_CONFIGURATION = DictHelper( PyFunceble.storage.CONFIGURATION ).flatten() PyFunceble.storage.HTTP_CODES = Box( config["http_codes"], ) if "collection" in config: PyFunceble.storage.COLLECTION = Box(config["collection"]) PyFunceble.storage.LINKS = Box(config["links"]) return self
def test_float(self): """ Tests the case that we want to merge 2 floats. """ expected = 2.1 actual = Merge(2.1).into(3.1) self.assertEqual(expected, actual)
def test_int(self): """ Tests the case that we want to merge 2 ints. """ expected = 2 actual = Merge(2).into(1) self.assertEqual(expected, actual)
def test_str(self): """ Tests the case that we want to merge 2 strs. """ expected = "Hello" actual = Merge("Hello").into("World") self.assertEqual(expected, actual)
def test_mixed_int_float(self): """ Tests the case that we want to merge an int into a float. """ expected = 1 actual = Merge(1).into(2.1) self.assertEqual(expected, actual)
def test_mixed_str_int(self): """ Tests the case that we want to merge a str into an int. """ expected = "Hello" actual = Merge("Hello").into(1) self.assertEqual(expected, actual)
def test_not_strict_simple_list(self): """ Tests the case that we want to merge 2 simple lists. """ given = [1, 2, 3, 4] to_merge = [2, 4, 5, 6, 7] expected = [1, 2, 3, 4, 5, 6, 7] actual = Merge(to_merge).into(given, strict=False) self.assertEqual(actual, expected)
def get_config_file_content(self) -> dict: """ Provides the content of the configuration file or the one already loaded. """ def is_3_x_version(config: dict) -> bool: """ Checks if the given configuration is an old one. :param config: The config to work with. """ return config and "days_between_inactive_db_clean" in config if not self.is_already_loaded(): self.install_missing_infrastructure_files() self.download_dynamic_infrastructure_files() try: config = self.dict_helper.from_yaml_file(self.path_to_config) except ConstructorError: self.file_helper.set_path(self.path_to_default_config).copy( self.path_to_config ) config = self.dict_helper.from_yaml_file(self.path_to_config) if ( not config or self.merge_upstream or is_3_x_version(config) ): # pragma: no cover ## Testing the underlying comparison method is sufficent config = ConfigComparison( local_config=config, upstream_config=self.dict_helper.from_yaml_file( self.path_to_default_config ), ).get_merged() self.dict_helper.set_subject(config).to_yaml_file(self.path_to_config) if self.file_helper.set_path(self.path_to_overwrite_config).exists(): overwrite_data = self.dict_helper.from_yaml_file( self.path_to_overwrite_config ) if overwrite_data: config = Merge( self.dict_helper.from_yaml_file(self.path_to_overwrite_config) ).into(config) else: # pragma: no cover ## Just make it visible to end-user. self.file_helper.write("") return config
"filenames": { "auto_continue": "continue.json", "execution_time": "execution_time.json", "percentage": "percentage.txt", "whois": "whois.json", "date_format": "date_format.json", "no_referrer": "no_referrer.json", "inactive_not_retested": "inactive_not_retested", }, }, "parent_directory": "output", "merged_directory": "merged_results", "splitted": { "directory": "splitted" }, } OUTPUTS: Optional[Box] = Box( Merge(UNIX_OUTPUTS).into(UNIVERSAL_OUTPUTS) if PlatformUtility.is_unix() else Merge(WIN_OUTPUTS).into(UNIVERSAL_OUTPUTS), frozen_box=True, ) OUTPUT_DIRECTORY: str = os.path.join( PyFunceble.cli.storage_facility.get_output_directory(), OUTPUTS.parent_directory, ) # This one will store some extra messages to print to the user. EXTRA_MESSAGES: Optional[List[str]] = []
def get_merged(self) -> dict: """ Provides the merged configuration. """ # pylint: disable=too-many-branches if self.is_local_identical(): return self.local_config if not self.local_config: return self.upstream_config original_local = copy.deepcopy(self.local_config) original_upstream = copy.deepcopy(self.upstream_config) flatten_original = self.dict_helper.set_subject( original_local).flatten() flatten_upstream = self.dict_helper.set_subject( original_upstream).flatten() for key, value in self.OLD_TO_NEW.items(): if key not in flatten_original: continue if value not in flatten_upstream: # pragma: no cover ## Safety. raise RuntimeError(f"<value> ({value!r}) not found.") flatten_original[value] = original_local[key] del flatten_original[key] for key, value in self.OLD_TO_NEW_NEGATE.items(): if key not in flatten_original: continue if value not in flatten_upstream: # pragma: no cover ## Safety.0 raise RuntimeError(f"<value> ({value!r}) not found.") flatten_original[value] = not original_local[key] del flatten_original[key] original_local = self.dict_helper.set_subject( flatten_original).unflatten() del flatten_original merged = Merge(original_local).into(original_upstream) if "dns_lookup_over_tcp" in merged and merged["dns_lookup_over_tcp"]: merged["dns"]["protocol"] = "TCP" for index in self.DELETED_CORE: if index in merged: del merged[index] for index in self.DELETED_LINKS: if index in merged["links"]: del merged["links"][index] if not bool(merged["http_codes"]["self_managed"]): for index, values in PyFunceble.storage.STD_HTTP_CODES.list.items( ): merged["http_codes"]["list"][index] = list(values) if merged["cli_testing"]["db_type"] == "json": merged["cli_testing"]["db_type"] = "csv" if merged["cli_testing"]["cooldown_time"] is None: merged["cli_testing"]["cooldown_time"] = self.upstream_config[ "cli_testing"]["cooldown_time"] if "user_agent" not in self.local_config or not isinstance( self.local_config["user_agent"], dict): merged["user_agent"] = self.upstream_config["user_agent"] if "active" in merged["http_codes"]: del merged["http_codes"]["active"] if "not_found_default" in merged["http_codes"]: del merged["http_codes"]["not_found_default"] return merged
if file_helper.set_path( os.path.join( pyfunceble_webworker.storage.CONFIG_DIRECTORY, assets_defaults.OVERWRITE_CONFIG_FILE, )).exists(): local = DictHelper().from_yaml_file(file_helper.path) if local: pyfunceble_config_loader.custom_config = local else: pyfunceble_config_loader.custom_config = dict() else: file_helper.write("") pyfunceble_config_loader.custom_config = Merge( pyfunceble_defaults.PERSISTENT_CONFIG).into( pyfunceble_config_loader.custom_config) pyfunceble_config_loader.start() app = FastAPI( title=assets_defaults.PROJECT_NAME, description=assets_defaults.PROJECT_DESCRIPTION, version=__version__, docs_url=None, redoc_url=None, ) with importlib.resources.path("pyfunceble_webworker.data", "logger.yaml") as logger_config_path: logger_data = DictHelper.from_yaml_file(str(logger_config_path))