def setUpClass(cls, *args, **kwargs): super().setUpClass(*args, **kwargs) cls.computer.configure() # pylint: disable=no-member cls.remote_code = orm.Code(remote_computer_exec=(cls.computer, '/bin/bash')).store() cls.local_code = orm.Code(local_executable='bash', files=['/bin/bash']).store() cls.inputs = { 'x': orm.Int(1), 'y': orm.Int(2), 'metadata': { 'options': {} } }
def test_file_usage(fixture_sandbox, aiida_localhost, generate_calc_job): """Test a base template that uses two files.""" file1_node = orm.SinglefileData(io.BytesIO(b'Content of file 1')) file2_node = orm.SinglefileData(io.BytesIO(b'Content of file 2')) # Check that the files are correctly copied to the copy list entry_point_name = 'templatereplacer' inputs = { 'code': orm.Code(remote_computer_exec=(aiida_localhost, '/bin/bash')), 'metadata': { 'options': { 'resources': { 'num_machines': 1, 'tot_num_mpiprocs': 1 } } }, 'template': orm.Dict(dict={ 'files_to_copy': [('filenode1', 'file1.txt'), ('filenode2', 'file2.txt')], }), 'files': { 'filenode1': file1_node, 'filenode2': file2_node } } calc_info = generate_calc_job(fixture_sandbox, entry_point_name, inputs) reference_copy_list = [] for node_idname, target_path in inputs['template']['files_to_copy']: file_node = inputs['files'][node_idname] reference_copy_list.append((file_node.uuid, file_node.filename, target_path)) assert sorted(calc_info.local_copy_list) == sorted(reference_copy_list)
def test_add_default(fixture_sandbox, aiida_localhost, generate_calc_job): """Test a default `ArithmeticAddCalculation`.""" entry_point_name = 'arithmetic.add' inputs = {'x': orm.Int(1), 'y': orm.Int(2), 'code': orm.Code(remote_computer_exec=(aiida_localhost, '/bin/bash'))} calc_info = generate_calc_job(fixture_sandbox, entry_point_name, inputs) options = ArithmeticAddCalculation.spec().inputs['metadata']['options'] # Check the attributes of the returned `CalcInfo` assert isinstance(calc_info, datastructures.CalcInfo) assert sorted(calc_info.retrieve_list) == sorted([options['output_filename'].default]) codes_info = calc_info.codes_info assert isinstance(codes_info, list) assert len(codes_info) == 1 code_info = codes_info[0] assert isinstance(code_info, datastructures.CodeInfo) assert code_info.code_uuid == inputs['code'].uuid assert code_info.stdin_name == options['input_filename'].default assert code_info.stdout_name == options['output_filename'].default with fixture_sandbox.open(options['input_filename'].default) as handle: input_written = handle.read() assert input_written == 'echo $(({} + {}))\n'.format(inputs['x'].value, inputs['y'].value)
def test_code_list(self): """Test code list command.""" # set up second code 'code2' try: code = orm.Code.get_from_string('code2') except NotExistent: code = orm.Code( input_plugin_name='templatereplacer', remote_computer_exec=[self.computer, '/remote/abs/path'], ) code.label = 'code2' code.store() options = [ '-A', '-a', '-o', '--input-plugin=arithmetic.add', f'--computer={self.computer.label}' ] result = self.cli_runner.invoke(code_list, options) self.assertIsNone(result.exception, result.output) self.assertTrue( str(self.code.pk) in result.output, 'PK of first code should be included') self.assertTrue('code2' not in result.output, 'label of second code should not be included') self.assertTrue('comp' in result.output, 'computer name should be included') self.assertNotIn(result.output, '# No codes found matching the specified criteria.')
def setUpClass(cls): super().setUpClass() from aiida import orm cls.computer = orm.Computer(label='comp', hostname='localhost', transport_type='local', scheduler_type='direct', workdir='/tmp/aiida').store() cls.code = orm.Code(remote_computer_exec=(cls.computer, '/bin/true')).store() cls.group = orm.Group(label='test_group').store() cls.node = orm.Data().store() # some of the export tests write in the current directory, # make sure it is writeable and we don't pollute the current one cls.old_cwd = os.getcwd() cls.cwd = tempfile.mkdtemp(__name__) os.chdir(cls.cwd) # Utility helper cls.fixture_archive = 'export/migrate' cls.newest_archive = f'export_v{EXPORT_VERSION}_simple.aiida' cls.penultimate_archive = 'export_v0.6_simple.aiida'
def setUpClass(cls, *args, **kwargs): super(TestCalcJob, cls).setUpClass(*args, **kwargs) cls.remote_code = orm.Code(remote_computer_exec=(cls.computer, '/bin/true')).store() cls.local_code = orm.Code(local_executable='true', files=['/bin/true']).store() cls.inputs = { 'x': orm.Int(1), 'y': orm.Int(2), 'metadata': { 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, } } }
def silicon_builder(db_test_app): """Prepare a mock - ready calculation for silicon""" silicon = orm.StructureData() r_unit = 2.6954645 silicon.set_cell(np.array([[1, 1, 0], [1, 0, 1], [0, 1, 1]]) * r_unit) silicon.append_atom(symbols=["Si"], position=[0, 0, 0]) silicon.append_atom(symbols=["Si"], position=[r_unit * 0.5] * 3) silicon.label = "Si" silicon.description = "A silicon structure" param_dict = { # Notice that the keywords are group into two sub-dictionaries # just like you would do when preparing the inputs by hand "CELL": { "symmetry_generate": True, "snap_to_symmetry": True, # Pass a list of string to set a BLOCK inputs #"cell_constraints": #["0 0 0", "0 0 0"] }, "PARAM": { "task": "singlepoint", "basis_precision": "medium", "fix_occupancy": True, # Use bool type to make it easy for querying "opt_strategy": "memory", "num_dump_cycles": 0, "write_formatted_density": True } } # We need to create a Dict node that holds the dictionary param = orm.Dict(dict=param_dict) kpoints = orm.KpointsData() # Use gamma and 0.25, 0.25, 0.25 kpoints.set_kpoints_mesh((4, 4, 4), offset=(0, 0, 0)) c9 = OTFGData(otfg_entry="C9") CastepCalculation = CalculationFactory('castep.castep') code_path = check_output(['which', 'castep.mock'], universal_newlines=True).strip() castep_mock = orm.Code((db_test_app.localhost, code_path), input_plugin_name='castep.castep') builder = CastepCalculation.get_builder() builder.structure = silicon builder.parameters = param builder.kpoints = kpoints builder.code = castep_mock builder.pseudos = {'Si': c9} builder.metadata.options.withmpi = False builder.metadata.options.resources = { 'num_machines': 1, 'tot_num_mpiprocs': 2 } builder.metadata.options.max_wallclock_seconds = 600 builder.metadata.label = "Si SINGLEPOINT" builder.metadata.description = 'A Example CASTEP calculation for silicon' return builder
def test_base_template(fixture_sandbox, aiida_localhost, generate_calc_job): """Test a base template that emulates the arithmetic add.""" entry_point_name = 'templatereplacer' inputs = { 'code': orm.Code(remote_computer_exec=(aiida_localhost, '/bin/bash')), 'metadata': { 'options': { 'resources': { 'num_machines': 1, 'tot_num_mpiprocs': 1 } } }, 'template': orm.Dict( dict={ 'input_file_template': 'echo $(({x} + {y}))', 'input_file_name': 'input.txt', 'cmdline_params': ['input.txt'], 'output_file_name': 'output.txt', }), 'parameters': orm.Dict(dict={ 'x': 1, 'y': 2 }), } # Check the attributes of the resulting `CalcInfo` calc_info = generate_calc_job(fixture_sandbox, entry_point_name, inputs) assert isinstance(calc_info, datastructures.CalcInfo) assert sorted(calc_info.retrieve_list) == sorted( [inputs['template']['output_file_name']]) # Check the integrity of the `codes_info` codes_info = calc_info.codes_info assert isinstance(codes_info, list) assert len(codes_info) == 1 # Check the attributes of the resulting `CodeInfo` code_info = codes_info[0] assert isinstance(code_info, datastructures.CodeInfo) assert code_info.code_uuid == inputs['code'].uuid assert code_info.stdout_name == inputs['template']['output_file_name'] assert sorted(code_info.cmdline_params) == sorted( inputs['template']['cmdline_params']) # Check the content of the generated script with fixture_sandbox.open(inputs['template']['input_file_name']) as handle: input_written = handle.read() assert input_written == f"echo $(({inputs['parameters']['x']} + {inputs['parameters']['y']}))"
def test_input_code(self, temp_dir): """ This test checks that when a calculation is exported then the corresponding code is also exported. It also checks that the links are also in place after the import. """ code_label = 'test_code1' code = orm.Code() code.set_remote_computer_exec((self.computer, '/bin/true')) code.label = code_label code.store() code_uuid = code.uuid calc = orm.CalcJobNode() calc.computer = self.computer calc.set_option('resources', { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }) calc.add_incoming(code, LinkType.INPUT_CALC, 'code') calc.store() calc.seal() links_count = 1 export_links = get_all_node_links() export_file = os.path.join(temp_dir, 'export.aiida') export([calc], filename=export_file) self.clean_db() import_data(export_file) # Check that the code node is there self.assertEqual(orm.load_node(code_uuid).label, code_label) # Check that the link is in place import_links = get_all_node_links() self.assertListEqual(sorted(export_links), sorted(import_links)) self.assertEqual( len(export_links), links_count, 'Expected to find only one link from code to ' 'the calculation node before export. {} found.'.format( len(export_links))) self.assertEqual( len(import_links), links_count, 'Expected to find only one link from code to ' 'the calculation node after import. {} found.'.format( len(import_links)))
def test_provenance_exclude_list(self): """Test the functionality of the `CalcInfo.provenance_exclude_list` attribute.""" import tempfile code = orm.Code(input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/bin/true']).store() with tempfile.NamedTemporaryFile('w+') as handle: handle.write('dummy_content') handle.flush() file_one = orm.SinglefileData(file=handle.name) with tempfile.NamedTemporaryFile('w+') as handle: handle.write('dummy_content') handle.flush() file_two = orm.SinglefileData(file=handle.name) inputs = { 'code': code, 'files': { # Note the `FileCalcJob` will turn underscores in the key into forward slashes making a nested hierarchy 'base_a_sub_one': file_one, 'base_b_two': file_two, }, 'settings': orm.Dict(dict={'provenance_exclude_list': ['base/a/sub/one']}), 'metadata': { 'dry_run': True, 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } } } # We perform a `dry_run` because the calculation cannot actually run, however, the contents will still be # written to the node's repository so we can check it contains the expected contents. _, node = launch.run_get_node(FileCalcJob, **inputs) self.assertIn('folder', node.dry_run_info) # Verify that the folder (representing the node's repository) indeed do not contain the input files. Note, # however, that the directory hierarchy should be there, albeit empty self.assertIn('base', node.list_object_names()) self.assertEqual(sorted(['b']), sorted(node.list_object_names(os.path.join('base')))) self.assertEqual(['two'], node.list_object_names(os.path.join('base', 'b')))
def test_leak_ssh_calcjob(): """Test whether running a CalcJob over SSH leaks memory. Note: This relies on the 'slurm-ssh' computer being set up. """ code = orm.Code( input_plugin_name='arithmetic.add', remote_computer_exec=[orm.load_computer('slurm-ssh'), '/bin/bash']) inputs = {'x': orm.Int(1), 'y': orm.Int(2), 'code': code} run_finished_ok(ArithmeticAddCalculation, **inputs) # check that no reference to the process is left in memory # some delay is necessary in order to allow for all callbacks to finish process_instances = get_instances(processes.Process, delay=0.2) assert not process_instances, f'Memory leak: process instances remain in memory: {process_instances}'
def test_par_env_resources_computer(self): """Test launching a `CalcJob` an a computer with a scheduler using `ParEnvJobResource` as resources. Even though the computer defines a default number of MPI procs per machine, it should not raise when the scheduler that is defined does not actually support it, for example SGE or LSF. """ inputs = deepcopy(self.inputs) computer = orm.Computer('sge_computer', 'localhost', 'desc', 'local', 'sge').store() computer.set_default_mpiprocs_per_machine(1) inputs['code'] = orm.Code(remote_computer_exec=(computer, '/bin/bash')).store() inputs['metadata']['options']['resources'] = {'parallel_env': 'environment', 'tot_num_mpiprocs': 10} # Just checking that instantiating does not raise, meaning the inputs were valid ArithmeticAddCalculation(inputs=inputs)
def setUpClass(cls, *args, **kwargs): super().setUpClass(*args, **kwargs) import aiida files = [ os.path.join(os.path.dirname(aiida.__file__), os.pardir, '.ci', 'add.sh') ] cls.computer.configure() # pylint: disable=no-member cls.remote_code = orm.Code(remote_computer_exec=(cls.computer, '/bin/true')).store() cls.local_code = orm.Code(local_executable='add.sh', files=files).store() cls.inputs = { 'x': orm.Int(1), 'y': orm.Int(2), 'metadata': { 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }, } } }
def setUp(self): self.comp = orm.Computer.objects.get(name='comp') try: code = orm.Code.get_from_string('code') except NotExistent: code = orm.Code( input_plugin_name='arithmetic.add', remote_computer_exec=[self.comp, '/remote/abs/path'], ) code.label = 'code' code.description = 'desc' code.store() self.code = code self.cli_runner = CliRunner()
def setUp(self): try: code = orm.Code.get_from_string('code') except NotExistent: code = orm.Code( input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/remote/abs/path'], ) code.label = 'code' code.description = 'desc' code.set_prepend_text('text to prepend') code.set_append_text('text to append') code.store() self.code = code self.cli_runner = CliRunner()
def test_calcjob_dry_run_no_provenance(self): """Test that dry run with `store_provenance=False` still works for unstored inputs. The special thing about this test is that the unstored input nodes that will be used in the `local_copy_list`. This was broken as the code in `upload_calculation` assumed that the nodes could be loaded through their UUID which is not the case in the `store_provenance=False` mode with unstored nodes. Note that it also explicitly tests nested namespaces as that is a non-trivial case. """ import os import tempfile code = orm.Code(input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/bin/true']).store() with tempfile.NamedTemporaryFile('w+') as handle: handle.write('dummy_content') handle.flush() single_file = orm.SinglefileData(file=handle.name) file_one = orm.SinglefileData(file=handle.name) file_two = orm.SinglefileData(file=handle.name) inputs = { 'code': code, 'single_file': single_file, 'files': { 'file_one': file_one, 'file_two': file_two, }, 'metadata': { 'dry_run': True, 'store_provenance': False, 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } } } _, node = launch.run_get_node(FileCalcJob, **inputs) self.assertIn('folder', node.dry_run_info) for filename in ['single_file', 'file_one', 'file_two']: self.assertIn(filename, os.listdir(node.dry_run_info['folder']))
def test_launchers_dry_run_no_provenance(self): """Test the launchers in `dry_run` mode with `store_provenance=False`.""" from aiida.plugins import CalculationFactory ArithmeticAddCalculation = CalculationFactory('arithmetic.add') # pylint: disable=invalid-name code = orm.Code(input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/bin/true']).store() inputs = { 'code': code, 'x': orm.Int(1), 'y': orm.Int(1), 'metadata': { 'dry_run': True, 'store_provenance': False, 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } } } result = launch.run(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) result, pk = launch.run_get_pk(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) self.assertIsNone(pk) result, node = launch.run_get_node(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) self.assertIsInstance(node, orm.CalcJobNode) self.assertFalse(node.is_stored) self.assertIsInstance(node.dry_run_info, dict) self.assertIn('folder', node.dry_run_info) self.assertIn('script_filename', node.dry_run_info) node = launch.submit(ArithmeticAddCalculation, **inputs) self.assertIsInstance(node, orm.CalcJobNode) self.assertFalse(node.is_stored)
def test_launchers_dry_run(self): """All launchers should work with `dry_run=True`, even `submit` which forwards to `run`.""" from aiida.plugins import CalculationFactory ArithmeticAddCalculation = CalculationFactory('arithmetic.add') # pylint: disable=invalid-name code = orm.Code(input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/bin/true']).store() inputs = { 'code': code, 'x': orm.Int(1), 'y': orm.Int(1), 'metadata': { 'dry_run': True, 'options': { 'resources': { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 } } } } result = launch.run(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) result, pk = launch.run_get_pk(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) self.assertIsInstance(pk, int) result, node = launch.run_get_node(ArithmeticAddCalculation, **inputs) self.assertEqual(result, {}) self.assertIsInstance(node, orm.CalcJobNode) self.assertIsInstance(node.dry_run_info, dict) self.assertIn('folder', node.dry_run_info) self.assertIn('script_filename', node.dry_run_info) node = launch.submit(ArithmeticAddCalculation, **inputs) self.assertIsInstance(node, orm.CalcJobNode)
def test_code_type_change(self, temp_dir): """ Code type string changed Change: “code.Bool.” → “data.code.Code.” """ # Create Code instance code = orm.Code() code.set_remote_computer_exec((self.computer, '/bin/true')) code.store() # Save uuid and type code_uuid = str(code.uuid) code_type = code.node_type # Assert correct type exists prior to export self.assertEqual(code_type, 'data.code.Code.') # Export node filename = os.path.join(temp_dir, 'export.aiida') export([code], filename=filename) # Clean the database and reimport self.clean_db() import_data(filename) # Retrieve Code node and make sure exactly 1 is retrieved builder = orm.QueryBuilder() builder.append(orm.Code, project=['uuid']) imported_code = builder.all() self.assertEqual(builder.count(), 1) # Check uuid is the same after import imported_code_uuid = str(imported_code[0][0]) self.assertEqual(imported_code_uuid, code_uuid) # Check whether types are correctly imported imported_code_type = orm.load_node(imported_code_uuid).node_type self.assertEqual(imported_code_type, code_type)
def test_that_solo_code_is_exported_correctly(self, temp_dir): """ This test checks that when a calculation is exported then the corresponding code is also exported. """ code_label = 'test_code1' code = orm.Code() code.set_remote_computer_exec((self.computer, '/bin/true')) code.label = code_label code.store() code_uuid = code.uuid export_file = os.path.join(temp_dir, 'export.aiida') export([code], filename=export_file) self.clean_db() import_data(export_file) self.assertEqual(orm.load_node(code_uuid).label, code_label)
def test_code_get_builder(self): """Test that the `Code.get_builder` method returns a builder where the code is already set.""" code = orm.Code() code.set_remote_computer_exec((self.computer, '/bin/true')) code.label = 'test_code' code.set_input_plugin_name('templatereplacer') code.store() # Check that I can get a builder builder = code.get_builder() self.assertEqual(builder.code.pk, code.pk) # Check that I can set the parameters builder.parameters = orm.Dict(dict={}) # Check that it complains for an unknown input with self.assertRaises(AttributeError): builder.unknown_parameter = 3 # Check that it complains if the type is not the correct one (for the templatereplacer, it should be a Dict) with self.assertRaises(ValueError): builder.parameters = orm.Int(3)
def test_get_node_summary(self): """Test the `get_node_summary` utility.""" from aiida.cmdline.utils.common import get_node_summary computer_label = self.computer.name # pylint: disable=no-member code = orm.Code( input_plugin_name='arithmetic.add', remote_computer_exec=[self.computer, '/remote/abs/path'], ) code.store() node = orm.CalculationNode() node.computer = self.computer node.add_incoming(code, link_type=LinkType.INPUT_CALC, link_label='code') node.store() summary = get_node_summary(node) self.assertIn(node.uuid, summary) self.assertIn(computer_label, summary)
def test_add_custom_filenames(fixture_sandbox, aiida_localhost, generate_calc_job): """Test an `ArithmeticAddCalculation` with non-default input and output filenames.""" entry_point_name = 'arithmetic.add' input_filename = 'custom.in' output_filename = 'custom.out' inputs = { 'x': orm.Int(1), 'y': orm.Int(2), 'code': orm.Code(remote_computer_exec=(aiida_localhost, '/bin/bash')), 'metadata': { 'options': { 'input_filename': input_filename, 'output_filename': output_filename, } } } calc_info = generate_calc_job(fixture_sandbox, entry_point_name, inputs) code_info = calc_info.codes_info[0] assert code_info.stdin_name == input_filename assert code_info.stdout_name == output_filename assert calc_info.retrieve_list == [output_filename]
def test_cif_structure_roundtrip(self): from aiida.tools.dbexporters.tcod import export_cif, export_values from aiida.common.folders import SandboxFolder import tempfile with tempfile.NamedTemporaryFile(mode='w+') as tmpf: tmpf.write(''' data_test _cell_length_a 10 _cell_length_b 10 _cell_length_c 10 _cell_angle_alpha 90 _cell_angle_beta 90 _cell_angle_gamma 90 loop_ _atom_site_label _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z C 0 0 0 O 0.5 0.5 0.5 ''') tmpf.flush() a = orm.CifData(filepath=tmpf.name) c = a.get_structure() c.store() pd = orm.Dict() code = orm.Code(local_executable='test.sh') with tempfile.NamedTemporaryFile(mode='w+') as tmpf: tmpf.write("#/bin/bash\n\necho test run\n") tmpf.flush() code.put_object_from_filelike(tmpf, 'test.sh') code.store() calc = orm.CalcJobNode(computer=self.computer) calc.set_option('resources', { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }) calc.add_incoming(code, LinkType.INPUT_CALC, "code") calc.set_option('environment_variables', { 'PATH': '/dev/null', 'USER': '******' }) with tempfile.NamedTemporaryFile(mode='w+', prefix="Fe") as tmpf: tmpf.write("<UPF version=\"2.0.1\">\nelement=\"Fe\"\n") tmpf.flush() upf = orm.UpfData(filepath=tmpf.name) upf.store() calc.add_incoming(upf, LinkType.INPUT_CALC, "upf") with tempfile.NamedTemporaryFile(mode='w+') as tmpf: tmpf.write("data_test") tmpf.flush() cif = orm.CifData(filepath=tmpf.name) cif.store() calc.add_incoming(cif, LinkType.INPUT_CALC, "cif") with SandboxFolder() as fhandle: calc.put_object_from_tree(fhandle.abspath) calc.store() fd = orm.FolderData() with fd.open('_scheduler-stdout.txt', 'w') as fhandle: fhandle.write(u"standard output") with fd.open('_scheduler-stderr.txt', 'w') as fhandle: fhandle.write(u"standard error") fd.store() fd.add_incoming(calc, LinkType.CREATE, calc.link_label_retrieved) pd.add_incoming(calc, LinkType.CREATE, "create1") pd.store() with self.assertRaises(ValueError): export_cif(c, parameters=pd) c.add_incoming(calc, LinkType.CREATE, "create2") export_cif(c, parameters=pd) values = export_values(c, parameters=pd) values = values['0'] self.assertEquals(values['_tcod_computation_environment'], ['PATH=/dev/null\nUSER=unknown']) self.assertEquals(values['_tcod_computation_command'], ['cd 1; ./_aiidasubmit.sh'])
def setUpClass(cls, *args, **kwargs): super().setUpClass(*args, **kwargs) from aiida.common.links import LinkType from aiida.engine import ProcessState cls.computer = orm.Computer(name='comp', hostname='localhost', transport_type='local', scheduler_type='direct', workdir='/tmp/aiida').store() cls.code = orm.Code(remote_computer_exec=(cls.computer, '/bin/true')).store() cls.group = orm.Group(label='test_group').store() cls.node = orm.Data().store() cls.calcs = [] user = orm.User.objects.get_default() authinfo = orm.AuthInfo(computer=cls.computer, user=user) authinfo.store() process_class = CalculationFactory('templatereplacer') process_type = get_entry_point_string_from_class( process_class.__module__, process_class.__name__) # Create 5 CalcJobNodes (one for each CalculationState) for calculation_state in CalcJobState: calc = orm.CalcJobNode(computer=cls.computer, process_type=process_type) calc.set_option('resources', { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }) calc.store() calc.set_process_state(ProcessState.RUNNING) cls.calcs.append(calc) if calculation_state == CalcJobState.PARSING: cls.KEY_ONE = 'key_one' cls.KEY_TWO = 'key_two' cls.VAL_ONE = 'val_one' cls.VAL_TWO = 'val_two' output_parameters = orm.Dict(dict={ cls.KEY_ONE: cls.VAL_ONE, cls.KEY_TWO: cls.VAL_TWO, }).store() output_parameters.add_incoming(calc, LinkType.CREATE, 'output_parameters') # Create shortcut for easy dereferencing cls.result_job = calc # Add a single calc to a group cls.group.add_nodes([calc]) # Create a single failed CalcJobNode cls.EXIT_STATUS = 100 calc = orm.CalcJobNode(computer=cls.computer) calc.set_option('resources', { 'num_machines': 1, 'num_mpiprocs_per_machine': 1 }) calc.store() calc.set_exit_status(cls.EXIT_STATUS) calc.set_process_state(ProcessState.FINISHED) cls.calcs.append(calc) # Load the fixture containing a single ArithmeticAddCalculation node import_archive('calcjob/arithmetic.add.aiida') # Get the imported ArithmeticAddCalculation node ArithmeticAddCalculation = CalculationFactory('arithmetic.add') calculations = orm.QueryBuilder().append( ArithmeticAddCalculation).all()[0] cls.arithmetic_job = calculations[0]