@@ -29,46 +29,41 @@ def lobster_test_dir(test_dir):
29
29
return test_dir / "lobster"
30
30
31
31
32
- def monkeypatch_lobster (monkeypatch , lobster_test_dir ):
33
- """
34
- This is provided as a generator and can be used as by conextmanagers and
35
- pytest.fixture ("mock_lobster").
32
+ def monkeypatch_lobster (monkeypatch : pytest .MonkeyPatch , lobster_test_dir : Path ):
33
+ """Monkeypatch LOBSTER run calls for testing purposes.
34
+
35
+ This generator can be used as a context manager or pytest fixture ("mock_lobster").
36
+ It replaces calls to run_lobster with a mock function that copies reference files
37
+ instead of running LOBSTER.
36
38
37
- It works by monkeypatching (replacing) calls to run_lobster that will
38
- work when the lobster executables
39
- are not present.
40
39
The primary idea is that instead of running LOBSTER to generate the output files,
41
- reference files will be copied into the directory instead. As we do not want to
42
- test whether LOBSTER is giving the correct output rather that the calculation inputs
43
- are generated correctly and that the outputs are parsed properly, this should be
44
- sufficient for our needs.
45
- To use the fixture successfully, the following steps must be followed:
46
- 1. "mock_lobster" should be included as an argument to any test that would
47
- like to use its functionally.
48
- 2. For each job in your workflow, you should prepare a reference directory
49
- containing two folders "inputs" (containing the reference input files
50
- expected to be produced by Lobsterin.standard_calculations_from_vasp_files
51
- and "outputs" (containing the expected
52
- output files to be produced by run_lobster). These files should reside in a
53
- subdirectory of "tests/test_data/lobster".
54
- 3. Create a dictionary mapping each job name to its reference directory.
55
- Note that you should supply the reference directory relative to the
56
- "tests/test_data/lobster" folder. For example, if your calculation
57
- has one job named "lobster_run_0" and the reference files are present in
58
- "tests/test_data/lobster/Si_lobster_run_0", the dictionary
59
- would look like: ``{"lobster_run_0": "Si_lobster_run_0"}``.
60
- 4. Optional: create a dictionary mapping each job name to custom
61
- keyword arguments that will be supplied to fake_run_lobster.
62
- This way you can configure which lobsterin settings are expected for each job.
63
- For example, if your calculation has one job named "lobster_run_0"
64
- and you wish to validate that "basisfunctions" is set correctly
65
- in the lobsterin, your dictionary would look like
66
- ``{"lobster_run_0": {"lobsterin_settings": {"basisfunctions": Ba 5p 5s 6s}}``.
67
- 5. Inside the test function, call `mock_lobster(ref_paths, fake_lobster_kwargs)`,
68
- where ref_paths is the dictionary created in step 3
69
- and fake_lobster_kwargs is the
70
- dictionary created in step 4.
71
- 6. Run your lobster job after calling `mock_lobster`.
40
+ reference files will be copied into the directory instead. This ensures that the
41
+ calculation inputs are generated correctly and that the outputs are parsed properly.
42
+
43
+ To use the fixture successfully, follow these steps:
44
+ 1. Include "mock_lobster" as an argument to any test that would like to use its functionality.
45
+ 2. For each job in your workflow, prepare a reference directory containing two folders:
46
+ "inputs" (containing the reference input files expected to be produced by
47
+ Lobsterin.standard_calculations_from_vasp_files) and "outputs" (containing the expected
48
+ output files to be produced by run_lobster). These files should reside in a subdirectory
49
+ of "tests/test_data/lobster".
50
+ 3. Create a dictionary mapping each job name to its reference directory. Note that you should
51
+ supply the reference directory relative to the "tests/test_data/lobster" folder. For example,
52
+ if your calculation has one job named "lobster_run_0" and the reference files are present in
53
+ "tests/test_data/lobster/Si_lobster_run_0", the dictionary would look like:
54
+ {"lobster_run_0": "Si_lobster_run_0"}.
55
+ 4. Optionally, create a dictionary mapping each job name to custom keyword arguments that will be
56
+ supplied to fake_run_lobster. This way you can configure which lobsterin settings are expected
57
+ for each job. For example, if your calculation has one job named "lobster_run_0" and you wish
58
+ to validate that "basisfunctions" is set correctly in the lobsterin, your dictionary would look like:
59
+ {"lobster_run_0": {"lobsterin_settings": {"basisfunctions": Ba 5p 5s 6s}}.
60
+ 5. Inside the test function, call `mock_lobster(ref_paths, fake_lobster_kwargs)`, where ref_paths is the
61
+ dictionary created in step 3 and fake_lobster_kwargs is the dictionary created in step 4.
62
+ 6. Run your LOBSTER job after calling `mock_lobster`.
63
+
64
+ Args:
65
+ monkeypatch (pytest.MonkeyPatch): The pytest monkeypatch fixture.
66
+ lobster_test_dir (Path): The directory containing reference files for LOBSTER tests.
72
67
"""
73
68
74
69
def mock_run_lobster (* args , ** kwargs ):
@@ -81,7 +76,10 @@ def mock_run_lobster(*args, **kwargs):
81
76
monkeypatch .setattr (atomate2 .lobster .run , "run_lobster" , mock_run_lobster )
82
77
monkeypatch .setattr (atomate2 .lobster .jobs , "run_lobster" , mock_run_lobster )
83
78
84
- def _run (ref_paths , fake_run_lobster_kwargs ):
79
+ def _run (
80
+ ref_paths : dict [str , str | Path ],
81
+ fake_run_lobster_kwargs : dict [str , dict [str , Sequence ]],
82
+ ):
85
83
_LOBS_REF_PATHS .update (ref_paths )
86
84
_FAKE_RUN_LOBSTER_KWARGS .update (fake_run_lobster_kwargs )
87
85
@@ -131,7 +129,13 @@ def fake_run_lobster(
131
129
logger .info ("ran fake LOBSTER, generated outputs" )
132
130
133
131
134
- def verify_inputs (ref_path : str | Path , lobsterin_settings : Sequence [str ]):
132
+ def verify_inputs (ref_path : str | Path , lobsterin_settings : Sequence [str ]) -> None :
133
+ """Verify LOBSTER input files against reference settings.
134
+
135
+ Args:
136
+ ref_path (str | Path): Path to the reference directory containing input files.
137
+ lobsterin_settings (Sequence[str]): A list of LOBSTER settings to check.
138
+ """
135
139
user = Lobsterin .from_file ("lobsterin" )
136
140
137
141
# Check lobsterin
@@ -142,7 +146,12 @@ def verify_inputs(ref_path: str | Path, lobsterin_settings: Sequence[str]):
142
146
raise ValueError (f"lobsterin value of { key } is inconsistent!" )
143
147
144
148
145
- def copy_lobster_outputs (ref_path : str | Path ):
149
+ def copy_lobster_outputs (ref_path : str | Path ) -> None :
150
+ """Copy LOBSTER output files from the reference directory to the current directory.
151
+
152
+ Args:
153
+ ref_path (str | Path): Path to the reference directory containing output files.
154
+ """
146
155
output_path = Path (ref_path ) / "outputs"
147
156
for output_file in output_path .iterdir ():
148
157
if output_file .is_file ():
0 commit comments