mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
142 lines
5.1 KiB
Python
142 lines
5.1 KiB
Python
import tempfile
|
|
from typing import (
|
|
Callable,
|
|
List,
|
|
)
|
|
from unittest import SkipTest
|
|
from urllib.parse import (
|
|
urljoin,
|
|
urlparse,
|
|
)
|
|
|
|
import requests
|
|
|
|
from galaxy.files import (
|
|
ConfiguredFileSources,
|
|
ConfiguredFileSourcesConfig,
|
|
DictFileSourcesUserContext,
|
|
)
|
|
from galaxy.util.config_parsers import parse_allowlist_ips
|
|
from galaxy.util.drs import (
|
|
fetch_drs_to_file,
|
|
RetryOptions,
|
|
)
|
|
from galaxy_test.base.populators import DatasetPopulator
|
|
from ._framework import ApiTestCase
|
|
|
|
CONTENT = "My Cool DRS Data\n"
|
|
|
|
# DRS expects identical get/post for two main API entrypoints.
|
|
HTTP_METHODS: List[Callable[[str], requests.Response]] = [requests.get, requests.post]
|
|
|
|
CHECKSUM_TEST_SLEEP_TIME = 3.0
|
|
|
|
|
|
def user_context_fixture():
|
|
file_sources_config = ConfiguredFileSourcesConfig(fetch_url_allowlist=parse_allowlist_ips(["127.0.0.0/24"]))
|
|
file_sources = ConfiguredFileSources(file_sources_config, load_stock_plugins=True)
|
|
user_context = DictFileSourcesUserContext(
|
|
preferences={
|
|
"oidc|bearer_token": "IBearTokens",
|
|
},
|
|
file_sources=file_sources,
|
|
)
|
|
return user_context
|
|
|
|
|
|
class TestDrsApi(ApiTestCase):
|
|
dataset_populator: DatasetPopulator
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
|
|
|
def test_service_info(self):
|
|
api_url = self._url_join("ga4gh/drs/v1/service-info")
|
|
info_response = requests.get(api_url)
|
|
info_response.raise_for_status()
|
|
|
|
def test_404_on_private_datasets(self):
|
|
history_id = self.dataset_populator.new_history()
|
|
hda = self.dataset_populator.new_dataset(history_id, content=CONTENT, wait=True)
|
|
dataset_id = hda["id"]
|
|
drs_id = hda["drs_id"]
|
|
self.dataset_populator.make_private(history_id=history_id, dataset_id=dataset_id)
|
|
for method in HTTP_METHODS:
|
|
api_url = self._url_join(f"ga4gh/drs/v1/objects/{drs_id}")
|
|
show_response = method(api_url)
|
|
assert show_response.status_code == 403
|
|
|
|
def test_public_data_access(self):
|
|
history_id = self.dataset_populator.new_history()
|
|
hda = self.dataset_populator.new_dataset(history_id, content=CONTENT, wait=True)
|
|
drs_id = hda["drs_id"]
|
|
for method in HTTP_METHODS:
|
|
for _ in range(10):
|
|
api_url = self._url_join(f"ga4gh/drs/v1/objects/{drs_id}")
|
|
show_response = method(api_url)
|
|
show_response.raise_for_status()
|
|
if show_response.status_code != 202:
|
|
break
|
|
else:
|
|
import time
|
|
|
|
time.sleep(3)
|
|
response = show_response.json()
|
|
access_methods = response["access_methods"]
|
|
assert len(access_methods) > 0
|
|
access_method = access_methods[0]
|
|
assert access_method["type"].startswith("http")
|
|
access_url = access_method["access_url"]
|
|
url = access_url["url"]
|
|
headers_list = access_url.get("headers") or []
|
|
headers_as_dict = {}
|
|
for header_str in headers_list:
|
|
key, value = header_str.split(": ", 1)
|
|
headers_as_dict[key] = value
|
|
|
|
download_response = requests.get(url, headers=headers_as_dict)
|
|
download_response.raise_for_status()
|
|
assert download_response.text == CONTENT
|
|
|
|
def test_public_data_access_util_code(self):
|
|
history_id = self.dataset_populator.new_history()
|
|
hda = self.dataset_populator.new_dataset(history_id, content=CONTENT, wait=True)
|
|
drs_id = hda["drs_id"]
|
|
components = urlparse(self.url)
|
|
netloc = components.netloc
|
|
scheme = components.scheme
|
|
if components.path != "/":
|
|
raise SkipTest("Real DRS cannot be served on Galaxy not hosted at root.")
|
|
drs_uri = f"drs://{netloc}/{drs_id}"
|
|
force_http = scheme == "http"
|
|
with tempfile.NamedTemporaryFile(prefix="gxtest_drs") as tf:
|
|
retry_options = RetryOptions()
|
|
retry_options.override_retry_after = CHECKSUM_TEST_SLEEP_TIME
|
|
fetch_drs_to_file(
|
|
drs_uri,
|
|
tf.name,
|
|
user_context=user_context_fixture(),
|
|
force_http=force_http,
|
|
retry_options=retry_options,
|
|
)
|
|
with open(tf.name) as f:
|
|
assert CONTENT == f.read()
|
|
|
|
def test_exception_handling_schema(self):
|
|
history_id = self.dataset_populator.new_history()
|
|
hda = self.dataset_populator.new_dataset(history_id, content=CONTENT, wait=True)
|
|
drs_id = hda["drs_id"]
|
|
|
|
for method in HTTP_METHODS:
|
|
api_url = self._url_join(f"ga4gh/drs/v1/objects/{drs_id}/access/fakeid")
|
|
error_response = method(api_url)
|
|
assert isinstance(error_response.status_code, int)
|
|
assert error_response.status_code == 404
|
|
error_as_dict = error_response.json()
|
|
assert "status_code" in error_as_dict
|
|
assert "msg" in error_as_dict
|
|
|
|
def _url_join(self, suffix):
|
|
return urljoin(self.url, suffix)
|