diff --git a/tests/cmdline/commands/test_process.py b/tests/cmdline/commands/test_process.py index 15ff8911eb..064ab08e8b 100644 --- a/tests/cmdline/commands/test_process.py +++ b/tests/cmdline/commands/test_process.py @@ -352,12 +352,12 @@ def test_report(self, run_cli_command): assert len(result.output_lines) == 1, result.output_lines assert result.output_lines[0] == 'No log messages recorded for this entry' - def test_process_dump(self, run_cli_command, tmp_path, generate_workchain_multiply_add): + def test_process_dump(self, run_cli_command, tmp_path, run_workchain_multiply_add): """Test verdi process dump""" # Only test CLI interface here, the actual functionalities of the Python API are tested in `test_processes.py` test_path = tmp_path / 'cli-dump' - node = generate_workchain_multiply_add() + node = run_workchain_multiply_add() # Giving a single identifier should print a non empty string message options = [str(node.pk), '-p', str(test_path)] diff --git a/tests/conftest.py b/tests/conftest.py index 89b0a1bad7..be0c6d87d8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -277,6 +277,108 @@ def _generate_calcjob_node( return _generate_calcjob_node +@pytest.fixture() +def generate_calcjob_node_add(tmp_path, aiida_localhost, request): + def _generate_calcjob_node_add(x: int = 1, y: int = 2): + import json + + from aiida.common import LinkType + from aiida.engine import ProcessState + from aiida.orm import FolderData, InstalledCode, Int + from aiida.orm.utils.log import create_logger_adapter + from aiida.orm.utils.node import get_query_type_from_type_string + + workdir = tmp_path / 'workdir' + computer = aiida_localhost + generate_calcjob_node = request.getfixturevalue('generate_calcjob_node') + + # Create the calculation node + # NOTE: Not passing entry point due to: + # "[WARNING] could not load the calculation tools entry point core.arithmetic.add: + # Entry point 'core.arithmetic.add' not found in group 'aiida.tools.calculations'" + # As `aiida.tools.calculations` section is empty in `pyproject.toml` + # entry_point='core.arithmetic.add', + calcjob_node = generate_calcjob_node( + process_state=ProcessState.FINISHED, + exit_status=0, + entry_point=None, + workdir=str(workdir), + ) + calcjob_node.computer = computer + + # Create and store input nodes + x_node = Int(x) + y_node = Int(y) + code_node = InstalledCode(computer=computer, filepath_executable='/bin/bash') + + x_node.store() + y_node.store() + code_node.store() + + # Input files + input_content = f'echo $(({x} + {y}))\n' + calcjob_node.base.repository.put_object_from_bytes(input_content.encode(), 'aiida.in') + + # .aiida folder contents + calcinfo_dict = {'foo': 'bar'} + job_tmpl_dict = {'foo': 'bar'} + calcjob_node.base.repository.put_object_from_bytes( + json.dumps(calcinfo_dict, indent=4).encode(), '.aiida/calcinfo.json' + ) + calcjob_node.base.repository.put_object_from_bytes( + json.dumps(job_tmpl_dict, indent=4).encode(), '.aiida/job_tmpl.json' + ) + + # Submit script + submit_script = 'foobar' + calcjob_node.base.repository.put_object_from_bytes(submit_script.encode(), '_aiidasubmit.sh') + + # Add input links + calcjob_node.base.links.add_incoming(x_node, link_type=LinkType.INPUT_CALC, link_label='x') + calcjob_node.base.links.add_incoming(y_node, link_type=LinkType.INPUT_CALC, link_label='y') + calcjob_node.base.links.add_incoming(code_node, link_type=LinkType.INPUT_CALC, link_label='code') + + # Set some properties/attributes before storing + calcjob_node.base.attributes.set('is_valid_cache', True) + calcjob_node.base.attributes.set( + '_query_type_string', get_query_type_from_type_string(calcjob_node._plugin_type_string) + ) + calcjob_node._logger_adapter = create_logger_adapter(calcjob_node._logger, calcjob_node) + calcjob_node.set_process_state('finished') + calcjob_node.set_process_label('ArithmeticAddCalculation') + calcjob_node.set_process_type('aiida.calculations:core.arithmetic.add') + calcjob_node.set_exit_status(0) + calcjob_node.base.attributes.set('input_filename', 'aiida.in') + calcjob_node.base.attributes.set('output_filename', 'aiida.out') + + # Must store CalcjobNode before I can add output files + calcjob_node.store() + + # Create FolderData node for `retrieved` + retrieved_folder = FolderData() + output_content = f'{x+y}\n'.encode() + retrieved_folder.put_object_from_bytes(output_content, 'aiida.out') + + scheduler_stdout = '\n'.encode() + scheduler_stderr = '\n'.encode() + retrieved_folder.base.repository.put_object_from_bytes(scheduler_stdout, '_scheduler-stdout.txt') + retrieved_folder.base.repository.put_object_from_bytes(scheduler_stderr, '_scheduler-stderr.txt') + retrieved_folder.store() + + retrieved_folder.base.links.add_incoming(calcjob_node, link_type=LinkType.CREATE, link_label='retrieved') + + # Create and link output node (sum) + output_node = Int(x + y) + output_node.store() + output_node.base.links.add_incoming(calcjob_node, link_type=LinkType.CREATE, link_label='sum') + + calcjob_node.seal() + + return calcjob_node + + return _generate_calcjob_node_add + + @pytest.fixture def generate_calculation_node(): """Generate an instance of a `CalculationNode`.""" @@ -831,8 +933,8 @@ def reset_log_level(): @pytest.fixture -def generate_calculation_node_add(aiida_localhost): - def _generate_calculation_node_add(): +def run_calculation_arithmetic_add(aiida_localhost): + def _run_calculation_arithmetic_add(): from aiida.engine import run_get_node from aiida.orm import InstalledCode, Int from aiida.plugins import CalculationFactory @@ -849,12 +951,12 @@ def _generate_calculation_node_add(): return add_node - return _generate_calculation_node_add + return _run_calculation_arithmetic_add @pytest.fixture -def generate_workchain_multiply_add(aiida_localhost): - def _generate_workchain_multiply_add(): +def run_workchain_multiply_add(aiida_localhost): + def _run_workchain_multiply_add(): from aiida.engine import run_get_node from aiida.orm import InstalledCode, Int from aiida.plugins import WorkflowFactory @@ -872,7 +974,7 @@ def _generate_workchain_multiply_add(): return multiply_add_node - return _generate_workchain_multiply_add + return _run_workchain_multiply_add @pytest.fixture diff --git a/tests/tools/dumping/test_processes.py b/tests/tools/dumping/test_processes.py index accfbd17d2..4175bdd292 100644 --- a/tests/tools/dumping/test_processes.py +++ b/tests/tools/dumping/test_processes.py @@ -183,10 +183,10 @@ def test_dump_workflow(generate_calculation_node_io, generate_workchain_node_io, assert all([expected_file.is_file() for expected_file in expected_files]) -def test_dump_multiply_add(tmp_path, generate_workchain_multiply_add): +def test_dump_multiply_add(tmp_path, run_workchain_multiply_add): dump_parent_path = tmp_path / 'wc-dump-test-multiply-add' process_dumper = ProcessDumper() - wc_node = generate_workchain_multiply_add() + wc_node = run_workchain_multiply_add() process_dumper.dump(process_node=wc_node, output_path=dump_parent_path) input_files = ['_aiidasubmit.sh', 'aiida.in', '.aiida/job_tmpl.json', '.aiida/calcinfo.json'] @@ -313,11 +313,11 @@ def test_dump_calculation_no_inputs(tmp_path, generate_calculation_node_io): assert not (dump_parent_path / node_inputs_relpath).is_dir() -def test_dump_calculation_add(tmp_path, generate_calculation_node_add): +def test_dump_calculation_add(tmp_path, generate_calcjob_node_add): dump_parent_path = tmp_path / 'cj-dump-test-add' process_dumper = ProcessDumper() - calculation_node_add = generate_calculation_node_add() + calculation_node_add = generate_calcjob_node_add() process_dumper._dump_calculation(calculation_node=calculation_node_add, output_path=dump_parent_path) input_files = ['_aiidasubmit.sh', 'aiida.in', '.aiida/job_tmpl.json', '.aiida/calcinfo.json'] @@ -393,12 +393,12 @@ def test_prepare_dump_path(tmp_path): def test_generate_default_dump_path( - generate_calculation_node_add, - generate_workchain_multiply_add, + generate_calcjob_node_add, + run_workchain_multiply_add, ): process_dumper = ProcessDumper() - add_node = generate_calculation_node_add() - multiply_add_node = generate_workchain_multiply_add() + add_node = generate_calcjob_node_add() + multiply_add_node = run_workchain_multiply_add() add_path = process_dumper._generate_default_dump_path(process_node=add_node) multiply_add_path = process_dumper._generate_default_dump_path(process_node=multiply_add_node) @@ -422,7 +422,7 @@ def test_generate_calculation_io_mapping(): def test_generate_child_node_label( - generate_workchain_multiply_add, generate_calculation_node_io, generate_workchain_node_io + run_workchain_multiply_add, generate_calculation_node_io, generate_workchain_node_io ): # Check with manually constructed, more complex workchain cj_node = generate_calculation_node_io(attach_outputs=False) @@ -445,7 +445,7 @@ def test_generate_child_node_label( assert output_paths == ['00-sub_workflow', '01-calculation'] # Check with multiply_add workchain node - multiply_add_node = generate_workchain_multiply_add() + multiply_add_node = run_workchain_multiply_add() output_triples = multiply_add_node.base.links.get_outgoing().all() # Sort by ctime here, not mtime, as I'm generating the WorkChain normally output_triples = sorted(output_triples, key=lambda link_triple: link_triple.node.ctime) @@ -455,7 +455,7 @@ def test_generate_child_node_label( assert output_paths == ['00-multiply', '01-ArithmeticAddCalculation', '02-result'] -def test_dump_node_yaml(generate_calculation_node_io, tmp_path, generate_workchain_multiply_add): +def test_dump_node_yaml(generate_calculation_node_io, tmp_path, run_workchain_multiply_add): process_dumper = ProcessDumper() cj_node = generate_calculation_node_io(attach_outputs=False) process_dumper._dump_node_yaml(process_node=cj_node, output_path=tmp_path) @@ -463,7 +463,7 @@ def test_dump_node_yaml(generate_calculation_node_io, tmp_path, generate_workcha assert (tmp_path / node_metadata_file).is_file() # Test with multiply_add - wc_node = generate_workchain_multiply_add() + wc_node = run_workchain_multiply_add() process_dumper._dump_node_yaml(process_node=wc_node, output_path=tmp_path) assert (tmp_path / node_metadata_file).is_file() @@ -497,8 +497,8 @@ def test_dump_node_yaml(generate_calculation_node_io, tmp_path, generate_workcha assert 'Node extras:' not in contents -def test_generate_parent_readme(tmp_path, generate_workchain_multiply_add): - wc_node = generate_workchain_multiply_add() +def test_generate_parent_readme(tmp_path, run_workchain_multiply_add): + wc_node = run_workchain_multiply_add() process_dumper = ProcessDumper() process_dumper._generate_readme(process_node=wc_node, output_path=tmp_path)