diff --git a/lapis/drone.py b/lapis/drone.py
index 7126242..0e6845a 100644
--- a/lapis/drone.py
+++ b/lapis/drone.py
@@ -127,7 +127,7 @@ class Drone(interfaces.Pool):
 
             self._utilisation = self._allocation = None
 
-            job_execution = scope.do(job.run())
+            job_execution = scope.do(job.run(self))
             self.jobs += 1
             try:
                 async with self.resources.claim(
@@ -154,7 +154,6 @@ class Drone(interfaces.Pool):
                 await instant
                 job_execution.cancel()
             self.jobs -= 1
-            job.drone = None
             await self.scheduler.job_finished(job)
             self._utilisation = self._allocation = None
             self.scheduler.update_drone(self)
diff --git a/lapis/job.py b/lapis/job.py
index 934ceee..c4627e0 100644
--- a/lapis/job.py
+++ b/lapis/job.py
@@ -91,18 +91,23 @@ class Job(object):
             return self.in_queue_until - self.in_queue_since
         return float("Inf")
 
-    async def run(self):
+    async def run(self, drone: "Drone"):
+        assert drone, "Jobs cannot run without a drone being assigned"
+        self.drone = drone
         self.in_queue_until = time.now
         self._success = None
         await sampling_required.put(self)
         try:
             await (time + self.walltime)
         except CancelTask:
+            self.drone = None
             self._success = False
         except BaseException:
+            self.drone = None
             self._success = False
             raise
         else:
+            self.drone = None
             self._success = True
         await sampling_required.put(self)
 

Jobs can run without a drone being assigned
Apparently jobs can run although not being properly assigned to a drone. We should take care that this cannot happen.

See:

> This happens in the unit tests... Same with the fileprovider in 
> https://github.com/tfesenbecker/lapis/blob/53ebec5ea004e4f031a0f70102276fe0102d62e4/lapis/job.py#L96

_Originally posted by @tfesenbecker in https://github.com/MatterMiners/lapis/pull/53_
diff --git a/lapis_tests/__init__.py b/lapis_tests/__init__.py
index d0c54e8..722b3a2 100644
--- a/lapis_tests/__init__.py
+++ b/lapis_tests/__init__.py
@@ -43,3 +43,7 @@ class DummyScheduler:
     @staticmethod
     def update_drone(drone: Drone):
         pass
+
+
+class DummyDrone:
+    pass
diff --git a/lapis_tests/test_job.py b/lapis_tests/test_job.py
index 3c75916..181bb1a 100644
--- a/lapis_tests/test_job.py
+++ b/lapis_tests/test_job.py
@@ -3,7 +3,7 @@ from usim import Scope, time
 
 from lapis.drone import Drone
 from lapis.job import Job
-from lapis_tests import via_usim, DummyScheduler
+from lapis_tests import via_usim, DummyScheduler, DummyDrone
 
 
 class TestJob(object):
@@ -27,10 +27,11 @@ class TestJob(object):
 
     @via_usim
     async def test_run_job(self):
+        drone = DummyDrone()
         job = Job(resources={"walltime": 50}, used_resources={"walltime": 10})
         assert float("inf") == job.waiting_time
         async with Scope() as scope:
-            scope.do(job.run())
+            scope.do(job.run(drone))
         assert 10 == time
         assert 0 == job.waiting_time
         assert job.successful

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest flake8
apt-get update apt-get install -y gcc
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==24.2.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cfgv==3.3.1
click==8.1.8
cobald==0.13.0
distlib==0.3.9
entrypoints==0.4
exceptiongroup==1.2.2
filelock==3.12.2
flake8==5.0.4
identify==2.5.24
idna==3.10
importlib-metadata==6.7.0
iniconfig==2.0.0
-e git+https://github.com/MatterMiners/lapis.git@5e10d37d054ff87da91010260ab8ab8da52614c0#egg=lapis_sim
mccabe==0.7.0
nodeenv==1.9.1
outcome==1.3.0.post0
packaging==24.0
platformdirs==4.0.0
pluggy==1.2.0
pre-commit==2.21.0
pycodestyle==2.9.1
pyflakes==2.5.0
pytest==7.4.4
PyYAML==6.0.1
sniffio==1.3.1
sortedcontainers==2.4.0
tomli==2.0.1
toposort==1.10
trio==0.22.2
typing_extensions==4.7.1
usim==0.4.0
virtualenv==20.26.6
zipp==3.15.0

name: lapis
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==24.2.0
      - cfgv==3.3.1
      - click==8.1.8
      - cobald==0.13.0
      - distlib==0.3.9
      - entrypoints==0.4
      - exceptiongroup==1.2.2
      - filelock==3.12.2
      - flake8==5.0.4
      - identify==2.5.24
      - idna==3.10
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - lapis-sim==0.3.0
      - mccabe==0.7.0
      - nodeenv==1.9.1
      - outcome==1.3.0.post0
      - packaging==24.0
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - pre-commit==2.21.0
      - pycodestyle==2.9.1
      - pyflakes==2.5.0
      - pytest==7.4.4
      - pyyaml==6.0.1
      - sniffio==1.3.1
      - sortedcontainers==2.4.0
      - tomli==2.0.1
      - toposort==1.10
      - trio==0.22.2
      - typing-extensions==4.7.1
      - usim==0.4.0
      - virtualenv==20.26.6
      - zipp==3.15.0
prefix: /opt/conda/envs/lapis

lapis_tests/test_job.py::TestJob::test_run_job
lapis_tests/test_job.py::TestJob::test_init lapis_tests/test_job.py::TestJob::test_name lapis_tests/test_job.py::TestJob::test_job_in_drone lapis_tests/test_job.py::TestJob::test_nonmatching_job_in_drone lapis_tests/test_job.py::TestJob::test_two_nonmatching_jobs lapis_tests/test_job.py::TestJob::test_two_matching_jobs
lapis/drone.py lapis/job.py
lapis/drone.py lapis/job.py