diff --git a/docs/user-guide/color_mixing.rst b/docs/user-guide/color_mixing.rst index 8d2c64a..5cc6b22 100644 --- a/docs/user-guide/color_mixing.rst +++ b/docs/user-guide/color_mixing.rst @@ -101,15 +101,15 @@ This is the Python code for the color analyzer device: class ColorAnalyzerDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: port = int(initialization_parameters["port"]) self.client = DeviceClient(port) self.client.open_connection() - def _cleanup(self) -> None: + async def _cleanup(self) -> None: self.client.close_connection() - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: return {} def analyze(self, container: Container) -> tuple[Container, tuple[int, int, int]]: @@ -168,7 +168,7 @@ This is the Python code the "Analyze color" task: class AnalyzeColorTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/docs/user-guide/devices.rst b/docs/user-guide/devices.rst index 84c1aa2..b2214af 100644 --- a/docs/user-guide/devices.rst +++ b/docs/user-guide/devices.rst @@ -67,15 +67,15 @@ Below is a example implementation of a magnetic mixer device: from user.color_lab.common.device_client import DeviceClient class MagneticMixerDevice(BaseDevice): - def _initialize(self, initialization_parameters: Dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: Dict[str, Any]) -> None: port = int(initialization_parameters["port"]) self.client = DeviceClient(port) self.client.open_connection() - def _cleanup(self) -> None: + async def _cleanup(self) -> None: self.client.close_connection() - def _report(self) -> Dict[str, Any]: + async def _report(self) -> Dict[str, Any]: return {} def mix(self, container: Container, mixing_time: int, mixing_speed: int) -> Container: diff --git a/docs/user-guide/tasks.rst b/docs/user-guide/tasks.rst index 0794753..b6f384f 100644 --- a/docs/user-guide/tasks.rst +++ b/docs/user-guide/tasks.rst @@ -239,7 +239,7 @@ Python File (task.yml) class MagneticMixingTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/eos/devices/base_device.py b/eos/devices/base_device.py index ef56613..7974810 100644 --- a/eos/devices/base_device.py +++ b/eos/devices/base_device.py @@ -1,58 +1,39 @@ +import asyncio import atexit -import threading -from abc import ABC, abstractmethod, ABCMeta +from abc import ABC, abstractmethod from enum import Enum from typing import Any from eos.devices.exceptions import ( EosDeviceInitializationError, EosDeviceCleanupError, - EosDeviceError, ) -class DeviceStatus(Enum): - DISABLED = "DISABLED" - IDLE = "IDLE" - BUSY = "BUSY" - ERROR = "ERROR" - - -def capture_exceptions(func: callable) -> callable: - def wrapper(self, *args, **kwargs) -> Any: - try: - return func(self, *args, **kwargs) - - except ( - EosDeviceInitializationError, - EosDeviceCleanupError, - ) as e: - raise e - except Exception as e: - self._status = DeviceStatus.ERROR - raise EosDeviceError(f"Error in the function '{func.__name__}' in device '{self._device_id}'.") from e +def register_async_exit_callback(async_fn, *args, **kwargs) -> None: + """ + Register an async function to run at program exit. + """ - return wrapper + async def _run_async_fn() -> None: + await async_fn(*args, **kwargs) + def _run_on_exit() -> None: + loop = asyncio.new_event_loop() + loop.run_until_complete(_run_async_fn()) + loop.close() -class DeviceMeta(ABCMeta): - def __new__(cls, name: str, bases: tuple, dct: dict): - cls._add_exception_capture_to_child_methods(bases, dct) - return super().__new__(cls, name, bases, dct) + atexit.register(_run_on_exit) - @staticmethod - def _add_exception_capture_to_child_methods(bases: tuple, dct: dict) -> None: - base_methods = set() - for base in bases: - if isinstance(base, DeviceMeta): - base_methods.update(base.__dict__.keys()) - for attr, value in dct.items(): - if callable(value) and not attr.startswith("__") and attr not in base_methods: - dct[attr] = capture_exceptions(value) +class DeviceStatus(Enum): + DISABLED = "DISABLED" + IDLE = "IDLE" + BUSY = "BUSY" + ERROR = "ERROR" -class BaseDevice(ABC, metaclass=DeviceMeta): +class BaseDevice(ABC): """ The base class for all devices in EOS. """ @@ -62,43 +43,42 @@ def __init__( device_id: str, lab_id: str, device_type: str, - initialization_parameters: dict[str, Any], ): self._device_id = device_id self._lab_id = lab_id self._device_type = device_type self._status = DeviceStatus.DISABLED - self._initialization_parameters = initialization_parameters + self._initialization_parameters = {} - self._lock = threading.Lock() + self._lock = asyncio.Lock() - atexit.register(self.cleanup) - self.initialize(initialization_parameters) + register_async_exit_callback(self.cleanup) - def initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def initialize(self, initialization_parameters: dict[str, Any]) -> None: """ Initialize the device. After calling this method, the device is ready to be used for tasks and the status is IDLE. """ - with self._lock: + async with self._lock: if self._status != DeviceStatus.DISABLED: raise EosDeviceInitializationError(f"Device {self._device_id} is already initialized.") try: - self._initialize(initialization_parameters) + await self._initialize(initialization_parameters) self._status = DeviceStatus.IDLE + self._initialization_parameters = initialization_parameters except Exception as e: self._status = DeviceStatus.ERROR raise EosDeviceInitializationError( f"Error initializing device {self._device_id}: {e!s}", ) from e - def cleanup(self) -> None: + async def cleanup(self) -> None: """ Clean up the device. After calling this method, the device can no longer be used for tasks and the status is DISABLED. """ - with self._lock: + async with self._lock: if self._status == DeviceStatus.DISABLED: return @@ -108,67 +88,84 @@ def cleanup(self) -> None: ) try: - self._cleanup() + await self._cleanup() self._status = DeviceStatus.DISABLED except Exception as e: self._status = DeviceStatus.ERROR raise EosDeviceCleanupError(f"Error cleaning up device {self._device_id}: {e!s}") from e - def enable(self) -> None: + async def report(self) -> dict[str, Any]: + """ + Return a dictionary with any member variables needed for logging purposes and progress tracking. + """ + return await self._report() + + async def enable(self) -> None: """ Enable the device. The status should be IDLE after calling this method. """ if self._status == DeviceStatus.DISABLED: - self.initialize(self._initialization_parameters) + await self.initialize(self._initialization_parameters) - def disable(self) -> None: + async def disable(self) -> None: """ Disable the device. The status should be DISABLED after calling this method. """ if self._status != DeviceStatus.DISABLED: - self.cleanup() - - def report(self) -> dict[str, Any]: - """ - Return a dictionary with any member variables needed for logging purposes and progress tracking. - """ - return self._report() + await self.cleanup() - def report_status(self) -> dict[str, Any]: - """ - Return a dictionary with the id and status of the task handler. - """ + def get_status(self) -> dict[str, Any]: return { "id": self._device_id, "status": self._status, } + def get_id(self) -> str: + return self._device_id + + def get_lab_id(self) -> str: + return self._lab_id + + def get_device_type(self) -> str: + return self._device_type + + def get_initialization_parameters(self) -> dict[str, Any]: + return self._initialization_parameters + @property def id(self) -> str: return self._device_id @property - def type(self) -> str: + def lab_id(self) -> str: + return self._lab_id + + @property + def device_type(self) -> str: return self._device_type @property def status(self) -> DeviceStatus: return self._status + @property + def initialization_parameters(self) -> dict[str, Any]: + return self._initialization_parameters + @abstractmethod - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: """ Implementation for the initialization of the device. """ @abstractmethod - def _cleanup(self) -> None: + async def _cleanup(self) -> None: """ Implementation for the cleanup of the device. """ @abstractmethod - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: """ Implementation for the report method. """ diff --git a/eos/devices/device_manager.py b/eos/devices/device_manager.py index 6388b8e..4aa1773 100644 --- a/eos/devices/device_manager.py +++ b/eos/devices/device_manager.py @@ -141,7 +141,7 @@ async def _create_devices_for_lab(self, lab_id: str) -> None: computer=device_config.computer, ) devices_to_upsert.append(new_device) - self._create_device_actor(new_device) + await self._create_device_actor(new_device) if devices_to_upsert: await self._devices.bulk_upsert([device.model_dump() for device in devices_to_upsert]) @@ -160,7 +160,7 @@ def _restore_device_actor(self, device: Device) -> None: ) log.debug(f"Restored device actor {device_actor_id}") - def _create_device_actor(self, device: Device) -> None: + async def _create_device_actor(self, device: Device) -> None: lab_config = self._configuration_manager.labs[device.lab_id] device_config = lab_config.devices[device.id] computer_name = device_config.computer.lower() @@ -194,10 +194,11 @@ def _create_device_actor(self, device: Device) -> None: name=device_actor_id, num_cpus=0, resources=resources, - ).remote(device.id, device.lab_id, device.type, initialization_parameters) + ).remote(device.id, device.lab_id, device.type) + await self._device_actor_handles[device_actor_id].initialize.remote(initialization_parameters) def _check_device_actors_healthy(self) -> None: - status_reports = [actor_handle.report_status.remote() for actor_handle in self._device_actor_handles.values()] + status_reports = [actor_handle.get_status.remote() for actor_handle in self._device_actor_handles.values()] status_report_to_device_actor_id = { status_report: device_actor_id for device_actor_id, status_report in zip(self._device_actor_handles.keys(), status_reports, strict=False) diff --git a/eos/tasks/base_task.py b/eos/tasks/base_task.py index 4682c5e..7b72914 100644 --- a/eos/tasks/base_task.py +++ b/eos/tasks/base_task.py @@ -20,12 +20,12 @@ def __init__(self, experiment_id: str, task_id: str) -> None: self._experiment_id = experiment_id self._task_id = task_id - def execute( + async def execute( self, devices: DevicesType, parameters: ParametersType, containers: ContainersType ) -> OutputType | None: """Execute a task with the given input and return the output.""" try: - output = self._execute(devices, parameters, containers) + output = await self._execute(devices, parameters, containers) output_parameters, output_containers, output_files = ({}, {}, {}) @@ -42,7 +42,7 @@ def execute( raise EosTaskExecutionError(f"Error executing task {self._task_id}") from e @abstractmethod - def _execute( + async def _execute( self, devices: DevicesType, parameters: ParametersType, containers: ContainersType ) -> OutputType | None: """Implementation for the execution of a task.""" diff --git a/eos/tasks/task_executor.py b/eos/tasks/task_executor.py index a74bd90..5179adf 100644 --- a/eos/tasks/task_executor.py +++ b/eos/tasks/task_executor.py @@ -224,7 +224,7 @@ def _ray_execute_task( ) -> tuple: task = task_class_type(_experiment_id, _task_id) devices = DeviceActorWrapperRegistry(_devices_actor_references) - return task.execute(devices, _parameters, _containers) + return asyncio.run(task.execute(devices, _parameters, _containers)) await self._task_manager.start_task(experiment_id, task_id) log.info(f"EXP '{experiment_id}' - Started task '{task_id}'.") diff --git a/tests/fixtures.py b/tests/fixtures.py index 1506b0b..9d60593 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -166,7 +166,7 @@ async def task_manager(setup_lab_experiment, configuration_manager, db_interface @pytest.fixture(scope="session", autouse=True) def ray_cluster(): - ray.init(namespace="test-eos", ignore_reinit_error=True, resources={"eos-core": 1}) + ray.init(namespace="test-eos", ignore_reinit_error=True, resources={"eos-core": 1000}) yield ray.shutdown() diff --git a/tests/test_base_device.py b/tests/test_base_device.py index 9404ead..e1a5cc1 100644 --- a/tests/test_base_device.py +++ b/tests/test_base_device.py @@ -2,89 +2,99 @@ from unittest.mock import Mock import pytest -import ray from eos.devices.base_device import BaseDevice, DeviceStatus from eos.devices.exceptions import EosDeviceError, EosDeviceCleanupError, EosDeviceInitializationError class MockDevice(BaseDevice): - def __init__(self, device_id: str, lab_id: str, device_type: str, initialization_parameters: dict[str, Any]): + def __init__(self, device_id: str, lab_id: str, device_type: str): self.mock_resource = None - super().__init__(device_id, lab_id, device_type, initialization_parameters) + super().__init__(device_id, lab_id, device_type) - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: self.mock_resource = Mock() - def _cleanup(self) -> None: + async def _cleanup(self) -> None: if self.mock_resource: self.mock_resource.close() self.mock_resource = None - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: return {"mock_resource": str(self.mock_resource)} def raise_exception(self): - raise ValueError("Test exception") + raise EosDeviceError("Test exception") class TestBaseDevice: @pytest.fixture - def mock_device(self): - return MockDevice("test_device", "test_lab", "mock", {}) + async def mock_device(self): + mock_device = MockDevice("test_device", "test_lab", "mock") + await mock_device.initialize({}) + return mock_device def test_initialize(self, mock_device): assert mock_device.id == "test_device" - assert mock_device.type == "mock" + assert mock_device.device_type == "mock" assert mock_device.status == DeviceStatus.IDLE assert mock_device.mock_resource is not None - def test_cleanup(self, mock_device): - mock_device.cleanup() + @pytest.mark.asyncio + async def test_cleanup(self, mock_device): + await mock_device.cleanup() assert mock_device.status == DeviceStatus.DISABLED assert mock_device.mock_resource is None - def test_enable_disable(self, mock_device): - mock_device.disable() + @pytest.mark.asyncio + async def test_enable_disable(self, mock_device): + await mock_device.disable() assert mock_device.status == DeviceStatus.DISABLED - mock_device.enable() + await mock_device.enable() assert mock_device.status == DeviceStatus.IDLE - def test_report(self, mock_device): - report = mock_device.report() + @pytest.mark.asyncio + async def test_report(self, mock_device): + report = await mock_device.report() assert "mock_resource" in report - def test_report_status(self, mock_device): - status_report = mock_device.report_status() + def test_get_status(self, mock_device): + status_report = mock_device.get_status() assert status_report["id"] == "test_device" assert status_report["status"] == DeviceStatus.IDLE def test_exception_handling(self, mock_device): with pytest.raises(EosDeviceError): mock_device.raise_exception() - assert mock_device.status == DeviceStatus.ERROR - def test_initialization_error(self): + @pytest.mark.asyncio + async def test_initialization_error(self): class FailingDevice(MockDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: raise ValueError("Initialization failed") + device = FailingDevice("fail_device", "test_lab", "failing") with pytest.raises(EosDeviceInitializationError): - FailingDevice("fail_device", "test_lab", "failing", {}) + await device.initialize({}) - def test_cleanup_error(self, mock_device): + @pytest.mark.asyncio + async def test_cleanup_error(self, mock_device): mock_device.mock_resource.close.side_effect = Exception("Cleanup failed") with pytest.raises(EosDeviceError): - mock_device.cleanup() + await mock_device.cleanup() + mock_device.mock_resource.close.side_effect = None assert mock_device.status == DeviceStatus.ERROR - def test_busy_status_cleanup(self, mock_device): + @pytest.mark.asyncio + async def test_busy_status_cleanup(self, mock_device): mock_device._status = DeviceStatus.BUSY with pytest.raises(EosDeviceCleanupError): - mock_device.cleanup() + await mock_device.cleanup() assert mock_device.status == DeviceStatus.BUSY + mock_device._status = DeviceStatus.IDLE - def test_double_initialization(self, mock_device): + @pytest.mark.asyncio + async def test_double_initialization(self, mock_device): with pytest.raises(EosDeviceInitializationError): - mock_device.initialize({}) + await mock_device.initialize({}) assert mock_device.status == DeviceStatus.IDLE diff --git a/tests/test_base_task.py b/tests/test_base_task.py index 03f9cbe..d515ef9 100644 --- a/tests/test_base_task.py +++ b/tests/test_base_task.py @@ -9,7 +9,7 @@ class ConcreteTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, containers: BaseTask.ContainersType ) -> BaseTask.OutputType | None: return {"out_param": parameters["param1"]}, {"container1": containers["container1"]}, {"file": b"content"} @@ -29,12 +29,13 @@ def test_init(self): assert task._experiment_id == "exp_id" assert task._task_id == "task_id" - def test_execute_success(self, concrete_task, container): + @pytest.mark.asyncio + async def test_execute_success(self, concrete_task, container): devices = {"device1": Mock(spec=DeviceActorWrapperRegistry)} parameters = {"param1": "value1"} containers = {"container1": container} - result = concrete_task.execute(devices, parameters, containers) + result = await concrete_task.execute(devices, parameters, containers) assert isinstance(result, tuple) assert len(result) == 3 @@ -45,9 +46,10 @@ def test_execute_success(self, concrete_task, container): assert result[1] == {"container1": container} assert result[2] == {"file": b"content"} - def test_execute_failure(self, container): + @pytest.mark.asyncio + async def test_execute_failure(self, container): class FailingTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -61,11 +63,12 @@ def _execute( failing_task = FailingTask("exp_id", "task_id") with pytest.raises(EosTaskExecutionError): - failing_task.execute(devices, parameters, containers) + await failing_task.execute(devices, parameters, containers) - def test_execute_empty_output(self, concrete_task): + @pytest.mark.asyncio + async def test_execute_empty_output(self, concrete_task): class EmptyOutputTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -74,13 +77,14 @@ def _execute( return None task = EmptyOutputTask("exp_id", "task_id") - result = task.execute({}, {}, {}) + result = await task.execute({}, {}, {}) assert result == ({}, {}, {}) - def test_execute_partial_output(self, concrete_task): + @pytest.mark.asyncio + async def test_execute_partial_output(self, concrete_task): class PartialOutputTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -89,13 +93,14 @@ def _execute( return {"out_param": "value"}, None, None task = PartialOutputTask("exp_id", "task_id") - result = task.execute({}, {}, {}) + result = await task.execute({}, {}, {}) assert result == ({"out_param": "value"}, {}, {}) - def test_automatic_input_container_passthrough(self, concrete_task, container): + @pytest.mark.asyncio + async def test_automatic_input_container_passthrough(self, concrete_task, container): class InputContainerPassthroughTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -104,6 +109,6 @@ def _execute( return None task = InputContainerPassthroughTask("exp_id", "task_id") - result = task.execute({}, {}, {"container1": container}) + result = await task.execute({}, {}, {"container1": container}) assert result == ({}, {"container1": container}, {}) diff --git a/tests/user/testing/devices/abstract_lab/DT1/device.py b/tests/user/testing/devices/abstract_lab/DT1/device.py index 611920d..baaec86 100644 --- a/tests/user/testing/devices/abstract_lab/DT1/device.py +++ b/tests/user/testing/devices/abstract_lab/DT1/device.py @@ -4,11 +4,11 @@ class DT1Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/abstract_lab/DT2/device.py b/tests/user/testing/devices/abstract_lab/DT2/device.py index ba688c5..ca9c76b 100644 --- a/tests/user/testing/devices/abstract_lab/DT2/device.py +++ b/tests/user/testing/devices/abstract_lab/DT2/device.py @@ -4,11 +4,11 @@ class DT2Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/abstract_lab/DT3/device.py b/tests/user/testing/devices/abstract_lab/DT3/device.py index 04ebc26..ee3f5d0 100644 --- a/tests/user/testing/devices/abstract_lab/DT3/device.py +++ b/tests/user/testing/devices/abstract_lab/DT3/device.py @@ -4,11 +4,11 @@ class DT3Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/abstract_lab/DT4/device.py b/tests/user/testing/devices/abstract_lab/DT4/device.py index 5eaecef..35e2d98 100644 --- a/tests/user/testing/devices/abstract_lab/DT4/device.py +++ b/tests/user/testing/devices/abstract_lab/DT4/device.py @@ -4,11 +4,11 @@ class DT4Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/abstract_lab/DT5/device.py b/tests/user/testing/devices/abstract_lab/DT5/device.py index 6ab25e4..1e335b6 100644 --- a/tests/user/testing/devices/abstract_lab/DT5/device.py +++ b/tests/user/testing/devices/abstract_lab/DT5/device.py @@ -4,11 +4,11 @@ class DT5Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/abstract_lab/DT6/device.py b/tests/user/testing/devices/abstract_lab/DT6/device.py index ac2ab08..f929fff 100644 --- a/tests/user/testing/devices/abstract_lab/DT6/device.py +++ b/tests/user/testing/devices/abstract_lab/DT6/device.py @@ -4,11 +4,11 @@ class DT6Device(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/multiplication_lab/analyzer/device.py b/tests/user/testing/devices/multiplication_lab/analyzer/device.py index 0bbbd3f..1542391 100644 --- a/tests/user/testing/devices/multiplication_lab/analyzer/device.py +++ b/tests/user/testing/devices/multiplication_lab/analyzer/device.py @@ -4,13 +4,13 @@ class AnalyzerDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass def analyze_result(self, number: int, product: int) -> int: diff --git a/tests/user/testing/devices/multiplication_lab/multiplier/device.py b/tests/user/testing/devices/multiplication_lab/multiplier/device.py index 33ed2ba..8ad0af9 100644 --- a/tests/user/testing/devices/multiplication_lab/multiplier/device.py +++ b/tests/user/testing/devices/multiplication_lab/multiplier/device.py @@ -4,13 +4,13 @@ class MultiplierDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass def multiply(self, a: int, b: int) -> int: diff --git a/tests/user/testing/devices/small_lab/computer/device.py b/tests/user/testing/devices/small_lab/computer/device.py index 5fd44c4..b9b145d 100644 --- a/tests/user/testing/devices/small_lab/computer/device.py +++ b/tests/user/testing/devices/small_lab/computer/device.py @@ -4,11 +4,11 @@ class ComputerDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/small_lab/evaporator/device.py b/tests/user/testing/devices/small_lab/evaporator/device.py index ceec58c..e66527e 100644 --- a/tests/user/testing/devices/small_lab/evaporator/device.py +++ b/tests/user/testing/devices/small_lab/evaporator/device.py @@ -4,11 +4,11 @@ class EvaporatorDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/small_lab/fridge/device.py b/tests/user/testing/devices/small_lab/fridge/device.py index e818aad..b436246 100644 --- a/tests/user/testing/devices/small_lab/fridge/device.py +++ b/tests/user/testing/devices/small_lab/fridge/device.py @@ -4,11 +4,11 @@ class FridgeDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/devices/small_lab/magnetic_mixer/device.py b/tests/user/testing/devices/small_lab/magnetic_mixer/device.py index 68f2cae..44c1693 100644 --- a/tests/user/testing/devices/small_lab/magnetic_mixer/device.py +++ b/tests/user/testing/devices/small_lab/magnetic_mixer/device.py @@ -4,11 +4,11 @@ class MagneticMixerDevice(BaseDevice): - def _initialize(self, initialization_parameters: dict[str, Any]) -> None: + async def _initialize(self, initialization_parameters: dict[str, Any]) -> None: pass - def _cleanup(self) -> None: + async def _cleanup(self) -> None: pass - def _report(self) -> dict[str, Any]: + async def _report(self) -> dict[str, Any]: pass diff --git a/tests/user/testing/tasks/file_generation_task/task.py b/tests/user/testing/tasks/file_generation_task/task.py index 8e7a945..7052bd2 100644 --- a/tests/user/testing/tasks/file_generation_task/task.py +++ b/tests/user/testing/tasks/file_generation_task/task.py @@ -4,7 +4,7 @@ class FileGenerationTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -13,6 +13,7 @@ def _execute( content_length = parameters["content_length"] file_content = "".join( - random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=content_length)) + random.choices("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", k=content_length) + ) return None, None, {"file.txt": bytes(file_content, "utf-8")} diff --git a/tests/user/testing/tasks/fridge_temperature_control/task.py b/tests/user/testing/tasks/fridge_temperature_control/task.py index 9f03dfe..5c6cf26 100644 --- a/tests/user/testing/tasks/fridge_temperature_control/task.py +++ b/tests/user/testing/tasks/fridge_temperature_control/task.py @@ -2,7 +2,7 @@ class FridgeTemperatureControlTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/gc_analysis/task.py b/tests/user/testing/tasks/gc_analysis/task.py index 8758504..eb8fa0f 100644 --- a/tests/user/testing/tasks/gc_analysis/task.py +++ b/tests/user/testing/tasks/gc_analysis/task.py @@ -2,7 +2,7 @@ class GcAnalysisTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/gc_injection/task.py b/tests/user/testing/tasks/gc_injection/task.py index 0142ce0..98c5b7e 100644 --- a/tests/user/testing/tasks/gc_injection/task.py +++ b/tests/user/testing/tasks/gc_injection/task.py @@ -2,7 +2,7 @@ class GcInjectionTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/hplc_analysis/task.py b/tests/user/testing/tasks/hplc_analysis/task.py index 2394be2..a898eae 100644 --- a/tests/user/testing/tasks/hplc_analysis/task.py +++ b/tests/user/testing/tasks/hplc_analysis/task.py @@ -2,7 +2,7 @@ class HplcAnalysisTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/magnetic_mixing/task.py b/tests/user/testing/tasks/magnetic_mixing/task.py index b76877a..ac8fdee 100644 --- a/tests/user/testing/tasks/magnetic_mixing/task.py +++ b/tests/user/testing/tasks/magnetic_mixing/task.py @@ -2,7 +2,7 @@ class MagneticMixingTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/multiplication_lab/compute_multiplication_objective/task.py b/tests/user/testing/tasks/multiplication_lab/compute_multiplication_objective/task.py index 6dc8863..0ea7e3a 100644 --- a/tests/user/testing/tasks/multiplication_lab/compute_multiplication_objective/task.py +++ b/tests/user/testing/tasks/multiplication_lab/compute_multiplication_objective/task.py @@ -2,7 +2,7 @@ class ComputeMultiplicationObjectiveTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/multiplication_lab/multiplication/task.py b/tests/user/testing/tasks/multiplication_lab/multiplication/task.py index d40b1e3..cdfa745 100644 --- a/tests/user/testing/tasks/multiplication_lab/multiplication/task.py +++ b/tests/user/testing/tasks/multiplication_lab/multiplication/task.py @@ -2,7 +2,7 @@ class MultiplicationTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/noop/task.py b/tests/user/testing/tasks/noop/task.py index 205eb0c..013ea1c 100644 --- a/tests/user/testing/tasks/noop/task.py +++ b/tests/user/testing/tasks/noop/task.py @@ -2,7 +2,7 @@ class NoopTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/purification/task.py b/tests/user/testing/tasks/purification/task.py index 6518b8c..5d6fe80 100644 --- a/tests/user/testing/tasks/purification/task.py +++ b/tests/user/testing/tasks/purification/task.py @@ -2,7 +2,7 @@ class PurificationTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/robot_arm_container_transfer/task.py b/tests/user/testing/tasks/robot_arm_container_transfer/task.py index d1f04c3..7ca83ff 100644 --- a/tests/user/testing/tasks/robot_arm_container_transfer/task.py +++ b/tests/user/testing/tasks/robot_arm_container_transfer/task.py @@ -2,7 +2,7 @@ class RobotArmContainerTransferTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/sleep/task.py b/tests/user/testing/tasks/sleep/task.py index 190d35b..a5256d4 100644 --- a/tests/user/testing/tasks/sleep/task.py +++ b/tests/user/testing/tasks/sleep/task.py @@ -1,10 +1,11 @@ +import asyncio import time from eos.tasks.base_task import BaseTask class SleepTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, @@ -20,7 +21,7 @@ def _execute( if self.cancel_requested: self.cancel_requested = False return None - time.sleep(1) + await asyncio.sleep(1) elapsed = time.time() - start_time return None diff --git a/tests/user/testing/tasks/wafer_sampling/task.py b/tests/user/testing/tasks/wafer_sampling/task.py index 6c3b588..3fc993d 100644 --- a/tests/user/testing/tasks/wafer_sampling/task.py +++ b/tests/user/testing/tasks/wafer_sampling/task.py @@ -2,7 +2,7 @@ class WaferSamplingTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType, diff --git a/tests/user/testing/tasks/weigh_container/task.py b/tests/user/testing/tasks/weigh_container/task.py index eb4c93b..a8d1870 100644 --- a/tests/user/testing/tasks/weigh_container/task.py +++ b/tests/user/testing/tasks/weigh_container/task.py @@ -2,7 +2,7 @@ class WeighContainerTask(BaseTask): - def _execute( + async def _execute( self, devices: BaseTask.DevicesType, parameters: BaseTask.ParametersType,