Ejemplo n.º 1
0
def add_data_and_message():
    """
    Makes and returns some test data and message
    """
    data = {
        'data':
        '\\\\isis\\inst$\\NDXTESTINSTRUMENT\\Instrument\\data\\cycle_21_1\\data.nxs',
        'facility': 'ISIS',
        'instrument': 'TESTINSTRUMENT',
        'rb_number': '1234',
        'run_number': '4321',
        'run_version': 1,
        'reduction_script':
        'print("hello")',  # not actually used for the reduction
        'reduction_arguments': {
            "standard_vars": {
                "arg1": "differentvalue",
                "arg2": 321
            },
            "advanced_vars": {
                "adv_arg1": "advancedvalue2",
                "adv_arg2": ""
            }
        },
        'description': 'This is a test',
        'software': {
            "name": "Mantid",
            "version": "latest",
        },
    }

    message = Message()
    message.populate(data)
    return data, message
Ejemplo n.º 2
0
def add_bad_data_and_message():
    """
    Makes and returns some test data and message
    """
    data = {
        'data':
        CYCLE_DIRECTORY % ("TESTINSTRUMENT", "21_1") + '/data.nxs',
        'facility':
        'ISIS',
        'instrument':
        'TESTINSTRUMENT',
        'rb_number':
        '1234',
        'run_number':
        '4321',
        'run_version':
        1,
        'reduction_script':
        'print("hello")',  # not actually used for the reduction
        'reduction_arguments':
        "None",
        'description':
        'This is a test',
        'software':
        "6.2.0",
        "reduction_data":
        "/instrument/TESTINSTRUMENT/RBNumber/RB1234/autoreduced/Test run name/run-version-1",
        "reduction_log":
        "Running reduction script: /isis/NDXTESTINSTRUMENT/user/scripts/autoreduction/reduce.py"
    }

    message = Message()
    message.populate(data)
    return data, message
 def test_populate_with_invalid_key(self):
     """
     Test: A warning is logged
     When: An unknown key is used to populate the Message
     """
     args = {'unknown': True}
     msg = Message()
     with self.assertRaises(ValueError):
         msg.populate(args)
    def run(self) -> Message:
        """Run the reduction subprocess."""
        try:
            # We need to run the reduction in a new process, otherwise scripts
            # will fail when they use things that require access to a main loop
            # e.g. a GUI main loop, for matplotlib or Mantid
            serialized_vars = self.message.serialize()
            serialized_vars_truncated = self.message.serialize(
                limit_reduction_script=True)
            args = ["autoreduce-runner-start", serialized_vars, self.run_name]
            logger.info("Calling: %s %s %s %s ", "python3", "runner.py",
                        serialized_vars_truncated, self.run_name)

            # Return a client configured from environment variables
            # The environment variables used are the same as those used by the Docker command-line client
            # https://docs.docker.com/engine/reference/commandline/cli/#environment-variables
            client = docker.from_env()

            image = get_correct_image(client, self.software)

            if "AUTOREDUCTION_PRODUCTION" not in os.environ:
                if not os.path.exists(ARCHIVE_ROOT):
                    Path(ARCHIVE_ROOT).mkdir(parents=True, exist_ok=True)
                if not os.path.exists(self.reduced_data_path):
                    self.reduced_data_path.mkdir(parents=True, exist_ok=True)
                # Run chmod's to make sure the directories are writable
                self.reduced_data_path.chmod(0o777)
                Path(ARCHIVE_ROOT).chmod(0o777)
                Path(AUTOREDUCE_HOME_ROOT).chmod(0o777)
                Path(f'{AUTOREDUCE_HOME_ROOT}/logs/autoreduce.log').chmod(
                    0o777)

            container = client.containers.run(
                image=image,
                command=args,
                volumes={
                    AUTOREDUCE_HOME_ROOT: {
                        'bind': '/home/isisautoreduce/.autoreduce/',
                        'mode': 'rw'
                    },
                    self.mantid_path: {
                        'bind': '/home/isisautoreduce/.mantid/',
                        'mode': 'rw'
                    },
                    ARCHIVE_ROOT: {
                        'bind': '/isis/',
                        'mode': 'rw'
                    },
                    self.reduced_data_path: {
                        'bind': '/instrument/',
                        'mode': 'rw'
                    },
                },
                stdin_open=True,
                environment=[
                    "AUTOREDUCTION_PRODUCTION=1", "PYTHONIOENCODING=utf-8"
                ],
                stdout=True,
                stderr=True,
            )

            logger.info("Container logs %s", container.decode("utf-8"))

            with open(f'{AUTOREDUCE_HOME_ROOT}/output.txt',
                      encoding="utf-8",
                      mode='r') as out_file:
                result_message_raw = out_file.read()

            result_message = Message()

            result_message.populate(result_message_raw)

        # If the specified image does not exist.
        except ImageNotFound as exc:
            raise exc
        # If the server returns an error.
        except APIError as exc:
            raise exc
        # If the container exits with a non-zero exit code and detach is False.
        except ContainerError as exc:
            raise exc
        except Exception:  # pylint:disable=broad-except
            logger.error("Processing encountered an error: %s",
                         traceback.format_exc())
            self.message.message = f"Processing encountered an error: {traceback.format_exc()}"
            result_message = self.message

        return result_message