Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions api/endpoints/job_update.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import datetime

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

Expand All @@ -24,7 +26,21 @@ def update_job_status(
db_job = job_crud.get_job(db, update.job_id)
if db_job is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)

# Update the status
db_job.status = update.status.value

# Update date_started when job is first pulled/started
if update.status == JobStates.pulled and db_job.date_started is None:
db_job.date_started = datetime.datetime.now(datetime.timezone.utc)

# Update date_finished when job reaches a terminal state
if (
update.status in [JobStates.finished, JobStates.error]
and db_job.date_finished is None
):
db_job.date_finished = datetime.datetime.now(datetime.timezone.utc)

if update.runtime_details:
db_job.runtime_details = (
(db_job.runtime_details or "") + "\n" + update.runtime_details
Expand Down
2 changes: 1 addition & 1 deletion api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Job(Base): # type: ignore
user_id = mapped_column(String, nullable=False)
user_email = mapped_column(String, nullable=True) # required for notifications
job_name = mapped_column(String)
date_created = mapped_column(DateTime, default=datetime.datetime.utcnow)
date_created = mapped_column(DateTime, default=lambda: datetime.datetime.now(datetime.timezone.utc))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please keep the current version

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted the date_created field to use the original datetime.utcnow as requested in commit 5a937fd.

date_started = mapped_column(DateTime)
date_finished = mapped_column(DateTime)
status = mapped_column(
Expand Down
135 changes: 135 additions & 0 deletions tests/integration/endpoints/test_job_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,138 @@ def test_finished_notification(
headers={"x-api-key": internal_api_key_secret},
)
mock_email_sender.send_email.assert_called_once()


def test_date_started_set_on_pulled_status(
client: TestClient,
db_session: Session,
internal_api_key_secret: str,
jobs: list[Job],
) -> None:
"""Test that date_started is set when job status changes to 'pulled'."""
job = jobs[0]
assert job.date_started is None # Initially no start date

response = client.put(
ENDPOINT,
json={"job_id": job.id, "status": "pulled"},
headers={"x-api-key": internal_api_key_secret},
)
assert response.status_code == 200

# Refresh job from database
db_session.refresh(job)
assert job.status == "pulled"
assert job.date_started is not None # Should now have a start date
assert job.date_finished is None # Should not have finished date yet


def test_date_started_not_overwritten(
client: TestClient,
db_session: Session,
internal_api_key_secret: str,
jobs: list[Job],
) -> None:
"""Test that date_started is not overwritten if already set."""
job = jobs[0]

# First update to 'pulled' to set date_started
client.put(
ENDPOINT,
json={"job_id": job.id, "status": "pulled"},
headers={"x-api-key": internal_api_key_secret},
)
db_session.refresh(job)
original_start_date = job.date_started
assert original_start_date is not None

# Update to another status and then back to pulled
client.put(
ENDPOINT,
json={"job_id": job.id, "status": "running"},
headers={"x-api-key": internal_api_key_secret},
)
client.put(
ENDPOINT,
json={"job_id": job.id, "status": "pulled"},
headers={"x-api-key": internal_api_key_secret},
)

db_session.refresh(job)
assert job.date_started == original_start_date # Should not change


def test_date_finished_set_on_finished_status(
client: TestClient,
db_session: Session,
internal_api_key_secret: str,
jobs: list[Job],
) -> None:
"""Test that date_finished is set when job status changes to 'finished'."""
job = jobs[0]
assert job.date_finished is None # Initially no finish date

response = client.put(
ENDPOINT,
json={"job_id": job.id, "status": "finished"},
headers={"x-api-key": internal_api_key_secret},
)
assert response.status_code == 200

# Refresh job from database
db_session.refresh(job)
assert job.status == "finished"
assert job.date_finished is not None # Should now have a finish date


def test_date_finished_set_on_error_status(
client: TestClient,
db_session: Session,
internal_api_key_secret: str,
jobs: list[Job],
) -> None:
"""Test that date_finished is set when job status changes to 'error'."""
job = jobs[0]
assert job.date_finished is None # Initially no finish date

response = client.put(
ENDPOINT,
json={"job_id": job.id, "status": "error"},
headers={"x-api-key": internal_api_key_secret},
)
assert response.status_code == 200

# Refresh job from database
db_session.refresh(job)
assert job.status == "error"
assert job.date_finished is not None # Should now have a finish date


def test_date_finished_not_overwritten(
client: TestClient,
db_session: Session,
internal_api_key_secret: str,
jobs: list[Job],
) -> None:
"""Test that date_finished is not overwritten if already set."""
job = jobs[0]

# First update to 'finished' to set date_finished
client.put(
ENDPOINT,
json={"job_id": job.id, "status": "finished"},
headers={"x-api-key": internal_api_key_secret},
)
db_session.refresh(job)
original_finish_date = job.date_finished
assert original_finish_date is not None

# Update to error status (should not overwrite date_finished)
client.put(
ENDPOINT,
json={"job_id": job.id, "status": "error"},
headers={"x-api-key": internal_api_key_secret},
)

db_session.refresh(job)
assert job.date_finished == original_finish_date # Should not change
Loading