예제 #1
0
    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)
예제 #2
0
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() == []
예제 #3
0
    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))
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
 def test_basic():
     """Test constructor."""
     with LocalTransport():
         pass
예제 #8
0
    def test_closed_connection(self):
        """Test running a command on a closed connection."""

        with self.assertRaises(TransportInternalError):
            transport = LocalTransport()
            transport.listdir()
예제 #9
0
    def test_whoami(self):
        """Test the `whoami` command."""
        import getpass

        with LocalTransport() as transport:
            self.assertEqual(transport.whoami(), getpass.getuser())
예제 #10
0
# 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):