diff --git a/setup.py b/setup.py index 1d17677..d529378 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ keywords="spinnaker allocation packing management supercomputer", # Requirements - install_requires=["rig", "six", "enum-compat", "inotify_simple"], + install_requires=["rig", "six", "enum-compat", "inotify_simple", "pytz"], # Scripts entry_points={ diff --git a/spalloc_server/controller.py b/spalloc_server/controller.py index dec63e6..ae23beb 100644 --- a/spalloc_server/controller.py +++ b/spalloc_server/controller.py @@ -14,6 +14,10 @@ import time +from datetime import datetime + +from pytz import utc + from rig.geometry import spinn5_chip_coord from spalloc_server.coordinates import \ @@ -1049,7 +1053,7 @@ class JobStateTuple(namedtuple("JobStateTuple", If the job has been destroyed, this may be a string describing the reason the job was terminated. start_time : float or None - The Unix time at which the job was created. + The Unix time (UTC) at which the job was created. """ # Python 3.4 Workaround: https://bugs.python.org/issue24931 @@ -1094,7 +1098,7 @@ class JobTuple(namedtuple("JobTuple", owner : str The string giving the name of the Job's owner. start_time : float - The time the job was created (Unix time) + The time the job was created (Unix time, UTC) keepalive : float or None The maximum time allowed between queries for this job before it is automatically destroyed (or None if the job can remain allocated @@ -1158,7 +1162,7 @@ class _Job(object): owner : str The job's owner. start_time : float - The time the job was created (Unix time) + The time the job was created (Unix time, UTC) keepalive : float or None The maximum time allowed between queries for this job before it is automatically destroyed (or None if the job can remain allocated @@ -1218,7 +1222,13 @@ def __init__(self, id, owner, self.id = id self.owner = owner - self.start_time = start_time if start_time is not None else time.time() + + if start_time is not None: # pragma: no branch + self.start_time = start_time # pragma: no cover + else: + now = datetime.now(utc) + epoch = datetime(1970, 1, 1, tzinfo=utc) + self.start_time = (now - epoch).total_seconds() # If None, never kill this job due to inactivity. Otherwise, stop the # job if the time exceeds this value. It is the allocator's diff --git a/spalloc_server/server.py b/spalloc_server/server.py index b06f6b6..e0813d7 100644 --- a/spalloc_server/server.py +++ b/spalloc_server/server.py @@ -626,8 +626,8 @@ def get_job_state(self, client, job_id): If the job has been destroyed, this may be a string describing the reason the job was terminated. start_time : float or None - For queued and allocated jobs, gives the Unix time at which the - job was created (or None otherwise). + For queued and allocated jobs, gives the Unix time (UTC) at + which the job was created (or None otherwise). """ out = self._controller.get_job_state(job_id)._asdict() out["state"] = int(out["state"]) @@ -849,7 +849,7 @@ def list_jobs(self, client): "owner" is the string giving the name of the Job's owner. - "start_time" is the time the job was created. + "start_time" is the time the job was created (Unix time, UTC). "keepalive" is the maximum time allowed between queries for this job before it is automatically destroyed (or None if the job can diff --git a/tests/test_controller.py b/tests/test_controller.py index dd8a65c..8827b6b 100644 --- a/tests/test_controller.py +++ b/tests/test_controller.py @@ -6,6 +6,10 @@ import time +from datetime import datetime + +from pytz import utc + from collections import OrderedDict from rig.links import Links @@ -641,8 +645,11 @@ def test_list_jobs(conn, m): assert jobs[0].owner == "me" assert jobs[1].owner == "you" - assert time.time() - 1.0 <= jobs[0].start_time <= time.time() - assert time.time() - 1.0 <= jobs[1].start_time <= time.time() + now = datetime.now(utc) + epoch = datetime(1970, 1, 1, tzinfo=utc) + unixtime_now = (now - epoch).total_seconds() + assert unixtime_now - 1.0 <= jobs[0].start_time <= unixtime_now + assert unixtime_now - 1.0 <= jobs[1].start_time <= unixtime_now assert jobs[0].keepalive == 60.0 assert jobs[1].keepalive is None