chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,688 @@
|
||||
# Copyright (C) CVAT.ai Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import io
|
||||
import json
|
||||
from http import HTTPStatus
|
||||
from urllib.parse import parse_qsl, urlparse
|
||||
|
||||
import pytest
|
||||
from cvat_sdk.api_client import ApiClient, models
|
||||
from cvat_sdk.api_client.api_client import Endpoint
|
||||
from cvat_sdk.core.helpers import get_paginated_collection
|
||||
|
||||
from shared.fixtures.data import Container
|
||||
from shared.fixtures.init import docker_exec_redis_inmem, kube_exec_redis_inmem
|
||||
from shared.utils.config import make_api_client
|
||||
from shared.utils.helpers import generate_image_files
|
||||
|
||||
from .utils import (
|
||||
CollectionSimpleFilterTestBase,
|
||||
create_task,
|
||||
export_dataset,
|
||||
export_job_dataset,
|
||||
export_project_backup,
|
||||
export_project_dataset,
|
||||
export_task_backup,
|
||||
export_task_dataset,
|
||||
import_job_annotations,
|
||||
import_project_backup,
|
||||
import_project_dataset,
|
||||
import_task_annotations,
|
||||
import_task_backup,
|
||||
wait_background_request,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.timeout(60)
|
||||
@pytest.mark.usefixtures("restore_db_per_class")
|
||||
@pytest.mark.usefixtures("restore_redis_inmem_per_class")
|
||||
@pytest.mark.usefixtures("restore_redis_ondisk_per_class")
|
||||
class TestRequestsListFilters(CollectionSimpleFilterTestBase):
|
||||
# Org used for the org/org_id filter cases. Only the id is hardcoded;
|
||||
# the slug is derived from the `organizations` fixture at setup time.
|
||||
_ORG_ID = 2
|
||||
|
||||
field_lookups = {
|
||||
"target": ["operation", "target"],
|
||||
"subresource": ["operation", "type", lambda x: x.split(":")[1]],
|
||||
"action": ["operation", "type", lambda x: x.split(":")[0]],
|
||||
"project_id": ["operation", "project_id"],
|
||||
"task_id": ["operation", "task_id"],
|
||||
"job_id": ["operation", "job_id"],
|
||||
"format": ["operation", "format"],
|
||||
"org_id": ["operation", "org_id"],
|
||||
}
|
||||
|
||||
def _get_endpoint(self, api_client: ApiClient) -> Endpoint:
|
||||
return api_client.requests_api.list_endpoint
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def setup_user(cls, restore_db_per_class, find_users):
|
||||
cls.user = find_users(privilege="user")[0]["username"]
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def setup_org_users(cls, restore_db_per_class, find_users, organizations, memberships):
|
||||
cls.org_slug = next(o["slug"] for o in organizations if o["id"] == cls._ORG_ID)
|
||||
# Pick an owner/maintainer so they can create projects/tasks in the org.
|
||||
cls.org_user = next(
|
||||
find_users(id=m["user"]["id"])[0]["username"]
|
||||
for m in memberships
|
||||
if m["organization"] == cls._ORG_ID
|
||||
and m["user"]
|
||||
and m["role"] in ("owner", "maintainer")
|
||||
)
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_resources_ids(
|
||||
cls, setup_user, restore_redis_inmem_per_class, restore_redis_ondisk_per_class
|
||||
):
|
||||
with make_api_client(cls.user) as api_client:
|
||||
project_ids = [
|
||||
api_client.projects_api.create(
|
||||
{"name": f"Test project {idx + 1}", "labels": [{"name": "car"}]}
|
||||
)[0].id
|
||||
for idx in range(3)
|
||||
]
|
||||
|
||||
task_ids = [
|
||||
create_task(
|
||||
cls.user,
|
||||
spec={"name": f"Test task {idx + 1}"},
|
||||
data={
|
||||
"image_quality": 75,
|
||||
"client_files": generate_image_files(2),
|
||||
"segment_size": 1,
|
||||
},
|
||||
)[0]
|
||||
for idx in range(3)
|
||||
]
|
||||
|
||||
job_ids = []
|
||||
for task_id in task_ids:
|
||||
jobs, _ = api_client.jobs_api.list(task_id=task_id)
|
||||
job_ids.extend([j.id for j in jobs.results])
|
||||
|
||||
return project_ids, task_ids, job_ids
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_make_requests(
|
||||
cls,
|
||||
setup_user,
|
||||
fxt_make_export_project_requests,
|
||||
fxt_make_export_task_requests,
|
||||
fxt_make_export_job_requests,
|
||||
fxt_download_file,
|
||||
):
|
||||
def _make_requests(project_ids: list[int], task_ids: list[int], job_ids: list[int]):
|
||||
# make requests to export projects|tasks|jobs annotations|datasets|backups
|
||||
fxt_make_export_project_requests(project_ids[1:])
|
||||
fxt_make_export_task_requests(task_ids[1:])
|
||||
fxt_make_export_job_requests(job_ids[1:])
|
||||
|
||||
# make requests to download files and then import them
|
||||
for resource_type, first_resource in zip(
|
||||
("project", "task", "job"), (project_ids[0], task_ids[0], job_ids[0])
|
||||
):
|
||||
for subresource in ("dataset", "annotations", "backup"):
|
||||
if resource_type == "job" and subresource == "backup":
|
||||
continue
|
||||
|
||||
data = fxt_download_file(resource_type, first_resource, subresource)
|
||||
|
||||
tmp_file = io.BytesIO(data)
|
||||
tmp_file.name = f"{resource_type}_{subresource}.zip"
|
||||
|
||||
if resource_type == "task" and subresource == "backup":
|
||||
import_task_backup(
|
||||
cls.user,
|
||||
file_content=tmp_file,
|
||||
)
|
||||
|
||||
empty_file = io.BytesIO(b"empty_file")
|
||||
empty_file.name = "empty.zip"
|
||||
|
||||
# import corrupted backup
|
||||
import_task_backup(
|
||||
cls.user,
|
||||
file_content=empty_file,
|
||||
)
|
||||
|
||||
return _make_requests
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_download_file(cls, setup_user):
|
||||
def download_file(resource: str, rid: int, subresource: str):
|
||||
func = {
|
||||
("project", "dataset"): lambda *args, **kwargs: export_project_dataset(
|
||||
*args, **kwargs, save_images=True
|
||||
),
|
||||
("project", "annotations"): lambda *args, **kwargs: export_project_dataset(
|
||||
*args, **kwargs, save_images=False
|
||||
),
|
||||
("project", "backup"): export_project_backup,
|
||||
("task", "dataset"): lambda *args, **kwargs: export_task_dataset(
|
||||
*args, **kwargs, save_images=True
|
||||
),
|
||||
("task", "annotations"): lambda *args, **kwargs: export_task_dataset(
|
||||
*args, **kwargs, save_images=False
|
||||
),
|
||||
("task", "backup"): export_task_backup,
|
||||
("job", "dataset"): lambda *args, **kwargs: export_job_dataset(
|
||||
*args, **kwargs, save_images=True
|
||||
),
|
||||
("job", "annotations"): lambda *args, **kwargs: export_job_dataset(
|
||||
*args, **kwargs, save_images=False
|
||||
),
|
||||
}[(resource, subresource)]
|
||||
|
||||
data = func(cls.user, id=rid, download_result=True)
|
||||
assert data, f"Failed to download {resource} {subresource} locally"
|
||||
return data
|
||||
|
||||
return download_file
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_make_export_project_requests(cls, setup_user):
|
||||
def make_requests(project_ids: list[int]):
|
||||
for project_id in project_ids:
|
||||
export_project_backup(cls.user, id=project_id, download_result=False)
|
||||
export_project_dataset(
|
||||
cls.user, save_images=True, id=project_id, download_result=False
|
||||
)
|
||||
export_project_dataset(
|
||||
cls.user,
|
||||
save_images=False,
|
||||
id=project_id,
|
||||
download_result=False,
|
||||
)
|
||||
|
||||
return make_requests
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_make_export_task_requests(cls, setup_user):
|
||||
def make_requests(task_ids: list[int]):
|
||||
for task_id in task_ids:
|
||||
export_task_backup(cls.user, id=task_id, download_result=False)
|
||||
export_task_dataset(cls.user, save_images=True, id=task_id, download_result=False)
|
||||
export_task_dataset(cls.user, save_images=False, id=task_id, download_result=False)
|
||||
|
||||
return make_requests
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_make_export_job_requests(cls, setup_user):
|
||||
def make_requests(job_ids: list[int]):
|
||||
for job_id in job_ids:
|
||||
export_job_dataset(
|
||||
cls.user,
|
||||
save_images=True,
|
||||
id=job_id,
|
||||
format="COCO 1.0",
|
||||
download_result=False,
|
||||
)
|
||||
export_job_dataset(
|
||||
cls.user,
|
||||
save_images=False,
|
||||
id=job_id,
|
||||
format="YOLO 1.1",
|
||||
download_result=False,
|
||||
)
|
||||
|
||||
return make_requests
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
@classmethod
|
||||
def fxt_org_resources(cls, setup_org_users):
|
||||
with make_api_client(cls.org_user) as api_client:
|
||||
api_client.set_default_header("X-Organization", cls.org_slug)
|
||||
cls.org_project_id = api_client.projects_api.create(
|
||||
{"name": "Org test project", "labels": [{"name": "car"}]},
|
||||
)[0].id
|
||||
cls.org_task_id = create_task(
|
||||
cls.org_user,
|
||||
spec={"name": "Org test task"},
|
||||
data={
|
||||
"image_quality": 75,
|
||||
"client_files": generate_image_files(2),
|
||||
"segment_size": 1,
|
||||
},
|
||||
org_id=cls._ORG_ID,
|
||||
)[0]
|
||||
export_dataset(
|
||||
api_client.projects_api,
|
||||
save_images=True,
|
||||
id=cls.org_project_id,
|
||||
download_result=False,
|
||||
)
|
||||
export_dataset(
|
||||
api_client.tasks_api,
|
||||
save_images=True,
|
||||
id=cls.org_task_id,
|
||||
download_result=False,
|
||||
)
|
||||
|
||||
@pytest.fixture(scope="class", autouse=True)
|
||||
@classmethod
|
||||
def setup(
|
||||
cls,
|
||||
setup_user,
|
||||
setup_org_users,
|
||||
fxt_resources_ids,
|
||||
fxt_make_requests,
|
||||
fxt_org_resources,
|
||||
):
|
||||
cls.project_ids, cls.task_ids, cls.job_ids = fxt_resources_ids
|
||||
fxt_make_requests(cls.project_ids, cls.task_ids, cls.job_ids)
|
||||
|
||||
def _get_field_samples(self, field):
|
||||
if field == "org":
|
||||
gt_objects = [
|
||||
s
|
||||
for s in self.samples
|
||||
if self._get_field(s, ["operation", "org_id"]) == self._ORG_ID
|
||||
]
|
||||
return self.org_slug, gt_objects
|
||||
return super()._get_field_samples(field)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"simple_filter, values",
|
||||
[
|
||||
("subresource", ["annotations", "dataset", "backup"]),
|
||||
("action", ["create", "export", "import"]),
|
||||
("status", ["finished", "failed"]),
|
||||
("project_id", []),
|
||||
("task_id", []),
|
||||
("job_id", []),
|
||||
("format", ["CVAT for images 1.1", "COCO 1.0", "YOLO 1.1"]),
|
||||
("target", ["project", "task", "job"]),
|
||||
("org_id", []),
|
||||
("org", []),
|
||||
],
|
||||
)
|
||||
def test_can_use_simple_filter_for_object_list(self, simple_filter: str, values: list):
|
||||
if simple_filter == "project_id":
|
||||
values = self.project_ids[-1:]
|
||||
elif simple_filter == "task_id":
|
||||
values = self.task_ids[-1:]
|
||||
elif simple_filter == "job_id":
|
||||
values = self.job_ids[-1:]
|
||||
elif simple_filter == "org_id":
|
||||
values = [self._ORG_ID]
|
||||
|
||||
with make_api_client(self.user) as api_client:
|
||||
self.samples = get_paginated_collection(
|
||||
self._get_endpoint(api_client), return_json=True
|
||||
)
|
||||
|
||||
return super()._test_can_use_simple_filter_for_object_list(simple_filter, values)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("restore_db_per_function")
|
||||
@pytest.mark.usefixtures("restore_redis_inmem_per_function")
|
||||
def test_list_requests_when_there_is_job_with_non_regular_or_corrupted_meta(
|
||||
jobs: Container, admin_user: str, request: pytest.FixtureRequest
|
||||
):
|
||||
job = next(j for j in jobs if j["media_type"] != "audio")
|
||||
|
||||
export_job_dataset(admin_user, save_images=True, id=job["id"], download_result=False)
|
||||
export_job_dataset(admin_user, save_images=False, id=job["id"], download_result=False)
|
||||
|
||||
with make_api_client(admin_user) as api_client:
|
||||
background_requests, response = api_client.requests_api.list(_check_status=False)
|
||||
assert response.status == HTTPStatus.OK
|
||||
assert 2 == background_requests.count
|
||||
|
||||
corrupted_job, normal_job = background_requests.results
|
||||
corrupted_job_key = f"rq:job:{corrupted_job['id']}"
|
||||
remove_meta_command = f'redis-cli -e HDEL "{corrupted_job_key}" meta'
|
||||
|
||||
if request.config.getoption("--platform") == "local":
|
||||
stdout = docker_exec_redis_inmem(["sh", "-c", remove_meta_command])
|
||||
else:
|
||||
stdout = kube_exec_redis_inmem(
|
||||
[
|
||||
"sh",
|
||||
"-c",
|
||||
'export REDISCLI_AUTH="${REDIS_PASSWORD}" && ' + remove_meta_command,
|
||||
]
|
||||
)
|
||||
assert bool(int(stdout.strip()))
|
||||
|
||||
_, response = api_client.requests_api.list(_check_status=False, _parse_response=False)
|
||||
assert response.status == HTTPStatus.OK
|
||||
|
||||
background_requests = json.loads(response.data)
|
||||
assert 1 == background_requests["count"]
|
||||
assert normal_job.id == background_requests["results"][0]["id"]
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("restore_db_per_class")
|
||||
@pytest.mark.usefixtures("restore_redis_inmem_per_function")
|
||||
class TestGetRequests:
|
||||
|
||||
def _test_get_request_200(
|
||||
self, api_client: ApiClient, rq_id: str, validate_rq_id: bool = True, **kwargs
|
||||
) -> models.Request:
|
||||
background_request, response = api_client.requests_api.retrieve(rq_id, **kwargs)
|
||||
assert response.status == HTTPStatus.OK
|
||||
|
||||
if validate_rq_id:
|
||||
assert background_request.id == rq_id
|
||||
|
||||
return background_request
|
||||
|
||||
def _test_get_request_403(self, api_client: ApiClient, rq_id: str):
|
||||
_, response = api_client.requests_api.retrieve(
|
||||
rq_id, _parse_response=False, _check_status=False
|
||||
)
|
||||
assert response.status == HTTPStatus.FORBIDDEN
|
||||
|
||||
@pytest.mark.parametrize("format_name", ("CVAT for images 1.1",))
|
||||
@pytest.mark.parametrize("save_images", (True, False))
|
||||
def test_owner_can_retrieve_request(self, format_name: str, save_images: bool, projects):
|
||||
project = next(
|
||||
p
|
||||
for p in projects
|
||||
if p["owner"] and (p["target_storage"] or {}).get("location") == "local"
|
||||
)
|
||||
owner = project["owner"]
|
||||
|
||||
subresource = "dataset" if save_images else "annotations"
|
||||
request_id = export_project_dataset(
|
||||
owner["username"],
|
||||
save_images=save_images,
|
||||
id=project["id"],
|
||||
download_result=False,
|
||||
format=format_name,
|
||||
)
|
||||
|
||||
with make_api_client(owner["username"]) as owner_client:
|
||||
bg_request = self._test_get_request_200(owner_client, request_id)
|
||||
|
||||
assert (
|
||||
bg_request.created_date
|
||||
< bg_request.started_date
|
||||
< bg_request.finished_date
|
||||
< bg_request.expiry_date
|
||||
)
|
||||
assert bg_request.operation.format == format_name
|
||||
assert bg_request.operation.project_id == project["id"]
|
||||
assert bg_request.operation.target == "project"
|
||||
assert bg_request.operation.task_id is None
|
||||
assert bg_request.operation.job_id is None
|
||||
assert bg_request.operation.type == f"export:{subresource}"
|
||||
assert bg_request.owner.id == owner["id"]
|
||||
assert bg_request.owner.username == owner["username"]
|
||||
|
||||
parsed_url = urlparse(bg_request.result_url)
|
||||
assert all([parsed_url.scheme, parsed_url.netloc, parsed_url.path, parsed_url.query])
|
||||
|
||||
def test_non_owner_cannot_retrieve_request(self, find_users, projects):
|
||||
project = next(
|
||||
p
|
||||
for p in projects
|
||||
if p["owner"] and (p["target_storage"] or {}).get("location") == "local"
|
||||
)
|
||||
owner = project["owner"]
|
||||
malefactor = find_users(exclude_username=owner["username"])[0]
|
||||
|
||||
request_id = export_project_dataset(
|
||||
owner["username"],
|
||||
save_images=True,
|
||||
id=project["id"],
|
||||
download_result=False,
|
||||
)
|
||||
with make_api_client(malefactor["username"]) as malefactor_client:
|
||||
self._test_get_request_403(malefactor_client, request_id)
|
||||
|
||||
def _test_get_request_using_legacy_id(
|
||||
self,
|
||||
legacy_request_id: str,
|
||||
username: str,
|
||||
*,
|
||||
action: str,
|
||||
target_type: str,
|
||||
subresource: str | None = None,
|
||||
):
|
||||
with make_api_client(username) as api_client:
|
||||
bg_requests, _ = api_client.requests_api.list(
|
||||
target=target_type,
|
||||
action=action,
|
||||
**({"subresource": subresource} if subresource else {}),
|
||||
)
|
||||
assert len(bg_requests.results) == 1
|
||||
request_id = bg_requests.results[0].id
|
||||
bg_request = self._test_get_request_200(
|
||||
api_client, legacy_request_id, validate_rq_id=False
|
||||
)
|
||||
assert bg_request.id == request_id
|
||||
|
||||
@pytest.mark.parametrize("target_type", ("project", "task", "job"))
|
||||
@pytest.mark.parametrize("save_images", (True, False))
|
||||
@pytest.mark.parametrize("export_format", ("CVAT for images 1.1",))
|
||||
@pytest.mark.parametrize("import_format", ("CVAT 1.1",))
|
||||
def test_can_retrieve_dataset_import_export_requests_using_legacy_ids(
|
||||
self,
|
||||
target_type: str,
|
||||
save_images: bool,
|
||||
export_format: str,
|
||||
import_format: str,
|
||||
projects,
|
||||
tasks,
|
||||
jobs,
|
||||
):
|
||||
def build_legacy_id_for_export_request(
|
||||
*,
|
||||
target_type: str,
|
||||
target_id: int,
|
||||
subresource: str,
|
||||
format_name: str,
|
||||
user_id: int,
|
||||
):
|
||||
return f"export:{target_type}-{target_id}-{subresource}-in-{format_name.replace(' ', '_').replace('.', '@')}-format-by-{user_id}"
|
||||
|
||||
def build_legacy_id_for_import_request(
|
||||
*,
|
||||
target_type: str,
|
||||
target_id: int,
|
||||
subresource: str,
|
||||
):
|
||||
return f"import:{target_type}-{target_id}-{subresource}"
|
||||
|
||||
if target_type == "project":
|
||||
export_func, import_func = export_project_dataset, import_project_dataset
|
||||
target = next(p for p in projects if p["dimension"] != "1d")
|
||||
owner = target["owner"]
|
||||
elif target_type == "task":
|
||||
export_func, import_func = export_task_dataset, import_task_annotations
|
||||
target = next(t for t in tasks if t["media_type"] != "audio")
|
||||
owner = target["owner"]
|
||||
else:
|
||||
assert target_type == "job"
|
||||
export_func, import_func = export_job_dataset, import_job_annotations
|
||||
target = next(j for j in jobs if j["media_type"] != "audio")
|
||||
owner = tasks[target["task_id"]]["owner"]
|
||||
|
||||
target_id = target["id"]
|
||||
subresource = "dataset" if save_images else "annotations"
|
||||
file_content = io.BytesIO(
|
||||
export_func(
|
||||
owner["username"],
|
||||
save_images=save_images,
|
||||
format=export_format,
|
||||
id=target_id,
|
||||
)
|
||||
)
|
||||
file_content.name = "file.zip"
|
||||
|
||||
legacy_request_id = build_legacy_id_for_export_request(
|
||||
target_type=target_type,
|
||||
target_id=target["id"],
|
||||
subresource=subresource,
|
||||
format_name=export_format,
|
||||
user_id=owner["id"],
|
||||
)
|
||||
|
||||
self._test_get_request_using_legacy_id(
|
||||
legacy_request_id,
|
||||
owner["username"],
|
||||
action="export",
|
||||
target_type=target_type,
|
||||
subresource=subresource,
|
||||
)
|
||||
|
||||
# check import requests
|
||||
if not save_images and target_type == "project" or save_images and target_type != "project":
|
||||
# skip:
|
||||
# importing annotations into a project
|
||||
# importing datasets into a task or job
|
||||
return
|
||||
|
||||
import_func(
|
||||
owner["username"],
|
||||
file_content=file_content,
|
||||
id=target_id,
|
||||
format=import_format,
|
||||
)
|
||||
|
||||
legacy_request_id = build_legacy_id_for_import_request(
|
||||
target_type=target_type, target_id=target_id, subresource=subresource
|
||||
)
|
||||
self._test_get_request_using_legacy_id(
|
||||
legacy_request_id,
|
||||
owner["username"],
|
||||
action="import",
|
||||
target_type=target_type,
|
||||
subresource=subresource,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("target_type", ("project", "task"))
|
||||
def test_can_retrieve_backup_import_export_requests_using_legacy_ids(
|
||||
self,
|
||||
target_type: str,
|
||||
projects,
|
||||
tasks,
|
||||
):
|
||||
def build_legacy_id_for_export_request(
|
||||
*,
|
||||
target_type: str,
|
||||
target_id: int,
|
||||
user_id: int,
|
||||
):
|
||||
return f"export:{target_type}-{target_id}-backup-by-{user_id}"
|
||||
|
||||
def build_legacy_id_for_import_request(
|
||||
*,
|
||||
target_type: str,
|
||||
uuid_: str,
|
||||
):
|
||||
return f"import:{target_type}-{uuid_}-backup"
|
||||
|
||||
if target_type == "project":
|
||||
export_func, import_func = export_project_backup, import_project_backup
|
||||
target = next(iter(projects))
|
||||
else:
|
||||
assert target_type == "task"
|
||||
export_func, import_func = export_task_backup, import_task_backup
|
||||
target = next(iter(tasks))
|
||||
|
||||
owner = target["owner"]
|
||||
|
||||
# check export requests
|
||||
backup_file = io.BytesIO(
|
||||
export_func(
|
||||
owner["username"],
|
||||
id=target["id"],
|
||||
)
|
||||
)
|
||||
backup_file.name = "file.zip"
|
||||
|
||||
legacy_request_id = build_legacy_id_for_export_request(
|
||||
target_type=target_type, target_id=target["id"], user_id=owner["id"]
|
||||
)
|
||||
self._test_get_request_using_legacy_id(
|
||||
legacy_request_id,
|
||||
owner["username"],
|
||||
action="export",
|
||||
target_type=target_type,
|
||||
subresource="backup",
|
||||
)
|
||||
|
||||
# check import requests
|
||||
result_id = import_func(
|
||||
owner["username"],
|
||||
file_content=backup_file,
|
||||
).id
|
||||
legacy_request_id = build_legacy_id_for_import_request(
|
||||
target_type=target_type, uuid_=dict(parse_qsl(result_id))["id"]
|
||||
)
|
||||
|
||||
self._test_get_request_using_legacy_id(
|
||||
legacy_request_id,
|
||||
owner["username"],
|
||||
action="import",
|
||||
target_type=target_type,
|
||||
subresource="backup",
|
||||
)
|
||||
|
||||
def test_can_retrieve_task_creation_requests_using_legacy_ids(self, admin_user: str):
|
||||
task_id = create_task(
|
||||
admin_user,
|
||||
spec={"name": "Test task"},
|
||||
data={
|
||||
"image_quality": 75,
|
||||
"client_files": generate_image_files(2),
|
||||
"segment_size": 1,
|
||||
},
|
||||
)[0]
|
||||
|
||||
legacy_request_id = f"create:task-{task_id}"
|
||||
self._test_get_request_using_legacy_id(
|
||||
legacy_request_id, admin_user, action="create", target_type="task"
|
||||
)
|
||||
|
||||
def test_can_retrieve_quality_calculation_requests_using_legacy_ids(self, jobs, tasks):
|
||||
gt_job = next(
|
||||
j
|
||||
for j in jobs
|
||||
if (
|
||||
j["type"] == "ground_truth"
|
||||
and j["stage"] == "acceptance"
|
||||
and j["state"] == "completed"
|
||||
)
|
||||
)
|
||||
task_id = gt_job["task_id"]
|
||||
owner = tasks[task_id]["owner"]
|
||||
|
||||
legacy_request_id = f"quality-check-task-{task_id}-user-{owner['id']}"
|
||||
|
||||
with make_api_client(owner["username"]) as api_client:
|
||||
# initiate quality report calculation
|
||||
_, response = api_client.quality_api.create_report(
|
||||
quality_report_create_request=models.QualityReportCreateRequest(task_id=task_id),
|
||||
_parse_response=False,
|
||||
)
|
||||
assert response.status == HTTPStatus.ACCEPTED
|
||||
request_id = json.loads(response.data)["rq_id"]
|
||||
|
||||
# get background request details using common request API
|
||||
bg_request = self._test_get_request_200(
|
||||
api_client, legacy_request_id, validate_rq_id=False
|
||||
)
|
||||
assert bg_request.id == request_id
|
||||
|
||||
# get quality report by legacy request ID using the deprecated API endpoint
|
||||
wait_background_request(api_client, request_id)
|
||||
api_client.quality_api.create_report(
|
||||
quality_report_create_request=models.QualityReportCreateRequest(task_id=task_id),
|
||||
rq_id=request_id,
|
||||
)
|
||||
Reference in New Issue
Block a user