def run(self): """Run the calculation job. This means invoking the `presubmit` and storing the temporary folder in the node's repository. Then we move the process in the `Wait` state, waiting for the `UPLOAD` transport task to be started. """ if self.inputs.metadata.dry_run: from aiida.common.folders import SubmitTestFolder from aiida.engine.daemon.execmanager import upload_calculation from aiida.transports.plugins.local import LocalTransport with LocalTransport() as transport: with SubmitTestFolder() as folder: calc_info = self.presubmit(folder) transport.chdir(folder.abspath) upload_calculation(self.node, transport, calc_info, folder, inputs=self.inputs, dry_run=True) self.node.dry_run_info = { 'folder': folder.abspath, 'script_filename': self.node.get_option('submit_script_filename') } return plumpy.Stop(None, True) # The following conditional is required for the caching to properly work. Even if the source node has a process # state of `Finished` the cached process will still enter the running state. The process state will have then # been overridden by the engine to `Running` so we cannot check that, but if the `exit_status` is anything other # than `None`, it should mean this node was taken from the cache, so the process should not be rerun. if self.node.exit_status is not None: return self.node.exit_status # Launch the upload operation return plumpy.Wait(msg='Waiting to upload', data=UPLOAD_COMMAND)
def test_upload_local_copy_list(fixture_sandbox, aiida_localhost, aiida_local_code_factory): """Test the ``local_copy_list`` functionality in ``upload_calculation``. Specifically, verify that files in the ``local_copy_list`` do not end up in the repository of the node. """ from aiida.common.datastructures import CalcInfo, CodeInfo from aiida.orm import CalcJobNode, SinglefileData inputs = { 'file_a': SinglefileData(io.BytesIO(b'content_a')).store(), 'file_b': SinglefileData(io.BytesIO(b'content_b')).store(), } node = CalcJobNode(computer=aiida_localhost) node.store() code = aiida_local_code_factory('arithmetic.add', '/bin/bash').store() code_info = CodeInfo() code_info.code_uuid = code.uuid calc_info = CalcInfo() calc_info.uuid = node.uuid calc_info.codes_info = [code_info] calc_info.local_copy_list = [ (inputs['file_a'].uuid, inputs['file_a'].filename, './files/file_a'), (inputs['file_a'].uuid, inputs['file_a'].filename, './files/file_b'), ] with LocalTransport() as transport: execmanager.upload_calculation(node, transport, calc_info, fixture_sandbox) assert node.list_object_names() == []
def run(self): """Run the calculation job. This means invoking the `presubmit` and storing the temporary folder in the node's repository. Then we move the process in the `Wait` state, waiting for the `UPLOAD` transport task to be started. """ from aiida.orm import Code, load_node from aiida.common.folders import SandboxFolder, SubmitTestFolder from aiida.common.exceptions import InputValidationError # The following conditional is required for the caching to properly work. Even if the source node has a process # state of `Finished` the cached process will still enter the running state. The process state will have then # been overridden by the engine to `Running` so we cannot check that, but if the `exit_status` is anything other # than `None`, it should mean this node was taken from the cache, so the process should not be rerun. if self.node.exit_status is not None: return self.node.exit_status if self.inputs.metadata.dry_run: folder_class = SubmitTestFolder else: folder_class = SandboxFolder with folder_class() as folder: computer = self.node.computer if not self.inputs.metadata.dry_run and self.node.has_cached_links(): raise exceptions.InvalidOperation('calculation node has unstored links in cache') calc_info, script_filename = self.presubmit(folder) calc_info.uuid = str(self.uuid) input_codes = [load_node(_.code_uuid, sub_classes=(Code,)) for _ in calc_info.codes_info] for code in input_codes: if not code.can_run_on(computer): raise InputValidationError( 'The selected code {} for calculation {} cannot run on computer {}'.format( code.pk, self.node.pk, computer.name)) # After this call, no modifications to the folder should be done self.node.put_object_from_tree(folder.abspath, force=True) if self.inputs.metadata.dry_run: from aiida.engine.daemon.execmanager import upload_calculation from aiida.transports.plugins.local import LocalTransport with LocalTransport() as transport: transport.chdir(folder.abspath) upload_calculation(self.node, transport, calc_info, script_filename, dry_run=True) self.node.dry_run_info = { 'folder': folder.abspath, 'script_filename': script_filename } return plumpy.Stop(None, True) # Launch the upload operation return plumpy.Wait(msg='Waiting to upload', data=(UPLOAD_COMMAND, calc_info, script_filename))
def test_gotocomputer(): """Test gotocomputer""" with LocalTransport() as transport: cmd_str = transport.gotocomputer_command('/remote_dir/') expected_str = ( """bash -c "if [ -d '/remote_dir/' ] ;""" """ then cd '/remote_dir/' ; bash -l ; else echo ' ** The directory' ; """ """echo ' ** /remote_dir/' ; echo ' ** seems to have been deleted, I logout...' ; fi" """ ) assert cmd_str == expected_str
def test_retrieve_files_from_list( tmp_path_factory, generate_calculation_node, file_hierarchy, retrieve_list, expected_hierarchy ): """Test the `retrieve_files_from_list` function.""" source = tmp_path_factory.mktemp('source') target = tmp_path_factory.mktemp('target') create_file_hierarchy(file_hierarchy, source) with LocalTransport() as transport: node = generate_calculation_node() transport.chdir(source) execmanager.retrieve_files_from_list(node, transport, target, retrieve_list) assert serialize_file_hierarchy(target) == expected_hierarchy
def test_retrieve_files_from_list(tmp_path_factory, generate_calculation_node): """Test the `retrieve_files_from_list` function.""" node = generate_calculation_node() retrieve_list = [ 'file_a.txt', ('sub/folder', 'sub/folder', 0), ] source = tmp_path_factory.mktemp('source') target = tmp_path_factory.mktemp('target') content_a = b'content_a' content_b = b'content_b' with open(str(source / 'file_a.txt'), 'wb') as handle: handle.write(content_a) handle.flush() os.makedirs(str(source / 'sub' / 'folder')) with open(str(source / 'sub' / 'folder' / 'file_b.txt'), 'wb') as handle: handle.write(content_b) handle.flush() with LocalTransport() as transport: transport.chdir(str(source)) execmanager.retrieve_files_from_list(node, transport, str(target), retrieve_list) assert sorted(os.listdir(str(target))) == sorted(['file_a.txt', 'sub']) assert os.listdir(str(target / 'sub')) == ['folder'] assert os.listdir(str(target / 'sub' / 'folder')) == ['file_b.txt'] with open(str(target / 'sub' / 'folder' / 'file_b.txt'), 'rb') as handle: assert handle.read() == content_b with open(str(target / 'file_a.txt'), 'rb') as handle: assert handle.read() == content_a
def test_basic(): """Test constructor.""" with LocalTransport(): pass
def test_closed_connection(self): """Test running a command on a closed connection.""" with self.assertRaises(TransportInternalError): transport = LocalTransport() transport.listdir()
def test_whoami(self): """Test the `whoami` command.""" import getpass with LocalTransport() as transport: self.assertEqual(transport.whoami(), getpass.getuser())
# Copyright (c), The AiiDA team. All rights reserved. # # This file is part of the AiiDA code. # # # # The code is hosted on GitHub at https://github.com/aiidateam/aiida-core # # For further information on the license, see the LICENSE.txt file # # For further information please visit http://www.aiida.net # ########################################################################### """Tests for the `LocalTransport`.""" import unittest from aiida.transports.plugins.local import LocalTransport from aiida.transports.transport import TransportInternalError # This will be used by test_all_plugins plugin_transport = LocalTransport() class TestGeneric(unittest.TestCase): """ Test whoami on localhost. """ def test_whoami(self): """Test the `whoami` command.""" import getpass with LocalTransport() as transport: self.assertEqual(transport.whoami(), getpass.getuser()) class TestBasicConnection(unittest.TestCase):