Skip to content

Commit ac24c8a

Browse files
authored
Merge pull request #135 from CCPBioSim/124-remove-config-yaml
Remove static `config.yaml` and implement dynamic config loading
2 parents 7434628 + f4f5e32 commit ac24c8a

File tree

4 files changed

+58
-45
lines changed

4 files changed

+58
-45
lines changed

CodeEntropy/config/arg_config_manager.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import argparse
2+
import glob
23
import logging
34
import os
45

@@ -77,16 +78,26 @@ def __init__(self):
7778
self.arg_map = arg_map
7879

7980
def load_config(self, file_path):
80-
"""Load YAML configuration file."""
81-
if not os.path.exists(file_path):
82-
raise FileNotFoundError(f"Configuration file '{file_path}' not found.")
81+
"""Load YAML configuration file from the given directory."""
82+
yaml_files = glob.glob(os.path.join(file_path, "*.yaml"))
8383

84-
with open(file_path, "r") as file:
85-
config = yaml.safe_load(file)
86-
87-
# If YAML content is empty, return an empty dictionary
88-
if config is None:
89-
config = {}
84+
if not yaml_files:
85+
logger.warning(
86+
f"No YAML configuration files found in directory: {file_path}. "
87+
"Expected a file with extension '.yaml'. "
88+
"Proceeding with default configuration: {'run1': {}}."
89+
)
90+
return {"run1": {}}
91+
92+
try:
93+
with open(yaml_files[0], "r") as file:
94+
config = yaml.safe_load(file)
95+
logger.info(f"Loaded configuration from: {yaml_files[0]}")
96+
if config is None:
97+
config = {"run1": {}}
98+
except Exception as e:
99+
logger.error(f"Failed to load config file: {e}")
100+
config = {"run1": {}}
90101

91102
return config
92103

CodeEntropy/run.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,9 @@ def run_entropy_workflow(self):
9595
try:
9696
logger = self._logging_config.setup_logging()
9797

98-
config = self._config_manager.load_config("config.yaml")
99-
if config is None:
100-
raise ValueError(
101-
"No configuration file found, and no CLI arguments were provided."
102-
)
98+
current_directory = os.getcwd()
10399

100+
config = self._config_manager.load_config(current_directory)
104101
parser = self._config_manager.setup_argparse()
105102
args, _ = parser.parse_known_args()
106103
args.output_file = os.path.join(self.folder, args.output_file)

config.yaml

Lines changed: 0 additions & 15 deletions
This file was deleted.

tests/test_CodeEntropy/test_arg_config_manager.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,50 @@ def setup_file(self, mock_file):
6868
"water_entropy: False"
6969
).return_value
7070

71-
@patch("builtins.open", new_callable=mock_open)
72-
@patch("os.path.exists", return_value=True)
73-
def test_load_config(self, mock_exists, mock_file):
71+
@patch("builtins.open")
72+
@patch("glob.glob", return_value=["config.yaml"])
73+
def test_load_config(self, mock_glob, mock_file):
7474
"""
7575
Test loading a valid configuration file.
7676
"""
77-
arg_config = ConfigManager()
77+
# Setup the mock file content
7878
self.setup_file(mock_file)
79-
config = arg_config.load_config(self.config_file)
79+
80+
arg_config = ConfigManager()
81+
config = arg_config.load_config("/some/path")
82+
8083
self.assertIn("run1", config)
8184
self.assertEqual(
8285
config["run1"]["top_traj_file"], ["/path/to/tpr", "/path/to/trr"]
8386
)
87+
self.assertEqual(config["run1"]["selection_string"], "all")
88+
self.assertEqual(config["run1"]["start"], 0)
89+
self.assertEqual(config["run1"]["end"], -1)
90+
self.assertEqual(config["run1"]["step"], 1)
91+
self.assertEqual(config["run1"]["bin_width"], 30)
92+
self.assertEqual(config["run1"]["tempra"], 298.0)
93+
self.assertFalse(config["run1"]["verbose"])
94+
self.assertEqual(config["run1"]["thread"], 1)
95+
self.assertEqual(config["run1"]["output_file"], "output_file.json")
96+
self.assertEqual(config["run1"]["force_partitioning"], 0.5)
97+
self.assertFalse(config["run1"]["water_entropy"])
98+
99+
@patch("glob.glob", return_value=[])
100+
def test_load_config_no_yaml_files(self, mock_glob):
101+
arg_config = ConfigManager()
102+
config = arg_config.load_config("/some/path")
103+
self.assertEqual(config, {"run1": {}})
84104

85105
@patch("builtins.open", side_effect=FileNotFoundError)
86-
def test_load_config_file_not_found(self, mock_file):
106+
@patch("glob.glob", return_value=["config.yaml"])
107+
def test_load_config_file_not_found(self, mock_glob, mock_open):
87108
"""
88-
Test loading a configuration file that does not exist.
109+
Test loading a configuration file that exists but cannot be opened.
110+
Should return default config instead of raising an error.
89111
"""
90112
arg_config = ConfigManager()
91-
with self.assertRaises(FileNotFoundError):
92-
arg_config.load_config(self.config_file)
113+
config = arg_config.load_config("/some/path")
114+
self.assertEqual(config, {"run1": {}})
93115

94116
@patch.object(ConfigManager, "load_config", return_value=None)
95117
def test_no_cli_no_yaml(self, mock_load_config):
@@ -480,19 +502,17 @@ def test_edge_case_argument_values(self, mock_args):
480502
self.assertEqual(args.end, -10)
481503

482504
@patch("builtins.open", new_callable=mock_open, read_data="--- \n")
483-
@patch("os.path.exists", return_value=True)
484-
def test_empty_yaml_config(self, mock_exists, mock_file):
505+
@patch("glob.glob", return_value=["config.yaml"])
506+
def test_empty_yaml_config(self, mock_glob, mock_file):
485507
"""
486508
Test behavior when an empty YAML file is provided.
487-
Should use defaults or raise an appropriate error.
509+
Should return default config {'run1': {}}.
488510
"""
489-
490511
arg_config = ConfigManager()
491-
492-
config = arg_config.load_config(self.config_file)
512+
config = arg_config.load_config("/some/path")
493513

494514
self.assertIsInstance(config, dict)
495-
self.assertEqual(config, {})
515+
self.assertEqual(config, {"run1": {}})
496516

497517
def test_input_parameters_validation_all_valid(self):
498518
"""Test that input_parameters_validation passes with all valid inputs."""

0 commit comments

Comments
 (0)