Skip to content

Commit

Permalink
Merge pull request #19108 from mvdbeek/access_public_history_in_job_c…
Browse files Browse the repository at this point in the history
…ache

Access public history in job cache / job search
  • Loading branch information
mvdbeek authored Nov 6, 2024
2 parents ec6831e + 360b72a commit d07b528
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 12 deletions.
10 changes: 10 additions & 0 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8753,6 +8753,11 @@ export interface components {
* @description The email of the user that owns this job. Only the owner of the job and administrators can see this value.
*/
user_email?: string | null;
/**
* User Id
* @description User ID of user that ran this job
*/
user_id?: string | null;
};
/** EncodedJobParameterHistoryItem */
EncodedJobParameterHistoryItem: {
Expand Down Expand Up @@ -16177,6 +16182,11 @@ export interface components {
* @description The email of the user that owns this job. Only the owner of the job and administrators can see this value.
*/
user_email?: string | null;
/**
* User Id
* @description User ID of user that ran this job
*/
user_id?: string | null;
};
/**
* Src
Expand Down
17 changes: 12 additions & 5 deletions lib/galaxy/managers/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,18 @@ def _build_job_subquery(
self, tool_id: str, user_id: int, tool_version: Optional[str], job_state, wildcard_param_dump
):
"""Build subquery that selects a job with correct job parameters."""
stmt = select(model.Job.id).where(
and_(
model.Job.tool_id == tool_id,
model.Job.user_id == user_id,
model.Job.copied_from_job_id.is_(None), # Always pick original job
stmt = (
select(model.Job.id)
.join(model.History, model.Job.history_id == model.History.id)
.where(
and_(
model.Job.tool_id == tool_id,
or_(
model.Job.user_id == user_id,
model.History.published == true(),
),
model.Job.copied_from_job_id.is_(None), # Always pick original job
)
)
)
if tool_version:
Expand Down
1 change: 1 addition & 0 deletions lib/galaxy/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1549,6 +1549,7 @@ class Job(Base, JobLike, UsesCreateAndUpdateTime, Dictifiable, Serializable):
"galaxy_version",
"command_version",
"copied_from_job_id",
"user_id",
]

_numeric_metric = JobMetricNumeric
Expand Down
1 change: 1 addition & 0 deletions lib/galaxy/schema/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ class EncodedJobDetails(JobSummary):
title="Output collections",
description="",
)
user_id: Optional[EncodedDatabaseIdField] = Field(default=None, description="User ID of user that ran this job")


class JobDestinationParams(Model):
Expand Down
43 changes: 37 additions & 6 deletions lib/galaxy_test/api/test_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
Any,
Dict,
List,
Optional,
)
from uuid import uuid4

import pytest
from requests import (
Expand Down Expand Up @@ -974,15 +976,19 @@ def test_run_cat1(self):
output1_content = self.dataset_populator.get_history_dataset_content(history_id, dataset=output1)
assert output1_content.strip() == "Cat1Test"

def _get_cat1_inputs(self, history_id):
new_dataset = self.dataset_populator.new_dataset(history_id, content="Cat1Test")
inputs = dict(
input1=dataset_to_param(new_dataset),
)
return inputs

@skip_without_tool("cat1")
@requires_new_history
def test_run_cat1_use_cached_job(self):
with self.dataset_populator.test_history_for(self.test_run_cat1_use_cached_job) as history_id:
# Run simple non-upload tool with an input data parameter.
new_dataset = self.dataset_populator.new_dataset(history_id, content="Cat1Test")
inputs = dict(
input1=dataset_to_param(new_dataset),
)
inputs = self._get_cat1_inputs(history_id)
outputs_one = self._run_cat1(history_id, inputs=inputs, assert_ok=True, wait_for_job=True)
outputs_two = self._run_cat1(
history_id, inputs=inputs, use_cached_job=False, assert_ok=True, wait_for_job=True
Expand All @@ -998,6 +1004,31 @@ def test_run_cat1_use_cached_job(self):
assert len(filenames) == 3, filenames
assert len(set(filenames)) <= 2, filenames

@skip_without_tool("cat1")
@requires_new_history
def test_run_cat1_use_cached_job_from_public_history(self):
with self.dataset_populator.test_history_for(self.test_run_cat1_use_cached_job) as history_id:
# Run simple non-upload tool with an input data parameter.
inputs = self._get_cat1_inputs(history_id)
original_output = self._run_cat1(history_id, inputs=inputs, assert_ok=True, wait_for_job=True)
original_job = self.dataset_populator.get_job_details(original_output["jobs"][0]["id"], full=True).json()

def run_again(user_email):
with self._different_user_and_history(user_email=user_email) as different_history_id:
cached_output = self._run_cat1(
different_history_id, inputs=inputs, use_cached_job=True, assert_ok=True, wait_for_job=True
)
return self.dataset_populator.get_job_details(cached_output["jobs"][0]["id"], full=True).json()

job = run_again(f"{uuid4()}@test.com")
assert job["user_id"] != original_job["user_id"]
assert not job["copied_from_job_id"]
# publish history, now we can use cached job
self.dataset_populator.make_public(history_id=history_id)
cached_job = run_again(f"{uuid4()}@test.com")
assert cached_job["user_id"] != original_job["user_id"]
assert cached_job["copied_from_job_id"] == original_output["jobs"][0]["id"]

@skip_without_tool("cat1")
def test_run_cat1_listified_param(self):
with self.dataset_populator.test_history_for(self.test_run_cat1_listified_param) as history_id:
Expand Down Expand Up @@ -2809,8 +2840,8 @@ def _assert_dataset_permission_denied_response(self, response):
# assert "User does not have permission to use a dataset" in err_message, err_message

@contextlib.contextmanager
def _different_user_and_history(self):
with self._different_user():
def _different_user_and_history(self, user_email: Optional[str] = None):
with self._different_user(email=user_email):
with self.dataset_populator.test_history() as other_history_id:
yield other_history_id

Expand Down
3 changes: 2 additions & 1 deletion lib/galaxy_test/base/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def _setup_user_get_key(self, email, password=None):
return user, self._post(f"users/{user['id']}/api_key", admin=True).json()

@contextmanager
def _different_user(self, email=OTHER_USER, anon=False):
def _different_user(self, email: Optional[str] = None, anon=False):
"""Use in test cases to switch get/post operations to act as new user
..code-block:: python
Expand All @@ -164,6 +164,7 @@ def _different_user(self, email=OTHER_USER, anon=False):
self.galaxy_interactor.cookies = cookies
new_key = None
else:
email = OTHER_USER if email is None else email
_, new_key = self._setup_user_get_key(email)
try:
self.user_api_key = new_key
Expand Down

0 comments on commit d07b528

Please sign in to comment.