From 8989d6ab3968b6f3ed663ef94359ea0051b98a49 Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Fri, 12 Mar 2021 09:49:50 +0300 Subject: [PATCH 01/43] add tests --- .../tests/assets/annotations.json | 734 ++++++++++++++++++ .../tests/assets/tasks_for_formats.json | 83 ++ .../dataset_manager/tests/test_formats.py | 608 ++++++++++++++- 3 files changed, 1416 insertions(+), 9 deletions(-) create mode 100644 cvat/apps/dataset_manager/tests/assets/annotations.json create mode 100644 cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json new file mode 100644 index 00000000000..31936d36417 --- /dev/null +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -0,0 +1,734 @@ +{ + "CVAT for images 1.1": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [5.54, 3.5, 19.64, 11.19], + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": true, + "z_order": 0, + "points": [25.04, 13.7, 35.85, 20.2, 16.65, 19.8], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polyline", + "occluded": false, + "z_order": 1, + "points": [27.15, 26.7, 53.25, 24.8], + "frame": 0, + "label_id": null, + "group": 2, + "source": "manual", + "attributes": [] + }, + { + "type": "points", + "occluded": false, + "z_order": 1, + "points": [42.95, 33.59], + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "cuboid", + "occluded": false, + "z_order": 2, + "points": [ + 51.65, + 37.3, + 51.65, + 46.8, + 70.25, + 37.2, + 70.25, + 46.8, + 72.11, + 36.34, + 72.11, + 45.74, + 53.51, + 36.34, + 53.51, + 45.74 + ], + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "CVAT for video 1.1": { + "version": 0, + "tags": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [4.75, 4.8, 13.06, 11.39], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 1, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 1, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polyline", + "occluded": false, + "z_order": 1, + "points": [30.99, 31.37, 47.51, 26.94, 50.21, 22.73], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "points", + "occluded": false, + "z_order": 2, + "points": [59.82, 31.26], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 1, + "label_id": null, + "group": 2, + "source": "manual", + "shapes": [ + { + "type": "cuboid", + "occluded": false, + "z_order": 2, + "points": [ + 52.48, + 37.95, + 52.48, + 44.43, + 67.38, + 37.85, + 67.38, + 44.43, + 68.87, + 37.29, + 68.87, + 43.67, + 53.97, + 37.29, + 53.97, + 43.67 + ], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [65.65, 7.07, 78.83, 16.14], + "frame": 0, + "outside": false, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [65.65, 7.07, 78.83, 16.14], + "frame": 1, + "outside": true, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [65.65, 7.073, 78.83, 16.14], + "frame": 2, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "CamVid 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [83.0, 228.5, 69.5, 228.0, 69.0, 183.5, 164.5, 223.0, 164.0, 224.5, 83.0, 228.5], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "COCO 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [7.29, 8.58, 18.45, 19.22], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [27.03, 26.07, 63.94, 37.87, 18.34, 34.97], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "ImageNet 1.0": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [] + }, + "LabelMe 3.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [10.0, 8.79, 20.5, 15.69], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [35.0, 22.5, 53.32, 30.63, 22.34, 29.45], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "MOT 1.1": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [9.4, 12.09, 17.2, 18.19], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [10.5, 27.29, 23.3, 33.49], + "frame": 0, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "MOTS PNG 1.0": { + "version": 0, + "tags": [], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [19.4, 19.2, 41.7, 22.0, 38.8, 29.5, 21.5, 29.3], + "frame": 0, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "PASCAL VOC 1.1": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [9.4, 12.09, 17.2, 18.19], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "Segmentation mask 1.1": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [11.9, 21.5, 35.2, 21.9, 33.6, 31.9, 12.4, 30.47], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "TFRecord 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [16.5, 17.2, 38.89, 25.63], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "YOLO 1.1": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [8.3, 9.1, 19.2, 14.8], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "WiderFace 1.0": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [7.55, 9.75, 16.44, 15.85], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [3.55, 27.75, 11.33, 33.71], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "VGGFace2 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "points", + "occluded": false, + "z_order": 0, + "points": [28.05, 18.0, 36.65, 17.7, 36.85, 23.7, 26.95, 23.2, 30.35, 28.9], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [57.15, 20.9, 74.25, 32.0], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "Datumaro 1.0": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [5.54, 3.5, 19.64, 11.19], + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": true, + "z_order": 0, + "points": [25.04, 13.7, 35.85, 20.2, 16.65, 19.8], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polyline", + "occluded": false, + "z_order": 1, + "points": [27.15, 26.7, 53.25, 24.8], + "frame": 0, + "label_id": null, + "group": 2, + "source": "manual", + "attributes": [] + }, + { + "type": "points", + "occluded": false, + "z_order": 1, + "points": [42.95, 33.59], + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "cuboid", + "occluded": false, + "z_order": 2, + "points": [ + 51.65, + 37.3, + 51.65, + 46.8, + 70.25, + 37.2, + 70.25, + 46.8, + 72.11, + 36.34, + 72.11, + 45.74, + 53.51, + 36.34, + 53.51, + 45.74 + ], + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "CVAT for images 1.1 many jobs": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "frame": 8, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [5.54, 3.5, 19.64, 11.19], + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": true, + "z_order": 0, + "points": [25.04, 13.7, 35.85, 20.2, 16.65, 19.8], + "frame": 11, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "CVAT for video 1.1 many jobs": { + "version": 0, + "tags": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "frame": 8, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [4.75, 4.8, 13.06, 11.39], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 10, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + } +} diff --git a/cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json b/cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json new file mode 100644 index 00000000000..0f2dbc37643 --- /dev/null +++ b/cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json @@ -0,0 +1,83 @@ +{ + "main": { + "name": "main task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "car", + "color": "#2080c0", + "attributes": [ + { + "name": "select_name", + "mutable": false, + "input_type": "select", + "default_value": "bmw", + "values": ["bmw", "mazda", "renault"] + }, + { + "name": "radio_name", + "mutable": false, + "input_type": "radio", + "default_value": "x1", + "values": ["x1", "x2", "x3"] + }, + { + "name": "check_name", + "mutable": true, + "input_type": "checkbox", + "default_value": "false", + "values": ["false"] + }, + { + "name": "text_name", + "mutable": false, + "input_type": "text", + "default_value": "qwerty", + "values": ["qwerty"] + }, + { + "name": "number_name", + "mutable": false, + "input_type": "number", + "default_value": "-4", + "values": ["-4", "4", "1"] + } + ] + }, + { + "name": "person", + "color": "#c06060", + "attributes": [] + } + ] + }, + "no attributes": { + "name": "no attributes", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "labels": [ + { + "name": "car", + "color": "#2080c0", + "attributes": [] + } + ] + }, + "many jobs": { + "name": "many jobs", + "overlap": 0, + "segment_size": 5, + "owner_id": 1, + "labels": [ + { + "name": "car", + "color": "#2080c0", + "attributes": [] + } + ] + } +} diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 75ff51d01b4..1cd52b41aca 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -8,8 +8,14 @@ import os.path as osp import tempfile import zipfile +from unittest import skip +import copy +import json +import random +import xml.etree.ElementTree as ET import datumaro +from datumaro.util.test_utils import compare_datasets from PIL import Image from django.contrib.auth.models import User, Group from rest_framework.test import APITestCase, APIClient @@ -21,6 +27,13 @@ from cvat.apps.dataset_manager.task import TaskAnnotation from cvat.apps.engine.models import Task +path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') +with open(path) as f: + tasks = json.load(f) + +path = osp.join(osp.dirname(__file__), 'assets', 'annotations.json') +with open(path) as f: + annotations = json.load(f) def generate_image_file(filename, size=(100, 50)): f = BytesIO() @@ -56,30 +69,34 @@ def setUpTestData(cls): @classmethod def create_db_users(cls): - group, _ = Group.objects.get_or_create(name="adm") + (group_admin, _) = Group.objects.get_or_create(name="admin") + (group_user, _) = Group.objects.get_or_create(name="user") - admin = User.objects.create_superuser( - username="test", password="test", email="") - admin.groups.add(group) + user_admin = User.objects.create_superuser(username="admin", email="", + password="admin") + user_admin.groups.add(group_admin) + user_dummy = User.objects.create_user(username="user", password="user") + user_dummy.groups.add(group_user) - cls.user = admin + cls.admin = user_admin + cls.user = user_dummy def _put_api_v1_task_id_annotations(self, tid, data): - with ForceLogin(self.user, self.client): + with ForceLogin(self.admin, self.client): response = self.client.put("/api/v1/tasks/%s/annotations" % tid, data=data, format="json") return response def _put_api_v1_job_id_annotations(self, jid, data): - with ForceLogin(self.user, self.client): + with ForceLogin(self.admin, self.client): response = self.client.put("/api/v1/jobs/%s/annotations" % jid, data=data, format="json") return response def _create_task(self, data, image_data): - with ForceLogin(self.user, self.client): + with ForceLogin(self.admin, self.client): response = self.client.post('/api/v1/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] @@ -93,6 +110,81 @@ def _create_task(self, data, image_data): return task + def _get_request(self, path, user): + with ForceLogin(user, self.client): + response = self.client.get(path) + return response + + def _get_request_with_data(self, path, data, user): + with ForceLogin(user, self.client): + response = self.client.get(path, data) + return response + + def _delete_request(self, path, user): + with ForceLogin(user, self.client): + response = self.client.delete(path) + return response + + def _create_annotations(self, task, name_ann, key_get_values): + tmp_annotations = copy.deepcopy(annotations[name_ann]) + + # change attributes in all annotations + for item in tmp_annotations: + if item in ["tags", "shapes", "tracks"]: + for index_elem, elem in enumerate(tmp_annotations[item]): + tmp_annotations[item][index_elem]["label_id"] = task["labels"][0]["id"] + + for index_attribute, attribute in enumerate(task["labels"][0]["attributes"]): + spec_id = task["labels"][0]["attributes"][index_attribute]["id"] + + if key_get_values == "random": + if attribute["input_type"] == "number": + start = int(attribute["values"][0]) + stop = int(attribute["values"][1]) + 1 + step = int(attribute["values"][2]) + value = str(random.randrange(start, stop, step)) + else: + value = random.choice(task["labels"][0]["attributes"][index_attribute]["values"]) + elif key_get_values == "dafault": + value = attribute["default_value"] + + if item == "tracks" and attribute["mutable"]: + for index_shape, shape in enumerate(tmp_annotations[item][index_elem]["shapes"]): + tmp_annotations[item][index_elem]["shapes"][index_shape]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + else: + tmp_annotations[item][index_elem]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + + response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def _download_file(self, url, data, user, file_name): + for _ in range(5): + response = self._get_request_with_data(url, data, user) + if response.status_code == 200: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_name, "wb") as f: + f.write(content.getvalue()) + break + return response + + def _upload_file(self, url, binary_file, user): + with ForceLogin(user, self.client): + for _ in range(5): + response = self.client.put(url, {"annotation_file": binary_file}) + if response.status_code == 202: + break + return response + + def _check_downloaded_file(self, file_name): + if not osp.exists(file_name): + raise FileNotFoundError(f"File '{file_name}' was not downloaded") + class TaskExportTest(_DbTestBase): def _generate_custom_annotations(self, annotations, task): self._put_api_v1_task_id_annotations(task["id"], annotations) @@ -122,7 +214,7 @@ def _generate_annotations(self, task): }, { "spec_id": task["labels"][0]["attributes"][1]["id"], - "value": task["labels"][0]["attributes"][0]["default_value"] + "value": task["labels"][0]["attributes"][1]["default_value"] } ], "points": [1.0, 2.1, 100, 300.222], @@ -484,6 +576,504 @@ def test_frames_outside_are_not_generated(self): self.assertTrue(frame.frame in range(6, 10)) self.assertEqual(i + 1, 4) + + + + + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + test_name = self._testMethodName + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + # TODO skip failed formats + if dump_format_name in [ + "CamVid 1.0", # issue #2840 and changed points values + "CVAT for video 1.1", # issue #2923 and #2924 + "MOT 1.1", # issue #2925 + "MOTS PNG 1.0", # issue #2925 and changed points values + "Datumaro 1.0", # not uploaded + "Segmentation mask 1.1", # changed points values + "WiderFace 1.0", # issue #XXX + ]: + continue + + print("dump_format_name:", dump_format_name) + + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in ["MOT 1.1", "MOTS PNG 1.0", "PASCAL VOC 1.1", "Segmentation mask 1.1", "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", "WiderFace 1.0", "VGGFace2 1.0"]: + self._create_annotations(task, dump_format_name, "dafault") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + response = self._delete_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + + url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_update_wrong_label(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "dafault") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name_before_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}_wrong_label.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + response = self._delete_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # extract zip + folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_label = "wrong_label" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']") + element.attrib["label"] = wrong_label + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaises(ValueError) as context: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertTrue(f"Label '{wrong_label}' is not registered for this task" in str(context.exception)) + + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name_before_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + response = self._delete_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # extract zip + folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_checkbox_value = "wrong_checkbox_value" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") + element.text = wrong_checkbox_value + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaises(Exception) as context: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertTrue(f"Failed to convert attribute 'car'='{wrong_checkbox_value}'" in str(context.exception)) + + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_dataset_export_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump dataset + url = f"/api/v1/tasks/{task_id}/dataset" + data = { + "format": dump_format_name, + "action": "download", + } + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_annotations_update_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + for user in [self.admin, self.user, None]: + with open(file_zip_name, 'rb') as binary_file: + # remove annotations + response = self._delete_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # upload annotations + response = self._upload_file(url_upload, binary_file, user) + + if user is None: + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + else: + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + # check for presence annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNotEqual(len(response.data["tags"]), 0) + self.assertNotEqual(len(response.data["shapes"]), 0) + + def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + test_name = self._testMethodName + importer_format_name = { + 'COCO 1.0': 'coco', + 'CVAT for images 1.1': 'cvat', + 'CVAT for video 1.1': 'cvat', + 'Datumaro 1.0': 'datumaro_project', + 'LabelMe 3.0': 'label_me', + 'MOT 1.1': 'mot_seq', + 'MOTS PNG 1.0': 'mots_png', + 'PASCAL VOC 1.1': 'voc', + 'Segmentation mask 1.1': 'voc', + 'TFRecord 1.0': 'tf_detection_api', + 'YOLO 1.1': 'yolo', + 'ImageNet 1.0': 'imagenet_txt', + 'CamVid 1.0': 'camvid', + 'WiderFace 1.0': 'wider_face', + 'VGGFace2 1.0': 'vgg_face2', + } + + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + if dump_format_name != "Datumaro 1.0": + continue + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", + "YOLO 1.1", + "ImageNet 1.0", + "Datumaro 1.0", + ]: + continue + + print("dump_format_name:", dump_format_name) + + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in ["MOT 1.1", "MOTS PNG 1.0", "PASCAL VOC 1.1", "Segmentation mask 1.1", "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", "WiderFace 1.0", "VGGFace2 1.0"]: + self._create_annotations(task, dump_format_name, "dafault") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + data_datumaro = { + "dataset": None, + "annotations": None, + } + + for type_file in ("dataset", "annotations"): + # dump file + url = f"/api/v1/tasks/{task_id}/{type_file}" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # extract zip + folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + data_datumaro[type_file] = datumaro.components.project.Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + + # equals dataset vs annotations + compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + + @skip("Fail") + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro_many_jobs(self): + test_name = self._testMethodName + # create task with annotations + for dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) + + # dump annotations + url = f"/api/v1/tasks/{task_id}/annotations" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + response = self._delete_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + + url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_dataset_export_empty_data_with_datumaro(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + importer_format_name = "cvat" + data_datumaro = { + "dataset": None, + "annotations": None, + } + + # create task without annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) + + # dump dataset + for type_file in ("dataset", "annotations"): + # dump file + url = f"/api/v1/tasks/{task_id}/{type_file}" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # extract zip + folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + data_datumaro[type_file] = datumaro.components.project.Dataset.import_from(folder_name, importer_format_name) + + # equals dataset vs annotations + compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + + # upload annotations + url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + + class FrameMatchingTest(_DbTestBase): def _generate_task_images(self, paths): # pylint: disable=no-self-use f = BytesIO() From 476060c4b7d3aa6f70b4b5d4e02f213b90f7f700 Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Fri, 12 Mar 2021 10:24:43 +0300 Subject: [PATCH 02/43] small fix --- .vscode/settings.json | 2 +- .../assets/{tasks_for_formats.json => tasks.json} | 0 cvat/apps/dataset_manager/tests/test_formats.py | 10 ++-------- 3 files changed, 3 insertions(+), 9 deletions(-) rename cvat/apps/dataset_manager/tests/assets/{tasks_for_formats.json => tasks.json} (100%) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7efcd4e6a03..bf9c7502a40 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "python.pythonPath": ".env/bin/python", + "python.pythonPath": "C:\\Users\\doparinx\\AppData\\Local\\Programs\\Python\\Python38\\python.exe", "eslint.enable": true, "eslint.probe": [ "javascript", diff --git a/cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json b/cvat/apps/dataset_manager/tests/assets/tasks.json similarity index 100% rename from cvat/apps/dataset_manager/tests/assets/tasks_for_formats.json rename to cvat/apps/dataset_manager/tests/assets/tasks.json diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 1cd52b41aca..bcf5672208c 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -131,7 +131,7 @@ def _create_annotations(self, task, name_ann, key_get_values): # change attributes in all annotations for item in tmp_annotations: if item in ["tags", "shapes", "tracks"]: - for index_elem, elem in enumerate(tmp_annotations[item]): + for index_elem, _ in enumerate(tmp_annotations[item]): tmp_annotations[item][index_elem]["label_id"] = task["labels"][0]["id"] for index_attribute, attribute in enumerate(task["labels"][0]["attributes"]): @@ -149,7 +149,7 @@ def _create_annotations(self, task, name_ann, key_get_values): value = attribute["default_value"] if item == "tracks" and attribute["mutable"]: - for index_shape, shape in enumerate(tmp_annotations[item][index_elem]["shapes"]): + for index_shape, _ in enumerate(tmp_annotations[item][index_elem]["shapes"]): tmp_annotations[item][index_elem]["shapes"][index_shape]["attributes"].append({ "spec_id": spec_id, "value": value, @@ -576,10 +576,6 @@ def test_frames_outside_are_not_generated(self): self.assertTrue(frame.frame in range(6, 10)) self.assertEqual(i + 1, 4) - - - - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName # get formats @@ -1072,8 +1068,6 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_empty_data_with_datuma data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - class FrameMatchingTest(_DbTestBase): def _generate_task_images(self, paths): # pylint: disable=no-self-use f = BytesIO() From 867c0a84439bcf3ca98bdf3509d3cc8b8db76f4a Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Fri, 12 Mar 2021 11:02:31 +0300 Subject: [PATCH 03/43] revert settings.settings.json --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index bf9c7502a40..7efcd4e6a03 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { - "python.pythonPath": "C:\\Users\\doparinx\\AppData\\Local\\Programs\\Python\\Python38\\python.exe", + "python.pythonPath": ".env/bin/python", "eslint.enable": true, "eslint.probe": [ "javascript", From a41c3ea8dab004d8b7b9e62df3234e0d04e4c0eb Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Fri, 12 Mar 2021 12:28:17 +0300 Subject: [PATCH 04/43] add number bug --- cvat/apps/dataset_manager/tests/test_formats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index bcf5672208c..0168417fdce 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -593,7 +593,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): "MOTS PNG 1.0", # issue #2925 and changed points values "Datumaro 1.0", # not uploaded "Segmentation mask 1.1", # changed points values - "WiderFace 1.0", # issue #XXX + "WiderFace 1.0", # issue #2944 ]: continue From 884baddf16aeb0375b0a3b0842cec276d7bde5c2 Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Sun, 14 Mar 2021 22:59:51 +0300 Subject: [PATCH 05/43] revert test_formats.py --- .../dataset_manager/tests/test_formats.py | 602 +----------------- 1 file changed, 9 insertions(+), 593 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index 0168417fdce..75ff51d01b4 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -8,14 +8,8 @@ import os.path as osp import tempfile import zipfile -from unittest import skip -import copy -import json -import random -import xml.etree.ElementTree as ET import datumaro -from datumaro.util.test_utils import compare_datasets from PIL import Image from django.contrib.auth.models import User, Group from rest_framework.test import APITestCase, APIClient @@ -27,13 +21,6 @@ from cvat.apps.dataset_manager.task import TaskAnnotation from cvat.apps.engine.models import Task -path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') -with open(path) as f: - tasks = json.load(f) - -path = osp.join(osp.dirname(__file__), 'assets', 'annotations.json') -with open(path) as f: - annotations = json.load(f) def generate_image_file(filename, size=(100, 50)): f = BytesIO() @@ -69,34 +56,30 @@ def setUpTestData(cls): @classmethod def create_db_users(cls): - (group_admin, _) = Group.objects.get_or_create(name="admin") - (group_user, _) = Group.objects.get_or_create(name="user") + group, _ = Group.objects.get_or_create(name="adm") - user_admin = User.objects.create_superuser(username="admin", email="", - password="admin") - user_admin.groups.add(group_admin) - user_dummy = User.objects.create_user(username="user", password="user") - user_dummy.groups.add(group_user) + admin = User.objects.create_superuser( + username="test", password="test", email="") + admin.groups.add(group) - cls.admin = user_admin - cls.user = user_dummy + cls.user = admin def _put_api_v1_task_id_annotations(self, tid, data): - with ForceLogin(self.admin, self.client): + with ForceLogin(self.user, self.client): response = self.client.put("/api/v1/tasks/%s/annotations" % tid, data=data, format="json") return response def _put_api_v1_job_id_annotations(self, jid, data): - with ForceLogin(self.admin, self.client): + with ForceLogin(self.user, self.client): response = self.client.put("/api/v1/jobs/%s/annotations" % jid, data=data, format="json") return response def _create_task(self, data, image_data): - with ForceLogin(self.admin, self.client): + with ForceLogin(self.user, self.client): response = self.client.post('/api/v1/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] @@ -110,81 +93,6 @@ def _create_task(self, data, image_data): return task - def _get_request(self, path, user): - with ForceLogin(user, self.client): - response = self.client.get(path) - return response - - def _get_request_with_data(self, path, data, user): - with ForceLogin(user, self.client): - response = self.client.get(path, data) - return response - - def _delete_request(self, path, user): - with ForceLogin(user, self.client): - response = self.client.delete(path) - return response - - def _create_annotations(self, task, name_ann, key_get_values): - tmp_annotations = copy.deepcopy(annotations[name_ann]) - - # change attributes in all annotations - for item in tmp_annotations: - if item in ["tags", "shapes", "tracks"]: - for index_elem, _ in enumerate(tmp_annotations[item]): - tmp_annotations[item][index_elem]["label_id"] = task["labels"][0]["id"] - - for index_attribute, attribute in enumerate(task["labels"][0]["attributes"]): - spec_id = task["labels"][0]["attributes"][index_attribute]["id"] - - if key_get_values == "random": - if attribute["input_type"] == "number": - start = int(attribute["values"][0]) - stop = int(attribute["values"][1]) + 1 - step = int(attribute["values"][2]) - value = str(random.randrange(start, stop, step)) - else: - value = random.choice(task["labels"][0]["attributes"][index_attribute]["values"]) - elif key_get_values == "dafault": - value = attribute["default_value"] - - if item == "tracks" and attribute["mutable"]: - for index_shape, _ in enumerate(tmp_annotations[item][index_elem]["shapes"]): - tmp_annotations[item][index_elem]["shapes"][index_shape]["attributes"].append({ - "spec_id": spec_id, - "value": value, - }) - else: - tmp_annotations[item][index_elem]["attributes"].append({ - "spec_id": spec_id, - "value": value, - }) - - response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) - self.assertEqual(response.status_code, status.HTTP_200_OK) - - def _download_file(self, url, data, user, file_name): - for _ in range(5): - response = self._get_request_with_data(url, data, user) - if response.status_code == 200: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_name, "wb") as f: - f.write(content.getvalue()) - break - return response - - def _upload_file(self, url, binary_file, user): - with ForceLogin(user, self.client): - for _ in range(5): - response = self.client.put(url, {"annotation_file": binary_file}) - if response.status_code == 202: - break - return response - - def _check_downloaded_file(self, file_name): - if not osp.exists(file_name): - raise FileNotFoundError(f"File '{file_name}' was not downloaded") - class TaskExportTest(_DbTestBase): def _generate_custom_annotations(self, annotations, task): self._put_api_v1_task_id_annotations(task["id"], annotations) @@ -214,7 +122,7 @@ def _generate_annotations(self, task): }, { "spec_id": task["labels"][0]["attributes"][1]["id"], - "value": task["labels"][0]["attributes"][1]["default_value"] + "value": task["labels"][0]["attributes"][0]["default_value"] } ], "points": [1.0, 2.1, 100, 300.222], @@ -576,498 +484,6 @@ def test_frames_outside_are_not_generated(self): self.assertTrue(frame.frame in range(6, 10)) self.assertEqual(i + 1, 4) - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): - test_name = self._testMethodName - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - # TODO skip failed formats - if dump_format_name in [ - "CamVid 1.0", # issue #2840 and changed points values - "CVAT for video 1.1", # issue #2923 and #2924 - "MOT 1.1", # issue #2925 - "MOTS PNG 1.0", # issue #2925 and changed points values - "Datumaro 1.0", # not uploaded - "Segmentation mask 1.1", # changed points values - "WiderFace 1.0", # issue #2944 - ]: - continue - - print("dump_format_name:", dump_format_name) - - # create task - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in ["MOT 1.1", "MOTS PNG 1.0", "PASCAL VOC 1.1", "Segmentation mask 1.1", "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", "WiderFace 1.0", "VGGFace2 1.0"]: - self._create_annotations(task, dump_format_name, "dafault") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - response = self._delete_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - - # upload annotations - if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - upload_format_name = "CVAT 1.1" - else: - upload_format_name = dump_format_name - - url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_update_wrong_label(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "dafault") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name_before_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}_wrong_label.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - response = self._delete_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - - # extract zip - folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_label = "wrong_label" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']") - element.attrib["label"] = wrong_label - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaises(ValueError) as context: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertTrue(f"Label '{wrong_label}' is not registered for this task" in str(context.exception)) - - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) - - def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name_before_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - response = self._delete_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - - # extract zip - folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_checkbox_value = "wrong_checkbox_value" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") - element.text = wrong_checkbox_value - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaises(Exception) as context: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertTrue(f"Failed to convert attribute 'car'='{wrong_checkbox_value}'" in str(context.exception)) - - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) - - def test_api_v1_tasks_annotations_dump_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_dataset_export_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump dataset - url = f"/api/v1/tasks/{task_id}/dataset" - data = { - "format": dump_format_name, - "action": "download", - } - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_annotations_update_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - url_upload = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - for user in [self.admin, self.user, None]: - with open(file_zip_name, 'rb') as binary_file: - # remove annotations - response = self._delete_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - - # upload annotations - response = self._upload_file(url_upload, binary_file, user) - - if user is None: - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - else: - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - # check for presence annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertNotEqual(len(response.data["tags"]), 0) - self.assertNotEqual(len(response.data["shapes"]), 0) - - def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - test_name = self._testMethodName - importer_format_name = { - 'COCO 1.0': 'coco', - 'CVAT for images 1.1': 'cvat', - 'CVAT for video 1.1': 'cvat', - 'Datumaro 1.0': 'datumaro_project', - 'LabelMe 3.0': 'label_me', - 'MOT 1.1': 'mot_seq', - 'MOTS PNG 1.0': 'mots_png', - 'PASCAL VOC 1.1': 'voc', - 'Segmentation mask 1.1': 'voc', - 'TFRecord 1.0': 'tf_detection_api', - 'YOLO 1.1': 'yolo', - 'ImageNet 1.0': 'imagenet_txt', - 'CamVid 1.0': 'camvid', - 'WiderFace 1.0': 'wider_face', - 'VGGFace2 1.0': 'vgg_face2', - } - - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - if dump_format_name != "Datumaro 1.0": - continue - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", - "YOLO 1.1", - "ImageNet 1.0", - "Datumaro 1.0", - ]: - continue - - print("dump_format_name:", dump_format_name) - - # create task - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in ["MOT 1.1", "MOTS PNG 1.0", "PASCAL VOC 1.1", "Segmentation mask 1.1", "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", "WiderFace 1.0", "VGGFace2 1.0"]: - self._create_annotations(task, dump_format_name, "dafault") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - data_datumaro = { - "dataset": None, - "annotations": None, - } - - for type_file in ("dataset", "annotations"): - # dump file - url = f"/api/v1/tasks/{task_id}/{type_file}" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # extract zip - folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - zip_ref.extractall(folder_name) - data_datumaro[type_file] = datumaro.components.project.Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - - # equals dataset vs annotations - compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - - @skip("Fail") - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro_many_jobs(self): - test_name = self._testMethodName - # create task with annotations - for dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - images = self._generate_task_images(13) - task = self._create_task(tasks["many jobs"], images) - self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) - - # dump annotations - url = f"/api/v1/tasks/{task_id}/annotations" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - response = self._delete_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - - # upload annotations - if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - upload_format_name = "CVAT 1.1" - else: - upload_format_name = dump_format_name - - url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_dump_and_dataset_export_empty_data_with_datumaro(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - importer_format_name = "cvat" - data_datumaro = { - "dataset": None, - "annotations": None, - } - - # create task without annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_before_upload = datumaro.components.project.Dataset.from_extractors(extractor) - - # dump dataset - for type_file in ("dataset", "annotations"): - # dump file - url = f"/api/v1/tasks/{task_id}/{type_file}" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # extract zip - folder_name = osp.join(osp.dirname(__file__), 'assets', f'{test_name}_{type_file}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - zip_ref.extractall(folder_name) - data_datumaro[type_file] = datumaro.components.project.Dataset.import_from(folder_name, importer_format_name) - - # equals dataset vs annotations - compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - - # upload annotations - url = f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_after_upload = datumaro.components.project.Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - class FrameMatchingTest(_DbTestBase): def _generate_task_images(self, paths): # pylint: disable=no-self-use f = BytesIO() From 31c1f2b68efb76077dd9e57b5720c6cb58cf5f22 Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Sun, 14 Mar 2021 23:03:42 +0300 Subject: [PATCH 06/43] move rest api tests to other file --- .../tests/test_rest_api_formats.py | 649 ++++++++++++++++++ 1 file changed, 649 insertions(+) create mode 100644 cvat/apps/dataset_manager/tests/test_rest_api_formats.py diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py new file mode 100644 index 00000000000..2a07b033abc --- /dev/null +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -0,0 +1,649 @@ + +# Copyright (C) 2021 Intel Corporation +# +# SPDX-License-Identifier: MIT + + +import copy +import json +import os.path as osp +import random +import xml.etree.ElementTree as ET +import zipfile +from io import BytesIO + +from datumaro.components.dataset import Dataset +from datumaro.util.test_utils import compare_datasets, TestDir +from django.contrib.auth.models import Group, User +from PIL import Image +from rest_framework import status +from rest_framework.test import APIClient, APITestCase + +import cvat.apps.dataset_manager as dm +from cvat.apps.dataset_manager.bindings import CvatTaskDataExtractor, TaskData +from cvat.apps.dataset_manager.task import TaskAnnotation +from cvat.apps.engine.models import Task + +path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') +with open(path) as f: + tasks = json.load(f) + +path = osp.join(osp.dirname(__file__), 'assets', 'annotations.json') +with open(path) as f: + annotations = json.load(f) + +def generate_image_file(filename, size=(100, 50)): + f = BytesIO() + image = Image.new('RGB', size=size) + image.save(f, 'jpeg') + f.name = filename + f.seek(0) + return f + +class ForceLogin: + def __init__(self, user, client): + self.user = user + self.client = client + + def __enter__(self): + if self.user: + self.client.force_login(self.user, + backend='django.contrib.auth.backends.ModelBackend') + + return self + + def __exit__(self, exception_type, exception_value, traceback): + if self.user: + self.client.logout() + +class _DbTestBase(APITestCase): + def setUp(self): + self.client = APIClient() + + @classmethod + def setUpTestData(cls): + cls.create_db_users() + + @classmethod + def create_db_users(cls): + (group_admin, _) = Group.objects.get_or_create(name="admin") + (group_user, _) = Group.objects.get_or_create(name="user") + + user_admin = User.objects.create_superuser(username="admin", email="", + password="admin") + user_admin.groups.add(group_admin) + user_dummy = User.objects.create_user(username="user", password="user") + user_dummy.groups.add(group_user) + + cls.admin = user_admin + cls.user = user_dummy + + def _put_api_v1_task_id_annotations(self, tid, data): + with ForceLogin(self.admin, self.client): + response = self.client.put("/api/v1/tasks/%s/annotations" % tid, + data=data, format="json") + + return response + + def _generate_task_images(self, count): # pylint: disable=no-self-use + images = { + "client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) + for i in range(count) + } + images["image_quality"] = 75 + return images + + def _create_task(self, data, image_data): + with ForceLogin(self.admin, self.client): + response = self.client.post('/api/v1/tasks', data=data, format="json") + assert response.status_code == status.HTTP_201_CREATED, response.status_code + tid = response.data["id"] + + response = self.client.post("/api/v1/tasks/%s/data" % tid, + data=image_data) + assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code + + response = self.client.get("/api/v1/tasks/%s" % tid) + task = response.data + + return task + + def _get_request(self, path, user): + with ForceLogin(user, self.client): + response = self.client.get(path) + return response + + def _get_request_with_data(self, path, data, user): + with ForceLogin(user, self.client): + response = self.client.get(path, data) + return response + + def _delete_request(self, path, user): + with ForceLogin(user, self.client): + response = self.client.delete(path) + return response + + def _create_annotations(self, task, name_ann, key_get_values): + tmp_annotations = copy.deepcopy(annotations[name_ann]) + + # change attributes in all annotations + for item in tmp_annotations: + if item in ["tags", "shapes", "tracks"]: + for index_elem, _ in enumerate(tmp_annotations[item]): + tmp_annotations[item][index_elem]["label_id"] = task["labels"][0]["id"] + + for index_attribute, attribute in enumerate(task["labels"][0]["attributes"]): + spec_id = task["labels"][0]["attributes"][index_attribute]["id"] + + if key_get_values == "random": + if attribute["input_type"] == "number": + start = int(attribute["values"][0]) + stop = int(attribute["values"][1]) + 1 + step = int(attribute["values"][2]) + value = str(random.randrange(start, stop, step)) + else: + value = random.choice(task["labels"][0]["attributes"][index_attribute]["values"]) + elif key_get_values == "dafault": + value = attribute["default_value"] + + if item == "tracks" and attribute["mutable"]: + for index_shape, _ in enumerate(tmp_annotations[item][index_elem]["shapes"]): + tmp_annotations[item][index_elem]["shapes"][index_shape]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + else: + tmp_annotations[item][index_elem]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + + response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def _download_file(self, url, data, user, file_name): + for _ in range(5): + response = self._get_request_with_data(url, data, user) + if response.status_code == 200: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_name, "wb") as f: + f.write(content.getvalue()) + break + return response + + def _upload_file(self, url, binary_file, user): + with ForceLogin(user, self.client): + for _ in range(5): + response = self.client.put(url, {"annotation_file": binary_file}) + if response.status_code == 202: + break + return response + + def _check_downloaded_file(self, file_name): + if not osp.exists(file_name): + raise FileNotFoundError(f"File '{file_name}' was not downloaded") + + def _generate_url_dump_tasks_annotations(self, task_id): + return f"/api/v1/tasks/{task_id}/annotations" + + def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): + return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + + def _remove_annotations(self, url, user): + response = self._delete_request(url, user) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + return response + +class TaskDumpUploadTest(_DbTestBase): + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + test_name = self._testMethodName + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", # issues #2923 and #2924 + "MOT 1.1", # issue #2925 + "Datumaro 1.0", # not uploaded + "WiderFace 1.0", # issue #2944 + "CamVid 1.0", # issue #2840 and changed points values + "MOTS PNG 1.0", # issue #2925 and changed points values + "Segmentation mask 1.1", # changed points values + ]: + self.skipTest("Format is fail") + + print("dump_format_name:", dump_format_name) + + for include_images in (False, True): + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "dafault") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_update_wrong_label(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "dafault") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + self._remove_annotations(url, self.admin) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_label = "wrong_label" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']") + element.attrib["label"] = wrong_label + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): + response = self._upload_file(url_upload, binary_file, self.admin) + + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + self._remove_annotations(url, self.admin) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_checkbox_value = "wrong_checkbox_value" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") + element.text = wrong_checkbox_value + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): + response = self._upload_file(url_upload, binary_file, self.admin) + + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_dataset_export_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump dataset + url = f"/api/v1/tasks/{task_id}/dataset" + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_annotations_update_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + for user in [self.admin, self.user, None]: + with open(file_zip_name, 'rb') as binary_file: + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + response = self._upload_file(url_upload, binary_file, user) + + if user is None: + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + else: + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + # check for presence annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNotEqual(len(response.data["tags"]), 0) + self.assertNotEqual(len(response.data["shapes"]), 0) + + def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + test_name = self._testMethodName + importer_format_name = { + 'COCO 1.0': 'coco', + 'CVAT for images 1.1': 'cvat', + 'CVAT for video 1.1': 'cvat', + 'Datumaro 1.0': 'datumaro_project', + 'LabelMe 3.0': 'label_me', + 'MOT 1.1': 'mot_seq', + 'MOTS PNG 1.0': 'mots_png', + 'PASCAL VOC 1.1': 'voc', + 'Segmentation mask 1.1': 'voc', + 'TFRecord 1.0': 'tf_detection_api', + 'YOLO 1.1': 'yolo', + 'ImageNet 1.0': 'imagenet_txt', + 'CamVid 1.0': 'camvid', + 'WiderFace 1.0': 'wider_face', + 'VGGFace2 1.0': 'vgg_face2', + } + + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", + "YOLO 1.1", + "ImageNet 1.0", + "Datumaro 1.0", + ]: + self.skipTest("Format is fail") + + print("dump_format_name:", dump_format_name) + + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "dafault") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + data_datumaro = { + "dataset": None, + "annotations": None, + } + with TestDir() as test_dir: + for type_file in ("dataset", "annotations"): + # dump file + url = f"/api/v1/tasks/{task_id}/{type_file}" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + + # equals dataset vs annotations + compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro_many_jobs(self): + test_name = self._testMethodName + upload_format_name = "CVAT 1.1" + + for include_images in (False, True): + for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", # issues #2923 and #2945 + ]: + self.skipTest("Format is fail") + + # create task with annotations + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + From 4db0928f917239e1fb33854698c6f0c4d3dc193b Mon Sep 17 00:00:00 2001 From: Dmitriy Oparin Date: Mon, 15 Mar 2021 13:36:53 +0300 Subject: [PATCH 07/43] add new tests --- .../tests/assets/annotations.json | 126 ++++++++++++++++ .../dataset_manager/tests/assets/tasks.json | 13 ++ .../tests/test_rest_api_formats.py | 139 +++++++++++++++++- 3 files changed, 273 insertions(+), 5 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 31936d36417..3f1f3dec8c7 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -730,5 +730,131 @@ "attributes": [] } ] + }, + "CVAT for video 1.1 slice track": { + "version": 0, + "tags": [], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [66.45, 147.08, 182.16, 204.56], + "frame": 0, + "outside": true, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [66.45, 147.08, 182.16, 204.56], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "CVAT for images 1.1 merge": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [9.95, 8.09, 18.65, 13.39], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [11.545, 11.7, 19.44, 17.4], + "frame": 3, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [4.54, 19.59, 21.34, 26.89], + "frame": 0, + "outside": false, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [4.54, 19.59, 21.34, 26.89], + "frame": 6, + "outside": true, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 3, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [9.65, 23.59, 22.65, 29.79], + "frame": 3, + "outside": false, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [9.65, 23.59, 22.65, 29.79], + "frame": 9, + "outside": true, + "attributes": [] + } + ], + "attributes": [] + } + ] } } diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 0f2dbc37643..f1203a14a61 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -79,5 +79,18 @@ "attributes": [] } ] + }, + "change ovelap and segment size": { + "name": "change ovelap and segment size", + "overlap": 3, + "segment_size": 6, + "owner_id": 1, + "labels": [ + { + "name": "car", + "color": "#2080c0", + "attributes": [] + } + ] } } diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 2a07b033abc..23a0094ce77 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -217,8 +217,6 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): ]: self.skipTest("Format is fail") - print("dump_format_name:", dump_format_name) - for include_images in (False, True): # create task images = self._generate_task_images(3) @@ -548,8 +546,6 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): ]: self.skipTest("Format is fail") - print("dump_format_name:", dump_format_name) - # create task images = self._generate_task_images(3) task = self._create_task(tasks["main"], images) @@ -594,7 +590,7 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): # equals dataset vs annotations compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro_many_jobs(self): + def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): test_name = self._testMethodName upload_format_name = "CVAT 1.1" @@ -647,3 +643,136 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro_many_jobs(self): data_from_task_after_upload = Dataset.from_extractors(extractor) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(5) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, f'{dump_format_name} slice track', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_merge(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) From a4ba5a8802d819b6117f367120582fe50cd166d0 Mon Sep 17 00:00:00 2001 From: mzuevx Date: Wed, 24 Mar 2021 01:01:27 +0300 Subject: [PATCH 08/43] Fixed HTTP_400 code Commented out tests passed Ok Uncommented tests failed if launched in single test session, seems that tasks created via POST request to url /api/v1/tasks have the same id (1) --- .../dataset_manager/tests/assets/tasks.json | 55 + .../tests/test_rest_api_formats.py | 942 +++++++++--------- ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ...and_upload_rewrite_CVAT for images 1.1.zip | Bin 0 -> 4109 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 0 -> 5301 bytes .../annotations.xml | 138 +++ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 0 -> 5241 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 0 -> 5307 bytes .../annotations.xml | 138 +++ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 0 -> 5247 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 0 -> 5301 bytes .../annotations.xml | 138 +++ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 0 -> 5241 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 0 -> 5298 bytes .../annotations.xml | 138 +++ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 0 -> 5238 bytes 22 files changed, 1081 insertions(+), 468 deletions(-) create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-b67lk9ts/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-luh073az/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-mpty4d21/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-r8hdbd0m/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml create mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index f1203a14a61..ab51d2a8c23 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -54,6 +54,61 @@ } ] }, + "wrong_checkbox_value": { + "name": "wrong checkbox value task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "car", + "color": "#2080c0", + "attributes": [ + { + "name": "select_name", + "mutable": false, + "input_type": "select", + "default_value": "bmw", + "values": ["bmw", "mazda", "renault"] + }, + { + "name": "radio_name", + "mutable": false, + "input_type": "radio", + "default_value": "x1", + "values": ["x1", "x2", "x3"] + }, + { + "name": "check_name", + "mutable": true, + "input_type": "checkbox", + "default_value": "false", + "values": ["false"] + }, + { + "name": "text_name", + "mutable": false, + "input_type": "text", + "default_value": "qwerty", + "values": ["qwerty"] + }, + { + "name": "number_name", + "mutable": false, + "input_type": "number", + "default_value": "-4", + "values": ["-4", "4", "1"] + } + ] + }, + { + "name": "person", + "color": "#c06060", + "attributes": [] + } + ] + }, "no attributes": { "name": "no attributes", "overlap": 0, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 23a0094ce77..e873414e06c 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -103,6 +103,12 @@ def _create_task(self, data, image_data): data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code + for _ in range(5): + response = self.client.get("/api/v1/tasks/%s/status" % tid) + if response.status_code == status.HTTP_200_OK: + break + assert response.status_code == status.HTTP_200_OK, response.status_code + response = self.client.get("/api/v1/tasks/%s" % tid) task = response.data @@ -175,7 +181,7 @@ def _upload_file(self, url, binary_file, user): with ForceLogin(user, self.client): for _ in range(5): response = self.client.put(url, {"annotation_file": binary_file}) - if response.status_code == 202: + if response.status_code == 201: break return response @@ -195,84 +201,84 @@ def _remove_annotations(self, url, user): return response class TaskDumpUploadTest(_DbTestBase): - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): - test_name = self._testMethodName - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - with self.subTest(): - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", # issues #2923 and #2924 - "MOT 1.1", # issue #2925 - "Datumaro 1.0", # not uploaded - "WiderFace 1.0", # issue #2944 - "CamVid 1.0", # issue #2840 and changed points values - "MOTS PNG 1.0", # issue #2925 and changed points values - "Segmentation mask 1.1", # changed points values - ]: - self.skipTest("Format is fail") - - for include_images in (False, True): - # create task - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "dafault") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_before_upload = Dataset.from_extractors(extractor) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - upload_format_name = "CVAT 1.1" - else: - upload_format_name = dump_format_name - - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_after_upload = Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - + # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + # test_name = self._testMethodName + # # get formats + # dump_formats = dm.views.get_export_formats() + # + # for dump_format in dump_formats: + # if dump_format.ENABLED: + # dump_format_name = dump_format.DISPLAY_NAME + # + # with self.subTest(): + # # TODO skip failed formats + # if dump_format_name in [ + # "CVAT for video 1.1", # issues #2923 and #2924 + # "MOT 1.1", # issue #2925 + # "Datumaro 1.0", # not uploaded + # "WiderFace 1.0", # issue #2944 + # "CamVid 1.0", # issue #2840 and changed points values + # "MOTS PNG 1.0", # issue #2925 and changed points values + # "Segmentation mask 1.1", # changed points values + # ]: + # self.skipTest("Format is fail") + # + # for include_images in (False, True): + # # create task + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # + # # create annotations + # if dump_format_name in [ + # "MOT 1.1", "MOTS PNG 1.0", \ + # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + # "WiderFace 1.0", "VGGFace2 1.0", \ + # ]: + # self._create_annotations(task, dump_format_name, "dafault") + # else: + # self._create_annotations(task, dump_format_name, "random") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + # data_from_task_before_upload = Dataset.from_extractors(extractor) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + # upload_format_name = "CVAT 1.1" + # else: + # upload_format_name = dump_format_name + # + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + # data_from_task_after_upload = Dataset.from_extractors(extractor) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # def test_api_v1_tasks_annotations_update_wrong_label(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" @@ -281,7 +287,7 @@ def test_api_v1_tasks_annotations_update_wrong_label(self): # create task with annotations images = self._generate_task_images(3) task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "dafault") + self._create_annotations(task, dump_format_name, "default") task_id = task["id"] task_ann = TaskAnnotation(task_id) task_ann.init_from_db() @@ -338,7 +344,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # create task with annotations images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) + task = self._create_task(tasks["wrong_checkbox_value"], images) self._create_annotations(task, dump_format_name, "random") task_id = task["id"] task_ann = TaskAnnotation(task_id) @@ -389,390 +395,390 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): self.assertEqual(len(response.data["shapes"]), 0) self.assertEqual(len(response.data["tracks"]), 0) - def test_api_v1_tasks_annotations_dump_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_dataset_export_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump dataset - url = f"/api/v1/tasks/{task_id}/dataset" - data = { - "format": dump_format_name, - "action": "download", - } - - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_annotations_update_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - for user in [self.admin, self.user, None]: - with open(file_zip_name, 'rb') as binary_file: - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - response = self._upload_file(url_upload, binary_file, user) - - if user is None: - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - else: - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - # check for presence annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertNotEqual(len(response.data["tags"]), 0) - self.assertNotEqual(len(response.data["shapes"]), 0) - - def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - test_name = self._testMethodName - importer_format_name = { - 'COCO 1.0': 'coco', - 'CVAT for images 1.1': 'cvat', - 'CVAT for video 1.1': 'cvat', - 'Datumaro 1.0': 'datumaro_project', - 'LabelMe 3.0': 'label_me', - 'MOT 1.1': 'mot_seq', - 'MOTS PNG 1.0': 'mots_png', - 'PASCAL VOC 1.1': 'voc', - 'Segmentation mask 1.1': 'voc', - 'TFRecord 1.0': 'tf_detection_api', - 'YOLO 1.1': 'yolo', - 'ImageNet 1.0': 'imagenet_txt', - 'CamVid 1.0': 'camvid', - 'WiderFace 1.0': 'wider_face', - 'VGGFace2 1.0': 'vgg_face2', - } - - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - with self.subTest(): - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", - "YOLO 1.1", - "ImageNet 1.0", - "Datumaro 1.0", - ]: - self.skipTest("Format is fail") - - # create task - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "dafault") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - data_datumaro = { - "dataset": None, - "annotations": None, - } - with TestDir() as test_dir: - for type_file in ("dataset", "annotations"): - # dump file - url = f"/api/v1/tasks/{task_id}/{type_file}" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - zip_ref.extractall(folder_name) - data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - - # equals dataset vs annotations - compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - - def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): - test_name = self._testMethodName - upload_format_name = "CVAT 1.1" - - for include_images in (False, True): - for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - with self.subTest(): - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", # issues #2923 and #2945 - ]: - self.skipTest("Format is fail") - - # create task with annotations - images = self._generate_task_images(13) - task = self._create_task(tasks["many jobs"], images) - self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_before_upload = Dataset.from_extractors(extractor) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_after_upload = Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): - test_name = self._testMethodName - dump_format_name = "CVAT for video 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(5) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, f'{dump_format_name} slice track', "dafault") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_before_upload = Dataset.from_extractors(extractor) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_after_upload = Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_dump_and_upload_merge(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(10) - task = self._create_task(tasks["change ovelap and segment size"], images) - self._create_annotations(task, f'{dump_format_name} merge', "dafault") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 1) - self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - self.assertEqual(len(response.data["tracks"]), 0) - - def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(10) - task = self._create_task(tasks["change ovelap and segment size"], images) - self._create_annotations(task, f'{dump_format_name} merge', "dafault") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 1) - self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - self.assertEqual(len(response.data["tracks"]), 0) + # def test_api_v1_tasks_annotations_dump_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + # response = self._download_file(url, data, self.user, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + # response = self._download_file(url, data, None, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # with self.assertRaises(FileNotFoundError): + # self._check_downloaded_file(file_zip_name) + # + # def test_api_v1_tasks_dataset_export_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump dataset + # url = f"/api/v1/tasks/{task_id}/dataset" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + # response = self._download_file(url, data, self.user, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + # response = self._download_file(url, data, None, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # with self.assertRaises(FileNotFoundError): + # self._check_downloaded_file(file_zip_name) + # + # def test_api_v1_tasks_annotations_update_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # for user in [self.admin, self.user, None]: + # with open(file_zip_name, 'rb') as binary_file: + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # response = self._upload_file(url_upload, binary_file, user) + # + # if user is None: + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # else: + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # # check for presence annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertNotEqual(len(response.data["tags"]), 0) + # self.assertNotEqual(len(response.data["shapes"]), 0) + # + # def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + # test_name = self._testMethodName + # importer_format_name = { + # 'COCO 1.0': 'coco', + # 'CVAT for images 1.1': 'cvat', + # 'CVAT for video 1.1': 'cvat', + # 'Datumaro 1.0': 'datumaro_project', + # 'LabelMe 3.0': 'label_me', + # 'MOT 1.1': 'mot_seq', + # 'MOTS PNG 1.0': 'mots_png', + # 'PASCAL VOC 1.1': 'voc', + # 'Segmentation mask 1.1': 'voc', + # 'TFRecord 1.0': 'tf_detection_api', + # 'YOLO 1.1': 'yolo', + # 'ImageNet 1.0': 'imagenet_txt', + # 'CamVid 1.0': 'camvid', + # 'WiderFace 1.0': 'wider_face', + # 'VGGFace2 1.0': 'vgg_face2', + # } + # + # # get formats + # dump_formats = dm.views.get_export_formats() + # + # for dump_format in dump_formats: + # if dump_format.ENABLED: + # dump_format_name = dump_format.DISPLAY_NAME + # + # with self.subTest(): + # # TODO skip failed formats + # if dump_format_name in [ + # "CVAT for video 1.1", + # "YOLO 1.1", + # "ImageNet 1.0", + # "Datumaro 1.0", + # ]: + # self.skipTest("Format is fail") + # + # # create task + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # + # # create annotations + # if dump_format_name in [ + # "MOT 1.1", "MOTS PNG 1.0", \ + # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + # "WiderFace 1.0", "VGGFace2 1.0", \ + # ]: + # self._create_annotations(task, dump_format_name, "dafault") + # else: + # self._create_annotations(task, dump_format_name, "random") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # data_datumaro = { + # "dataset": None, + # "annotations": None, + # } + # with TestDir() as test_dir: + # for type_file in ("dataset", "annotations"): + # # dump file + # url = f"/api/v1/tasks/{task_id}/{type_file}" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + # + # # equals dataset vs annotations + # compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + # + # def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + # test_name = self._testMethodName + # upload_format_name = "CVAT 1.1" + # + # for include_images in (False, True): + # for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + # with self.subTest(): + # # TODO skip failed formats + # if dump_format_name in [ + # "CVAT for video 1.1", # issues #2923 and #2945 + # ]: + # self.skipTest("Format is fail") + # + # # create task with annotations + # images = self._generate_task_images(13) + # task = self._create_task(tasks["many jobs"], images) + # self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + # data_from_task_before_upload = Dataset.from_extractors(extractor) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + # data_from_task_after_upload = Dataset.from_extractors(extractor) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # + # def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for video 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(5) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, f'{dump_format_name} slice track', "dafault") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data) + # data_from_task_before_upload = Dataset.from_extractors(extractor) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # extractor = CvatTaskDataExtractor(task_data) + # data_from_task_after_upload = Dataset.from_extractors(extractor) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # + # def test_api_v1_tasks_annotations_dump_and_upload_merge(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(10) + # task = self._create_task(tasks["change ovelap and segment size"], images) + # self._create_annotations(task, f'{dump_format_name} merge', "dafault") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 1) + # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + # self.assertEqual(len(response.data["tracks"]), 0) + # + # def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(10) + # task = self._create_task(tasks["change ovelap and segment size"], images) + # self._create_annotations(task, f'{dump_format_name} merge', "dafault") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 1) + # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + # self.assertEqual(len(response.data["tracks"]), 0) diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..6d0ddbd50863972d3ce1915f4492573aacbc0671 GIT binary patch literal 4109 zcmeHK&2rN)5Kbv@=!Hukz+;X~<^RO)DDDIF(%}U%imf`P{>jL4Tgr(C;2Gc{IKhQS zV%`dzrMVgOvFFDC!{D!PIy`t z6}rwdd;$;clClaUbKOFwuF)bY$vJj%sGO-~E zCC$s2hCMuNNP$`f&kS6L4mK32mX>wG8Hp|^3$Za^)Oy4y;WQ3y)3%OG=g9Ik%R9D% zV>dvqYtI7fooODMfJbR6%X%Gew)9*yvpm!Hm8H^DmK7(AFV2~WjX3Cl?N!Qks}Tr| zj#CQKdU2j+T%K&iDxHihX;!IRKsKbH=ezt6Hco;}Y*c0?3*XwNZ${$yl5Jf}1;RN? zmo=w@Ex@I*Nsf)t-Ywf1;jF8_7l8}CCV-=bnq}dN^YyV| z0DfLk1|?*ir12c;S1fi11>>ez2ckO?fD6#=zgtrV}sw?_^9KNgz11)2l^jWR+YqxLXp;Q!Cix(s*Khs&!1+Nw(zuAxBW zlp=AS7T{3vy$a1qn!$`|K3h4=qoF5EswzziNrpb!Wbk(nPRz^`)$F%WQl{JgNUrvgeWV&|Ev$-Ciz|*ylg7lFYfON^gy^p3sENKTh zAir6ZET*v5ZDzo3kKWfsp4;wg1;|qy+ZJ+!Tx@Jlk$>ODoFtLK&gP}SMocBL)cfL+G54q_$aMQmx zaGUYZ#`tH?4ZlCe?>{&EFkOd@7u<`#OC$W)>+j>?+3DVk!~N}dcX_FY$G6Xd8d!>( U{MqTN*FwApe{=Z!A#VGV-$=J^5&!@I literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..d2f2aa6752f47975880d7504244b2a898046a79d GIT binary patch literal 4109 zcmeHKOK#gR5Ow-nbkj}Og`h5rP^4_jl0hq*E(!!Ff?gn?B}P`Gk3mtbn_UmkJMjhsuS zBw#67b>1w2NaGMB;i>n4QLvnc(S{WXx5`gEV_S|I-F9+EX~%sPNZPbITs;y287v<1ZR@Rp^IH|h^L3dx5#{n zy(PhjVBaU+8;qA2@EA#>S#RV0nl3@pg*V5((KM1qvyx26(=(xBqZ}QOy-2xjB?2YU zQAR*(pPr?e)SitK6OTCw`8YC+k)sAV5en`;9jmTjYG$;3*<;%1umR70UT}AA`3TCZkLV& z_+`Zfl#p|j#w(~_wb?le%1yBjSXVdz7ofSr(jP#BvTQJRMwNRCntv;3VE?Yr07BoD z18Cm0(Au)=y#~zJM-A-X7250?Xc_=C$_Rmu+U=l${oh0DGTc=kEk75~R$aPi4F#g7 z6pQn;0E33^MR?BA3}#I8-SS}`4J}btRcTUi4szX6i&CebqcpDb?Y@!ZP7!gvzzfV^ zX$8Ro48(RM(==x=Y@w2EnDPqr%GRt?j6QA?+xncwasxjC7`8V&O*V36&#~QjOV{Pj z(yh9(BPMLCjH0ZLd1I|AYY~CHoE0_8Y-=a8l^vj9Zd+f}(nmM|?plC(A9;$c*HbhF z{>5o2Vh(%VVGf*j=W}OhK5Ne<0h*hG)$~<-b+GFp|E7Z_OGXY~^09>n=}FWQYE^|- zFZ)1~aiGcl1o}@nydS?i#_v8f{L?Z1>HXj*WKeMgEuepzQV-C~R2*5L8SwvbsRvCj zsTPA7(3iT~_m~@?#Z9Gt``*64l7oN^XVdI{QuYr94u^`z|v)|5N*t669*M}4F`t_B4`f+*t@%y{UMEt>LLW-i~gr{Xu zq3b-uC-BfNDXTy-*DYk~8ZDwSPK#u&*Zlm**H6L&JTMCnG!3^Fp@l4LC`K&gloO!= zBq!BHLjse=A!x!=u7RK+ISr!~DH5ucmoy`5jTEs~(Ilq@*Q)e}VnZq^3n2~YOUHG+nXfFBrn0O!VSI7UL~O)C2W+oWu3L>jXmp%X zkk*UyG~@DQBUb5TWJ$A1c>#K^OVPqapVx`5U8ON!!H<9m%PX2DD?ZmfQ*Ta-m*ur4TXn8S zgy~utMOhuw##>d^ECPQyDQc4G+BMJSdVm5?*S-kSM`i%hB?I?9nhLR`9pr%gW>K=3 z!dkbP0lPhUUl)09yRQ`>Pi<^l$Psd}u{}lpLmP9Fj1GL~j4eD!Pa;UDRS{lE_JOv> zfwp!N=;t`_X8iUTzx~qiJ7fILZtz>ypyDhvgZ^nsJwUFiIBSMnkUw*&2Td=D7PFl} zsoQ;z*#Vk8RO*lK?cJ3e1Z+5)+})(?9}FA})nVYg|AD*rbFz8JO~-+o{=I?QjDI%9 zKYMBT{V{(3rQwI^I&8e)LHu1B;h(+!J|3Q(?!7wP-+p(OmwI^o{3fV@rMStToxXW1 P#C!0b!}qPY?N5FKe|v3O literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..ec11bdf78d5c806840a93a75f3d1091067b6e731 GIT binary patch literal 4109 zcmeHKOK;RL5Z>}S^unbQ*CB-|K2Q&G4`oD5mFd!K#Q9-h9!L9Rq!#TP2I({+j4-h@AvX#p zsFZ-Ep!NH92}G7eAPG;k2aJ*yEQ;5(Oqo%AU^(3wv`mber3EX6QD>KoSV~B1NLGYx zVyT7Z7FEKc0UogwL+^rR4yGfQSbC|qR!u56jo&jK5o<)~{g^WLkvT*gK^IwA*=YST%C zQlh7{fYLrY&vKzWn~+*2rz@7%Iv0=)#Te*5Ka@|Cpb{HbdBvlbjvd&sbYGF3X(d2~ z;MuAXY;**ew6^hyH95N@dqvU}M9%;_9cu#j_xe&eRQ&otPUL0aBEJpbWTWAEv=(A> zWLbb;)Qm$3S;twjg!+}6y`!Mq7VC(0g#&N_nlmo_5i}^v7GrNzx+kFpH-ZNCZwn0| z3|%>bHs1-YE4#sKz`Q$ZVE?wzydBUK0BDp60u{BJK?D1LhSq1euRc8-{1}fa4x~!oCpb6 za#CG3OCZuX1W9ZcE_9I3Kr*UYTwsm4UCzhvK?x{09 zb!}w&p67cXO!L$PJW5h&)|+^zrek}i*=Z_CrCD*p`0|2@*a$}lWG_-~S_xlBbd(a1 z+RKYHEP*f6ABD`|h2ih73 z+S*T`pTptp`0X)%`=#M`#`vB6;J2(n#aU<${nM1XkEW{PtT~zj|CvkOZ+c0znC%Qo z-R^tL_R;*IQh$7J@2}(_V8huo-A~H?!N9>#9R|+*AGmuzC)|LALC~Ka64yzzfq0Fp4c47yo2r87OZ(K=06V^b9>s zPtcWY`3FcD7?>%YhQ!gXc30p22A!VlzTKb6*RPs?`gw4GzI~X@*LT(gHP$>aR zLFrDM;{$Kuw&`IB0JMcfC|C0RU_Ew z2ry~g$0ye0?2haeNmmd(1MGCH3EbQDrEsYD^?{to%fLm8Hh`0jhUd{*h|Q5@0e(?4 z4kctAXUP)kS8n!>f^u7|Bi0=bzy)Z|xb#QRpe$RAy;13&gcdvs8rXj-G=MO4mf)E);7?Ee{BpW(jxNOe_0TlMK84HSr)QZy;D z5)5j35Mc$)a+opgcgKf$G`2)&U1w>@7|8WYB}%Mej*_G)Hd{uL?|EV9>%r0qf(00e z-AE=`L1EZJC7UqiCFrH8SZ6l+yh%;tDoex~egtgTUb8G+i>0}+&DLA8s;&*ys!KDb z+%&2<&YOg_*6OO^G1x0;+0fiHu0_5yLliDd^iNyrA)4!o!#m1gMovgIu6|8f8g%?oZLU;ylLRPzc+CAD!Kl||U;MezelZpJmdqRt%6jY>T zQK9QRBggPCE*YO?S=hrPmSX5#u*|`9=n_jW_13CR1gFsj;~}vIgx-%hqk_euV>|fJb`P;{;OWuS zK5}Qsn_0CfI6r-oR{7^nlf=X;uW+e{~9NV`e>AoUc(@KB}!P8YO z*x(2-Y2C#q*68e(>=a2`5FG>Tw5$=_oAsq|sQ7h(9LdYTh0`X0qm7zp;aZ5zk!1mX zQ85lBWF4pR0_s<8c8-E_Q>+8lEe^m1XwI7InM%bxS2mtbUG?xXw3QMv@-{w(ID@(h7nF z7>MmiCTUJ#*g_?nFy$rag{fFe8-3a&rg4?VVhuk6Hf*n1nykgboZ4pNEm@V(E`4MNz+G`L@1vPytF?<<;D1?` zJZ7-h9cIC4k3QE!Q?ET22WYAfb}(`!UmontkbmF7f+iz}Z}`~4gY+bF3AHN2tCoGB z@i@@?_u4&RO68RK_e8h&?--+dnZ7!N8AqdD|XQ|bZobj9I0@__%ur5-fBBwNgJ z2c_=xJ>~>xeqX6SytkjP%KpK?!B8CrZu&oPw|-9U9&)pB;AVes;O@ph zALF0DH2nS;zyH$k!*m@sUT`n|E{*WdUVk4CPfvDU?eA{CyQ@n*JbrwWtAVDx$)BFQ Rc`MmF@V9{PpYpap`3>#8YiIxf literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..62df8b92e3dcbba3f99e4a3a8a3f87ed7393a79a GIT binary patch literal 4109 zcmeHKOK#gR5Otcii)^~dqDw(t7NP#O6wt~6vI%;C8nnd7YVKLW-i~gr{Xu zq3b-uC-BfNDXV}p*DYk~8ZDwSPK#u&*Zlm**H6L&JWvY{G!3^Jp@l4LC_-%HloKHV zOHQhbW(hiVZ2GGz2TOOl-)7 z;^t*c!yXI-$dYE2$^~RYGJ3kp4`JgZ$izlvR^~Noy9JsA0F5$2Afxs$Xkh=((7FtF)rZTg0@|ue7p|c|bAxH4V!S)pS_Z`ehGIIEqk1ae%Pa>93t0KH|*$3Jh z2in?Apr69w&G_vxe*3xMcgFag-Qc&ZLB&~U2L02NdVpM2an=mEz<=UW51L*QEoM7| zQn&javja4{uhbvj+q)|{2-t8oxw}c(KNvU|s>8r}{{wgD=VbGcn~noF{d)tq8UJjI zfA-w)`(yn6bHfkQb=Y{pz4*H{!asZceLOrn-FtDkzy0nmFZJ;F_C>4)n&KvZcKYhI PVDG`-9KL^w+y3M?@c?Zd literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..e6264bafe0d8f82f7cb8f4de0ee94e3dfb11d4ca GIT binary patch literal 5301 zcmd^D&2Hm15bk!{9(?I#A3#u#jj2D&cCxf`>m`?e2PUyCauf$*V>*LSczyA5#2U7fh4?I#7B_}*B ziyF0ghOgnx_(WL^oSo?)+canqm2p}mJG0?;%dL4GEU;!4EDQtp7J-8tY$-wra>|L& zfF&pOL$?GXjRVkxcPRr#L2?@8BrOb~hb>7fVVyqHz{8gORLs1LX)taCTauxqCF~+2 zRbXRFEtM#263$5UKv{q-jZpH4QNn2)xVGyoZExv%hGSp(&Xwn&t?k;I%O7p~$_CF$ zQ&~1ue8SR0p6A=%R#_@dWm$8=`2LOw6u_}gjw)r>ts)T-HjRM{VN_-%3x06ztsRNuOR{$@6$s}n4I56iM@$9!qohOzx~3V8 z_+G4!A1l@JhLbR(!A~TsK}V6=!=+kUR1M$rr-}xhPe`(nb*LTFJJMu)|A}M`4Z{2p zTT|AdfmE!8<{~H0FGBm|v~WFVVbMB^ z)?Ku4JKq$7=$=Lob0GMIHS_X8dJN0<6(HPo$u1 zChlu>WUt{hzgExMPQSZhzqqDJP76LTppf+}z3?4%eOa<)uN#`)L|-(ypl@~)LBq1( zp7ZL;vY^-Snlfnj)^!^10DK`F3O97hZf}Y;Fow)NVb&9;-kFlMx6yA^Vj7QW%zwd$zlpJ z&`DU?RC}>Wr++e>VQ8ZLwzVO`?3($Yp(1c(Gj>`t5IyX?#n_n4ps)GojfO&Q2C7P) zH_}RWeV4IXSzPJR~L?lHugu)M_d2GwUKLo zbk=C?UqDp0fW8)qlR!?uAEu&%Ex!=7&n5t(2OJy+TRrYt6tc9SC&B + 1.1 + + + 1 + main task + 3 + annotation + 0 + + 2021-03-23 10:51:31.802079+00:00 + 2021-03-23 10:51:33.335038+00:00 + 0 + 2 + + + + + + + + 1 + 0 + 2 + http://testserver/?id=1 + + + + admin + + + + user + + + + 2021-03-23 10:51:33.433333+00:00 + + + + bmw + x3 + wrong_checkbox_value + qwerty + 0 + + + renault + x3 + false + qwerty + -4 + + + bmw + x3 + false + qwerty + 3 + + + renault + x3 + false + qwerty + -4 + + + mazda + x1 + false + qwerty + -1 + + + + + bmw + x3 + false + qwerty + 1 + + + + + \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip new file mode 100644 index 0000000000000000000000000000000000000000..bd4acb2eaa764e0faa6cae38377735fa31637ab3 GIT binary patch literal 5241 zcmd^D&2rl|5Kfx52VHt-9)QEn^b(r{Nl~&Lh`sgVi>K4+RRfVQ&6>N%}BBDXR5o}9>;uf%rl#~I&wi+tdrj9uy;XP%B-K`%o zN;r)I7rD+k^3Gk)aL|?STzQUlfn2n_e235#0&_}InXAj_h^A+Go{zi>rKu#9X2l8P z>suy{4u)RydgX5%RL(@u~4*V+#{akrGBy8ww8LF^I3l{v~ zq6-v?6U%A4q7)#Uvt(0qsx2{O=u1hC3}{7D8uGOm?=LIGvYL}kN`s$CT7it3YKu#; zBrj{e<_{$e8k=yLdeT@rqPL_@`T8SCYZ`2_Ew+cGv4Rw=gybwEj}e(MnhOhXxrK@G zsqM}m!(-zkbme_UqNI3UZ%C6TIAaHCILQ|~XSQ=^JIKOkbwPMX!}}>N_?6Yu?t`?r zDRw6~;kLPKll;)iKC2Tr-92+s2#Y5;;KPB!L7Ji!g; z^NB7vpU>tqQR=3n0q#LUgAZ(vfcY3umr!Agd>=G%i`5}oz;`-UPufnqyKcX@qH#uZ z-Vp%ET9OWYd(~Y+wk&U5og2uDx)!wcZNR8m8r*SSUfDL(8eUNbW!?TMiB{lz!R&w= zies}kMd}FMW^u92DN}sddJXnuSt3!EfN#5bZ-S+BBO( zE7 z>^2M(F0I8J#yo|kEgyytk_dgB3FZ4e zoxZx7fv8(gYxKp)47RMu>LtNxX zf&oz~iv%)sWxBqF=4Xy)Ezx_=w=VoM7g;WP?<}l^e+JRH0N;-zcXBMc#%Q$V12O!( zc(ir*>194Y0HO?x*1>k`cP$EOl2a`~+)pG(7n7ysKpYk#CcbC6FrI%p4o;hm2mJZ+ zIq`xq*w5D{1j6ZU48nR-B#{<@(;zB!0GAxd1%X$oyE2!q<$wtQFW@X8S0sl42SViw z4%cV{sL=*bsb64!*dia>+>rlCZ>>TR?D3`<8#nZ{=Uo zfCv)Q64NQAW@42k^h)4$qr0X1yZ7IG_)7eJ{PpSM&wnkN8z9C1_rN20UU0&bBCo6_ zOVKU78J{StfU`DT%P|d_M@5|E+qGHqhw0M1#S^5N;fZ0O)&jehi)=**K}Iw@#zWGGbn&L2fLiUh# zXdo3Up*hLOOH3w==E4Icy>M}OYP-W@cx-fruh3^CPKwK-Azi)!j0UdfC@dOx(s+{w zZs$cIh;}r390S2GtR9yS(qmXOZvf$8pKPOWXmu|N0;kP|FNN^<1^|A4qKrR}%mk%; zQ3&!n3n?3u2;(cm-sc-&n9fE*Fr7_i6VU?4R|C`+39Wn}`=BtNE7T?Q>LNcbny9VS zku!(a_*y+`JMHee{i2F)Gn(^`0fnq(>4op8>&ucYdtKM`2Ku7O;kMZg1T{T_H7cc0em6s3O97h{oWL-V|1HE#ZwL)vp1>1pKMDc&Jw`3qk9z!qe=?n z!~V17!>FNqLZqsaZBFSa*TUypJP&;#yPu{|TxaE}am8O)?qa!G%+%1)D#C7|fwqGg zN;0yg1|Vm`tS3&rHYIE0SihB9(|Af^zJpQF0r8F|+Z|t(kj0~nx zL{VDDbnmSyY8HXNjN~;*O{3u{*jmBNG@ixMx4@CngbduTthr#zHB6B!(|FkwET$j> zoh>Wsaw9hBwoisLbWOC~wl+kVxNFRvmWslWUEgg@EZW}d7JYLvaa;FaH|mPHiB+Y1 z-AF5cCY~N|4hGnwX=70q>GQV8&&0zujl+19MFMwrZF+&_%&uJDS~xd;U@e0y&#^q` z#)YXhxPs6uAp}}D&LVk{2*4!qIxe3n0;dAd!mb4&O>%lB3IOEUD8O|E5!8Q1jgK)ezWQ!mO*xM*Xbyy_v_!vNCa-lT2kngfK0Rh$1 zm(@v^go2pOWmp={fLOpykv4(=8&BHkl28zxP3nP-XSondsDVJhS3@5vUlZyQNz4Lk zAtaoE8e~KuZ3NNT=#o$ntxb1XJw0W{*3N&IGRJr0M2-GT_jU?H#6eMkkw_* + 1.1 + + + 1 + main task + 3 + annotation + 0 + + 2021-03-23 11:10:26.125292+00:00 + 2021-03-23 11:10:36.600819+00:00 + 0 + 2 + + + + + + + + 1 + 0 + 2 + http://testserver/?id=1 + + + + admin + + + + user + + + + 2021-03-23 11:10:37.178974+00:00 + + + + renault + x1 + wrong_checkbox_value + qwerty + -1 + + + renault + x3 + false + qwerty + 1 + + + mazda + x3 + false + qwerty + 3 + + + mazda + x1 + false + qwerty + -2 + + + renault + x1 + false + qwerty + 0 + + + + + bmw + x3 + false + qwerty + -4 + + + + + \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip new file mode 100644 index 0000000000000000000000000000000000000000..a16f9dede183d9a698489cd78d7e3dbec8cd1bdb GIT binary patch literal 5247 zcmdT|&649Z5T0d$LoOWH2XL7qiGSocKeLLtahWP=3b=4eDYhmt<3D71lgy1L;3c^7 zOgsv-WXqP5%#NoRc41PJNc|_NTm5z0w>PgpeRC!Le)wts{U6``_UB(;UR{a*FMvj} zEa!yBc~)A7G{M?D7#RkBM_CEXz_na#tBGKwloKHVLr%*3dI*y^3P2LRB@YN0NokOh zI5UJCw&h$g%lLr?9=7GLBBpsngKi_(mITGkVHXK00tee_s92k7%NYspDKqSL{g6?@ zX%rv_xf92mAkT2!YuC9(Gs{IjTB5HV=h^{tN>Z7tis-VYH?wArvv8M6Q%Ne#k`u<) zcT5}|4C~WQBrh5XBqZ9I5|G;KyEx&!<0NE5lTw`y{3{9FTzNbstnX_XsxVJ-7JP-A zg%gSs%W1Qs6d;_lcvEqzEzxJ_OG%ClXh{=01u0kx$x%ukA~Iq$6Bgid3lpcO zwp)MnkBuLpEAKNB#rey6Lz;YsGY*i3gM4vtM+Y=IKo-8J3&I@@?}xbHM^+8H57Oc$ zKRm+;clBi(+om>&b`0xE2tor5NBusU>R@EMNPgSOM`uH7##={BVq zZwUZo4M_*Sv+6D(Tb8%B&h_L)T??A})?-vG33i+p*R~C{hL@BD^pa6wZJ5oz z6>N8%5{|00xYU(+bIYACmh-9VEgC`CITX#N>B4bJw$#|sc)Q~((|1e*JZHj>IQ7bu z?6qV4Tx?BaA4hz*GF`_p>(gMsP-DyTs#psx*EHl+U764`m_{CkNfpuBT$xua1cNEb zDw3GSVZ%USY0aiE<_Roq`7k_6GW3W`7z?szi9J26a~4t1P%Fb3+QQjvRcjo~pe@F& zl=AHMvLcWpuqC!g*5~;gUR_`u?+!fLQ~|) zahqq4LWaxCP$b)h%)#}J|g1mHA$A1olyOg!xu zJs?f-eOl?CN8nNb8nh z?PbM(ISA)_!?p;5aC;Mlu-fEtq{ZNQK$WdLX=sieLfJ@-O6Qw6~cW9OP7V5ikO%GK zndiV+!XeN^i(WzwFLxD?8G2XYKGs##FxU$~ua{6TIYrjeAA68<&@G&VsB0O9LZf`< zKRMim5dUw0Q9P-f97iCdDEh;~1(iw<7rGd(HtMig_XaSyy?OP?o7a!OEtIbj;p_Kb Y#Yoc>?+$NoKKopdU%_Vuzhi0VZx5LOWdHyG literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip new file mode 100644 index 0000000000000000000000000000000000000000..be24acd0d8c2492f8afde0430f368a9acc4ecc4d GIT binary patch literal 5301 zcmdT|J9FbU5YFY26l&7k58yCmEIvR{l6?@}rE%lA$<-Q=gk{Ej1q9EuyL9;>`DH2c zJ8l6IB&bJBdpzUB8dKOO!TlDyD_&o{|L(&#;_vUz_n-b*{Q21jQvCl2Jd)=HCp;;w0Z~%$ncK*XCs~!Dd)Imn$m-W+*`>s%~W7mjDG&^dCJKReEa1D=(p zvaHMagr#q-&JkMs%2H`6%Zd}mw>L~g0UYb(pi-2b1`--Qr4*#~_9jWWe6kU#bW#%1 zv{F%rxJ$-BD@Dp;@P9z>*lAUX*KsaYfSaYh~Vl2>aB_$H*il#K; zTd_X8tyIfuPQsK1zmT*79Ytz4mug8~)_lt!N*c62A;|{TzIIG+NS*TS7n0UA2(x=^ zk6HT$Qn3=6vy42(WX5PNJV4S57yD0b_wg7%Ha@{u(Pt!1ir0;Xboq>6G;lm8#iDU% z4VpD@I$t#e(JhVcri9>ER!_?Z=`k#tX9VGC3 z#7t1iuNs29&O*wjB*OH{(E5Bv80L$KA($^_i z7ERpM>d0BbXL_xkw4H8u{eE#pcNxuj&wxVKvGl@s(Dh}>mc6cTdLw<&W4TCbO`gVfN`DZ*}{ zfp&u#PBOBi21L$;Sx-Fm#+0nBWBpd{OyfR@`7Mls4v24Qvb*IQ(|64FnK0B-LuTs6 zgpt8CiYQ9!n6}=kqGl2J%Sc|6)HE8Ng01B*OyfZ;JqsKeO~}CgxwRB*xrQn7+%z7y z1&b-jKxfB_y4;FQy4{`O8TuyLZCe{6%%E?~y_Q1Zz;5WaW+2+$(-uQ>GJ~$}KW)?( zb2Ctt@@XTj{F%WVj>4V^46sGhVNn+8!>-6r;NhCaJ|1O}z?t2c$hVxunG4gc^U;H( z@z0QBA?KsJw3hxEK(hu2G&oL1a)f{!r}nmc1hrB0VTyR#;*Fwzm>JmaLaqUjCOJKU z00i+Q0xQdfs4oQqzGop=FUC;^_=ZD(CLV&9Kya92M?iZc2%wMcrAG^a2zrM>REI?p zPe%Z1k_$!2g-n-K2?%dxd9p6)l28zfr39tn42Tt+5osd`utCyBmxO}oZBhg_$Z`Qm zsD40rOUr|r*Mz!65)1gbC?uSL8svj7Z3NNV=#o$nolSpCk)AM9tET)>a}eYs3Glx; zwPJKT$eA`tx{TpuH%gbiGdiu359s`s({11p6I)Ht-!vKVJa_;196? literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml new file mode 100644 index 00000000000..34117858730 --- /dev/null +++ b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml @@ -0,0 +1,138 @@ + + 1.1 + + + 1 + main task + 3 + annotation + 0 + + 2021-03-23 10:47:03.729206+00:00 + 2021-03-23 10:47:05.792285+00:00 + 0 + 2 + + + + + + + + 1 + 0 + 2 + http://testserver/?id=1 + + + + admin + + + + user + + + + 2021-03-23 10:47:05.886102+00:00 + + + + renault + x1 + wrong_checkbox_value + qwerty + -2 + + + bmw + x3 + false + qwerty + 1 + + + bmw + x2 + false + qwerty + 0 + + + mazda + x3 + false + qwerty + -4 + + + renault + x2 + false + qwerty + -2 + + + + + bmw + x1 + false + qwerty + 3 + + + + + \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip new file mode 100644 index 0000000000000000000000000000000000000000..295706cf93576a58e001f55bac92ce26c866090f GIT binary patch literal 5241 zcmdT|yK>_;6!m746lzjrKY+u`q*wWc=CY+{W?0QUjlp8FDSZ(e@>>P-Co`P1fyKYn}n`(Iz5or(Xi zV2xy1&Iyn6thBaig0*=tF%0~cvJ!}aYq{7~6G2ERCxQcpoRkms5GHXH04ID)8Z2Za zr9n#K%n*FomUBfc<3}2J*p^SVnC1};x`SX_E+}dar$|TPq>=+ak`ic?9J zoG`w;W8&(dSf6$*dC_nn!O_kXgOpz0#R>0SCm}1El1S)Y+8&Y#yBQsoK8*g_bNvc=Y&Y|&&3QTVJT2=8h5FvbKwvTB?^ zNR6v}dx8<}YG)f|hlclAjlk*lnS(-TJi!3JY$)Tqk)EKKpVb6em98io;|Sw3L#^`! zGh9qZn&4tOnNCEh8=nnumn5|Gf$hD-d@NBHP+{}zFlpi@SBK6FKI3!ssN*!JYtM^I zx=v}v+XYBu&61w@4ywCM*|NN~b*{%R>RQm$w;rKlNpR13ac$dBYj{Z+ly&>NI9h=5 z1+h)sP#o*Csik(IJuJ>Q8D)wNN3TGiEK4LxW3X*I@3c~ANfND1uzNZ%Da&}BQ97hl zXd9=quLav(r-Y*_Ee5+1-@3e5;*uFNYI zg2I$!6-i8EyJ8@4WzD8A<_Twn)&Ad(Io(|58ugv z$c}37xC0>ez<@^LX$c*Srtm&3^v|t-=qT83Os)Zt#2M8B1brYtS~%vG3lPi%9KL5E z7*9V8f!jpmfH`|H@i7n_`q;oOp9lgdWqU~15D23;7=+a-k0T9%(^6F8LSAwq3`D+4 z(88P}%LNsXynr%?Fp(4n6oASX6t2r~U54v2T$9u9g>%|vOCU*@;!ZK_A6$E42x4ui;m+4D& z0TCofSvB2pCYf4e3HwXn+r{n4K zCQHdBd|96uuYj|)J>=RJ%cCMr^8MDX#m)TOz6@r>FbiguMOur%LmqK7Aq5!|RBFId z(CY561R{w8(1dR#14d3W7GyNZEvZKwMQdS|JhH$ij{4QitcY3AZ-h9Cp```vBBf>E z5=Sq!D6IE_)98-zfH(%BC8usFaj_U5iX$G+vc7udV-FgoAhjl25UbuV1-tTnY| zUB)LYedPM<^%`qSt*I?5LAlu7aESsqHpyP4C|eCIH9ATwDC^x#k_vUQ0jYIT8nU#~ zr~~eb(bGB-5#_@es1Qa)TJYc}?4G-kJia1Z*Ghp3!IQ8S%y`65U_MGoRG=%CvPkUY z`uMR*Evp3$Qx^O}(+YGnX*^u1C3#tkop>l&aPSF9*0aXiF}tC4Dt4b}TC*U`?uj#G zjSZAyB{gRmeT?ahvs`+Bq?aznr*=9#hQ}r+_!@mq|<^>?!9FlDk4z2F1f*@G)%9lcVd;tKz-7_v8CT47fsUE z>d0NeXL_xkw4HW$-F`{M_8H4X$ACiCvdqGF)b&-#R=uukdINpgp_@ zj1Pz3mJg$b>50&)O7=NpPq~&pU*dV_i#Yu>MdCUupBz_w9sZQUoaxP?*B1@SFQ_P1hdFJ1d^CIa=;QklB7VPvqa zB8t*FW(RLoQS%7=Wi+p8YFmv+!4@qSw)G&FJ_1Kp6LN6BK`Y5tYnUQ8w)MCxc+5Zs zI(uH!|6j&IBHsogs>33Qr-uQ`k_UCk zgM3$o2?&3Ud{vrENhpcMN=2p-9EdgC6lEg`u))g4l!TJ#Y*Gw17?9dIrb6^7@XzIpqBmg0QqT758jmN;n0Hy;Q#9Y zp?lT>qs{Wnhg)IJ37<2=zv|v}oJX=Z$@YFaTu>X#aN%de)kPf=qkm}_TwlHU_TAgl hFBsLENBH{Vceyew^Jb)!tYM``3Giv4e0;? literal 0 HcmV?d00001 diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml new file mode 100644 index 00000000000..39e1cb6d263 --- /dev/null +++ b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml @@ -0,0 +1,138 @@ + + 1.1 + + + 1 + main task + 3 + annotation + 0 + + 2021-03-23 10:21:12.892906+00:00 + 2021-03-23 10:21:13.037772+00:00 + 0 + 2 + + + + + + + + 1 + 0 + 2 + http://testserver/?id=1 + + + + admin + + + + user + + + + 2021-03-23 10:21:13.132793+00:00 + + + + mazda + x2 + wrong_checkbox_value + qwerty + 3 + + + bmw + x1 + false + qwerty + -4 + + + renault + x1 + false + qwerty + -4 + + + bmw + x3 + false + qwerty + -3 + + + bmw + x3 + false + qwerty + 0 + + + + + bmw + x1 + false + qwerty + -3 + + + + + \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip new file mode 100644 index 0000000000000000000000000000000000000000..88606cbf2450070ef93914c729d83a0d9d13b862 GIT binary patch literal 5238 zcmds5$!_B|7|wLs9(?Jc^8kY8*o2ZOFL6dzZ@mNsf`Ebm!gl@ zQxE+~i4rB-6L}h-OM=AYzmfd@6~4QD{pFhr@$>up?fXBgAAkPi+lveF_YKfUmgSuA zIL}J7OA}Aq`xC?PK2TNy(|3^LS!yE~Ddj{+z><^lv0lO^4t|B?rUjHJ|0Nt_u% z&a>oRG0XUg`mSfmPen}gkow(4JWCQ3H-}p!r0{LeQcK0!R1s$+c%;m*+VcZO38$ft zZR}jx?iF?o$G*YNjf2tk5-;ufceZ_FgE=Ls%vD8rLeoXIyI3r+(o~X4v*d*F^*s|$ z2gCZd6UmE40t<PzC(4JGyg5NukAp* zSZLra>_fUm{+@K`C9R-9}S>ipV9&H&-Q z4z^J^G_o%W0;jtdP6}c13;=%JQpWcqBS8tjCl+uj11Sn(; zNiTc{-CdS!+1}bd*OM20&2Rc!k5RG2f8e~hu`K8{yrc};y7he=t^j<&YzsFu$NFxH z)Dqgudige^O!49B71)z)iG*nk*tYx5Dut0G(Z&R;XTu|98AlnV$BYVV<81b=cvd$l zd0~|nN2d}OIWAr-T{T-Yf^c(an$6JV#VLuX@j&C~fv?P&Z5n`_2_NFsD^s%9Hu|NA zOk*2|{9$D}wr$q0@t}qp5zDJ$EwmidkfFLVVP-ImJP491q_w#+uUG&EQ<7CAF^%1Z zfx;5ar?BP;9F1nM+)Fadh)Y-tvWvu>p4K@FDQKvZ;SFu$Y_6&e4knC=(2}(PR_GsS zb^X=!cMxB#)sq@sJ2L$(%d=>$+DSb;jIq&HbJJI)^7(_c`e%w!cc9@};El#FMV{=V zJUihI@Kce;kfSRT&yYR6bX>Hs-?=k%J-fsi@G4{9HFB)@*H=8Tu4!FmO*d zDU7X)pW~{3b#FQr;Wc#Q+y!k)cNaeDuGZ@i7~L0t{@v}XFW$U9{UxFN_7ML4_ED@f WP4SiC-R)Oj3-T-YUBTyDY3DEcUi=#X literal 0 HcmV?d00001 From 9d848bb5e66be641ec91c834bc72bb98e4d57b30 Mon Sep 17 00:00:00 2001 From: mzuevx Date: Wed, 24 Mar 2021 01:16:25 +0300 Subject: [PATCH 09/43] Remove extra files --- ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes ...mp_and_upload_rewrite_CVAT for images 1.1.zip | Bin 4109 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-b67lk9ts/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-luh073az/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-mpty4d21/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-r8hdbd0m/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-4mddxsch/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip deleted file mode 100644 index 6d0ddbd50863972d3ce1915f4492573aacbc0671..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4109 zcmeHK&2rN)5Kbv@=!Hukz+;X~<^RO)DDDIF(%}U%imf`P{>jL4Tgr(C;2Gc{IKhQS zV%`dzrMVgOvFFDC!{D!PIy`t z6}rwdd;$;clClaUbKOFwuF)bY$vJj%sGO-~E zCC$s2hCMuNNP$`f&kS6L4mK32mX>wG8Hp|^3$Za^)Oy4y;WQ3y)3%OG=g9Ik%R9D% zV>dvqYtI7fooODMfJbR6%X%Gew)9*yvpm!Hm8H^DmK7(AFV2~WjX3Cl?N!Qks}Tr| zj#CQKdU2j+T%K&iDxHihX;!IRKsKbH=ezt6Hco;}Y*c0?3*XwNZ${$yl5Jf}1;RN? zmo=w@Ex@I*Nsf)t-Ywf1;jF8_7l8}CCV-=bnq}dN^YyV| z0DfLk1|?*ir12c;S1fi11>>ez2ckO?fD6#=zgtrV}sw?_^9KNgz11)2l^jWR+YqxLXp;Q!Cix(s*Khs&!1+Nw(zuAxBW zlp=AS7T{3vy$a1qn!$`|K3h4=qoF5EswzziNrpb!Wbk(nPRz^`)$F%WQl{JgNUrvgeWV&|Ev$-Ciz|*ylg7lFYfON^gy^p3sENKTh zAir6ZET*v5ZDzo3kKWfsp4;wg1;|qy+ZJ+!Tx@Jlk$>ODoFtLK&gP}SMocBL)cfL+G54q_$aMQmx zaGUYZ#`tH?4ZlCe?>{&EFkOd@7u<`#OC$W)>+j>?+3DVk!~N}dcX_FY$G6Xd8d!>( U{MqTN*FwApe{=Z!A#VGV-$=J^5&!@I diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-_96frxa2/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip deleted file mode 100644 index d2f2aa6752f47975880d7504244b2a898046a79d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4109 zcmeHKOK#gR5Ow-nbkj}Og`h5rP^4_jl0hq*E(!!Ff?gn?B}P`Gk3mtbn_UmkJMjhsuS zBw#67b>1w2NaGMB;i>n4QLvnc(S{WXx5`gEV_S|I-F9+EX~%sPNZPbITs;y287v<1ZR@Rp^IH|h^L3dx5#{n zy(PhjVBaU+8;qA2@EA#>S#RV0nl3@pg*V5((KM1qvyx26(=(xBqZ}QOy-2xjB?2YU zQAR*(pPr?e)SitK6OTCw`8YC+k)sAV5en`;9jmTjYG$;3*<;%1umR70UT}AA`3TCZkLV& z_+`Zfl#p|j#w(~_wb?le%1yBjSXVdz7ofSr(jP#BvTQJRMwNRCntv;3VE?Yr07BoD z18Cm0(Au)=y#~zJM-A-X7250?Xc_=C$_Rmu+U=l${oh0DGTc=kEk75~R$aPi4F#g7 z6pQn;0E33^MR?BA3}#I8-SS}`4J}btRcTUi4szX6i&CebqcpDb?Y@!ZP7!gvzzfV^ zX$8Ro48(RM(==x=Y@w2EnDPqr%GRt?j6QA?+xncwasxjC7`8V&O*V36&#~QjOV{Pj z(yh9(BPMLCjH0ZLd1I|AYY~CHoE0_8Y-=a8l^vj9Zd+f}(nmM|?plC(A9;$c*HbhF z{>5o2Vh(%VVGf*j=W}OhK5Ne<0h*hG)$~<-b+GFp|E7Z_OGXY~^09>n=}FWQYE^|- zFZ)1~aiGcl1o}@nydS?i#_v8f{L?Z1>HXj*WKeMgEuepzQV-C~R2*5L8SwvbsRvCj zsTPA7(3iT~_m~@?#Z9Gt``*64l7oN^XVdI{QuYr94u^`z|v)|5N*t669*M}4F`t_B4`f+*t@%y{UMEt>LLW-i~gr{Xu zq3b-uC-BfNDXTy-*DYk~8ZDwSPK#u&*Zlm**H6L&JTMCnG!3^Fp@l4LC`K&gloO!= zBq!BHLjse=A!x!=u7RK+ISr!~DH5ucmoy`5jTEs~(Ilq@*Q)e}VnZq^3n2~YOUHG+nXfFBrn0O!VSI7UL~O)C2W+oWu3L>jXmp%X zkk*UyG~@DQBUb5TWJ$A1c>#K^OVPqapVx`5U8ON!!H<9m%PX2DD?ZmfQ*Ta-m*ur4TXn8S zgy~utMOhuw##>d^ECPQyDQc4G+BMJSdVm5?*S-kSM`i%hB?I?9nhLR`9pr%gW>K=3 z!dkbP0lPhUUl)09yRQ`>Pi<^l$Psd}u{}lpLmP9Fj1GL~j4eD!Pa;UDRS{lE_JOv> zfwp!N=;t`_X8iUTzx~qiJ7fILZtz>ypyDhvgZ^nsJwUFiIBSMnkUw*&2Td=D7PFl} zsoQ;z*#Vk8RO*lK?cJ3e1Z+5)+})(?9}FA})nVYg|AD*rbFz8JO~-+o{=I?QjDI%9 zKYMBT{V{(3rQwI^I&8e)LHu1B;h(+!J|3Q(?!7wP-+p(OmwI^o{3fV@rMStToxXW1 P#C!0b!}qPY?N5FKe|v3O diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-h8n5t7tc/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip deleted file mode 100644 index ec11bdf78d5c806840a93a75f3d1091067b6e731..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4109 zcmeHKOK;RL5Z>}S^unbQ*CB-|K2Q&G4`oD5mFd!K#Q9-h9!L9Rq!#TP2I({+j4-h@AvX#p zsFZ-Ep!NH92}G7eAPG;k2aJ*yEQ;5(Oqo%AU^(3wv`mber3EX6QD>KoSV~B1NLGYx zVyT7Z7FEKc0UogwL+^rR4yGfQSbC|qR!u56jo&jK5o<)~{g^WLkvT*gK^IwA*=YST%C zQlh7{fYLrY&vKzWn~+*2rz@7%Iv0=)#Te*5Ka@|Cpb{HbdBvlbjvd&sbYGF3X(d2~ z;MuAXY;**ew6^hyH95N@dqvU}M9%;_9cu#j_xe&eRQ&otPUL0aBEJpbWTWAEv=(A> zWLbb;)Qm$3S;twjg!+}6y`!Mq7VC(0g#&N_nlmo_5i}^v7GrNzx+kFpH-ZNCZwn0| z3|%>bHs1-YE4#sKz`Q$ZVE?wzydBUK0BDp60u{BJK?D1LhSq1euRc8-{1}fa4x~!oCpb6 za#CG3OCZuX1W9ZcE_9I3Kr*UYTwsm4UCzhvK?x{09 zb!}w&p67cXO!L$PJW5h&)|+^zrek}i*=Z_CrCD*p`0|2@*a$}lWG_-~S_xlBbd(a1 z+RKYHEP*f6ABD`|h2ih73 z+S*T`pTptp`0X)%`=#M`#`vB6;J2(n#aU<${nM1XkEW{PtT~zj|CvkOZ+c0znC%Qo z-R^tL_R;*IQh$7J@2}(_V8huo-A~H?!N9>#9R|+*AGmuzC)|LALC~Ka64yzzfq0Fp4c47yo2r87OZ(K=06V^b9>s zPtcWY`3FcD7?>%YhQ!gXc30p22A!VlzTKb6*RPs?`gw4GzI~X@*LT(gHP$>aR zLFrDM;{$Kuw&`IB0JMcfC|C0RU_Ew z2ry~g$0ye0?2haeNmmd(1MGCH3EbQDrEsYD^?{to%fLm8Hh`0jhUd{*h|Q5@0e(?4 z4kctAXUP)kS8n!>f^u7|Bi0=bzy)Z|xb#QRpe$RAy;13&gcdvs8rXj-G=MO4mf)E);7?Ee{BpW(jxNOe_0TlMK84HSr)QZy;D z5)5j35Mc$)a+opgcgKf$G`2)&U1w>@7|8WYB}%Mej*_G)Hd{uL?|EV9>%r0qf(00e z-AE=`L1EZJC7UqiCFrH8SZ6l+yh%;tDoex~egtgTUb8G+i>0}+&DLA8s;&*ys!KDb z+%&2<&YOg_*6OO^G1x0;+0fiHu0_5yLliDd^iNyrA)4!o!#m1gMovgIu6|8f8g%?oZLU;ylLRPzc+CAD!Kl||U;MezelZpJmdqRt%6jY>T zQK9QRBggPCE*YO?S=hrPmSX5#u*|`9=n_jW_13CR1gFsj;~}vIgx-%hqk_euV>|fJb`P;{;OWuS zK5}Qsn_0CfI6r-oR{7^nlf=X;uW+e{~9NV`e>AoUc(@KB}!P8YO z*x(2-Y2C#q*68e(>=a2`5FG>Tw5$=_oAsq|sQ7h(9LdYTh0`X0qm7zp;aZ5zk!1mX zQ85lBWF4pR0_s<8c8-E_Q>+8lEe^m1XwI7InM%bxS2mtbUG?xXw3QMv@-{w(ID@(h7nF z7>MmiCTUJ#*g_?nFy$rag{fFe8-3a&rg4?VVhuk6Hf*n1nykgboZ4pNEm@V(E`4MNz+G`L@1vPytF?<<;D1?` zJZ7-h9cIC4k3QE!Q?ET22WYAfb}(`!UmontkbmF7f+iz}Z}`~4gY+bF3AHN2tCoGB z@i@@?_u4&RO68RK_e8h&?--+dnZ7!N8AqdD|XQ|bZobj9I0@__%ur5-fBBwNgJ z2c_=xJ>~>xeqX6SytkjP%KpK?!B8CrZu&oPw|-9U9&)pB;AVes;O@ph zALF0DH2nS;zyH$k!*m@sUT`n|E{*WdUVk4CPfvDU?eA{CyQ@n*JbrwWtAVDx$)BFQ Rc`MmF@V9{PpYpap`3>#8YiIxf diff --git a/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_dump_and_upload_rewrite-uppwktd7/test_api_v1_tasks_annotations_dump_and_upload_rewrite_CVAT for images 1.1.zip deleted file mode 100644 index 62df8b92e3dcbba3f99e4a3a8a3f87ed7393a79a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4109 zcmeHKOK#gR5Otcii)^~dqDw(t7NP#O6wt~6vI%;C8nnd7YVKLW-i~gr{Xu zq3b-uC-BfNDXV}p*DYk~8ZDwSPK#u&*Zlm**H6L&JWvY{G!3^Jp@l4LC_-%HloKHV zOHQhbW(hiVZ2GGz2TOOl-)7 z;^t*c!yXI-$dYE2$^~RYGJ3kp4`JgZ$izlvR^~Noy9JsA0F5$2Afxs$Xkh=((7FtF)rZTg0@|ue7p|c|bAxH4V!S)pS_Z`ehGIIEqk1ae%Pa>93t0KH|*$3Jh z2in?Apr69w&G_vxe*3xMcgFag-Qc&ZLB&~U2L02NdVpM2an=mEz<=UW51L*QEoM7| zQn&javja4{uhbvj+q)|{2-t8oxw}c(KNvU|s>8r}{{wgD=VbGcn~noF{d)tq8UJjI zfA-w)`(yn6bHfkQb=Y{pz4*H{!asZceLOrn-FtDkzy0nmFZJ;F_C>4)n&KvZcKYhI PVDG`-9KL^w+y3M?@c?Zd From fa665abfb3e7999a7b4d849daebd7f8dc4e73fa8 Mon Sep 17 00:00:00 2001 From: mzuevx Date: Wed, 24 Mar 2021 01:26:39 +0300 Subject: [PATCH 10/43] Remove extra files --- ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 5301 -> 0 bytes .../annotations.xml | 138 ------------------ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 5241 -> 0 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 5307 -> 0 bytes .../annotations.xml | 138 ------------------ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 5247 -> 0 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 5301 -> 0 bytes .../annotations.xml | 138 ------------------ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 5241 -> 0 bytes ..._value_in_checkbox_CVAT for images 1.1.zip | Bin 5298 -> 0 bytes .../annotations.xml | 138 ------------------ ...AT for images 1.1_wrong_checkbox_value.zip | Bin 5238 -> 0 bytes 12 files changed, 552 deletions(-) delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml delete mode 100644 temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip deleted file mode 100644 index e6264bafe0d8f82f7cb8f4de0ee94e3dfb11d4ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5301 zcmd^D&2Hm15bk!{9(?I#A3#u#jj2D&cCxf`>m`?e2PUyCauf$*V>*LSczyA5#2U7fh4?I#7B_}*B ziyF0ghOgnx_(WL^oSo?)+canqm2p}mJG0?;%dL4GEU;!4EDQtp7J-8tY$-wra>|L& zfF&pOL$?GXjRVkxcPRr#L2?@8BrOb~hb>7fVVyqHz{8gORLs1LX)taCTauxqCF~+2 zRbXRFEtM#263$5UKv{q-jZpH4QNn2)xVGyoZExv%hGSp(&Xwn&t?k;I%O7p~$_CF$ zQ&~1ue8SR0p6A=%R#_@dWm$8=`2LOw6u_}gjw)r>ts)T-HjRM{VN_-%3x06ztsRNuOR{$@6$s}n4I56iM@$9!qohOzx~3V8 z_+G4!A1l@JhLbR(!A~TsK}V6=!=+kUR1M$rr-}xhPe`(nb*LTFJJMu)|A}M`4Z{2p zTT|AdfmE!8<{~H0FGBm|v~WFVVbMB^ z)?Ku4JKq$7=$=Lob0GMIHS_X8dJN0<6(HPo$u1 zChlu>WUt{hzgExMPQSZhzqqDJP76LTppf+}z3?4%eOa<)uN#`)L|-(ypl@~)LBq1( zp7ZL;vY^-Snlfnj)^!^10DK`F3O97hZf}Y;Fow)NVb&9;-kFlMx6yA^Vj7QW%zwd$zlpJ z&`DU?RC}>Wr++e>VQ8ZLwzVO`?3($Yp(1c(Gj>`t5IyX?#n_n4ps)GojfO&Q2C7P) zH_}RWeV4IXSzPJR~L?lHugu)M_d2GwUKLo zbk=C?UqDp0fW8)qlR!?uAEu&%Ex!=7&n5t(2OJy+TRrYt6tc9SC&B - 1.1 - - - 1 - main task - 3 - annotation - 0 - - 2021-03-23 10:51:31.802079+00:00 - 2021-03-23 10:51:33.335038+00:00 - 0 - 2 - - - - - - - - 1 - 0 - 2 - http://testserver/?id=1 - - - - admin - - - - user - - - - 2021-03-23 10:51:33.433333+00:00 - - - - bmw - x3 - wrong_checkbox_value - qwerty - 0 - - - renault - x3 - false - qwerty - -4 - - - bmw - x3 - false - qwerty - 3 - - - renault - x3 - false - qwerty - -4 - - - mazda - x1 - false - qwerty - -1 - - - - - bmw - x3 - false - qwerty - 1 - - - - - \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-4l6xwovr/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip deleted file mode 100644 index bd4acb2eaa764e0faa6cae38377735fa31637ab3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5241 zcmd^D&2rl|5Kfx52VHt-9)QEn^b(r{Nl~&Lh`sgVi>K4+RRfVQ&6>N%}BBDXR5o}9>;uf%rl#~I&wi+tdrj9uy;XP%B-K`%o zN;r)I7rD+k^3Gk)aL|?STzQUlfn2n_e235#0&_}InXAj_h^A+Go{zi>rKu#9X2l8P z>suy{4u)RydgX5%RL(@u~4*V+#{akrGBy8ww8LF^I3l{v~ zq6-v?6U%A4q7)#Uvt(0qsx2{O=u1hC3}{7D8uGOm?=LIGvYL}kN`s$CT7it3YKu#; zBrj{e<_{$e8k=yLdeT@rqPL_@`T8SCYZ`2_Ew+cGv4Rw=gybwEj}e(MnhOhXxrK@G zsqM}m!(-zkbme_UqNI3UZ%C6TIAaHCILQ|~XSQ=^JIKOkbwPMX!}}>N_?6Yu?t`?r zDRw6~;kLPKll;)iKC2Tr-92+s2#Y5;;KPB!L7Ji!g; z^NB7vpU>tqQR=3n0q#LUgAZ(vfcY3umr!Agd>=G%i`5}oz;`-UPufnqyKcX@qH#uZ z-Vp%ET9OWYd(~Y+wk&U5og2uDx)!wcZNR8m8r*SSUfDL(8eUNbW!?TMiB{lz!R&w= zies}kMd}FMW^u92DN}sddJXnuSt3!EfN#5bZ-S+BBO( zE7 z>^2M(F0I8J#yo|kEgyytk_dgB3FZ4e zoxZx7fv8(gYxKp)47RMu>LtNxX zf&oz~iv%)sWxBqF=4Xy)Ezx_=w=VoM7g;WP?<}l^e+JRH0N;-zcXBMc#%Q$V12O!( zc(ir*>194Y0HO?x*1>k`cP$EOl2a`~+)pG(7n7ysKpYk#CcbC6FrI%p4o;hm2mJZ+ zIq`xq*w5D{1j6ZU48nR-B#{<@(;zB!0GAxd1%X$oyE2!q<$wtQFW@X8S0sl42SViw z4%cV{sL=*bsb64!*dia>+>rlCZ>>TR?D3`<8#nZ{=Uo zfCv)Q64NQAW@42k^h)4$qr0X1yZ7IG_)7eJ{PpSM&wnkN8z9C1_rN20UU0&bBCo6_ zOVKU78J{StfU`DT%P|d_M@5|E+qGHqhw0M1#S^5N;fZ0O)&jehi)=**K}Iw@#zWGGbn&L2fLiUh# zXdo3Up*hLOOH3w==E4Icy>M}OYP-W@cx-fruh3^CPKwK-Azi)!j0UdfC@dOx(s+{w zZs$cIh;}r390S2GtR9yS(qmXOZvf$8pKPOWXmu|N0;kP|FNN^<1^|A4qKrR}%mk%; zQ3&!n3n?3u2;(cm-sc-&n9fE*Fr7_i6VU?4R|C`+39Wn}`=BtNE7T?Q>LNcbny9VS zku!(a_*y+`JMHee{i2F)Gn(^`0fnq(>4op8>&ucYdtKM`2Ku7O;kMZg1T{T_H7cc0em6s3O97h{oWL-V|1HE#ZwL)vp1>1pKMDc&Jw`3qk9z!qe=?n z!~V17!>FNqLZqsaZBFSa*TUypJP&;#yPu{|TxaE}am8O)?qa!G%+%1)D#C7|fwqGg zN;0yg1|Vm`tS3&rHYIE0SihB9(|Af^zJpQF0r8F|+Z|t(kj0~nx zL{VDDbnmSyY8HXNjN~;*O{3u{*jmBNG@ixMx4@CngbduTthr#zHB6B!(|FkwET$j> zoh>Wsaw9hBwoisLbWOC~wl+kVxNFRvmWslWUEgg@EZW}d7JYLvaa;FaH|mPHiB+Y1 z-AF5cCY~N|4hGnwX=70q>GQV8&&0zujl+19MFMwrZF+&_%&uJDS~xd;U@e0y&#^q` z#)YXhxPs6uAp}}D&LVk{2*4!qIxe3n0;dAd!mb4&O>%lB3IOEUD8O|E5!8Q1jgK)ezWQ!mO*xM*Xbyy_v_!vNCa-lT2kngfK0Rh$1 zm(@v^go2pOWmp={fLOpykv4(=8&BHkl28zxP3nP-XSondsDVJhS3@5vUlZyQNz4Lk zAtaoE8e~KuZ3NNT=#o$ntxb1XJw0W{*3N&IGRJr0M2-GT_jU?H#6eMkkw_* - 1.1 - - - 1 - main task - 3 - annotation - 0 - - 2021-03-23 11:10:26.125292+00:00 - 2021-03-23 11:10:36.600819+00:00 - 0 - 2 - - - - - - - - 1 - 0 - 2 - http://testserver/?id=1 - - - - admin - - - - user - - - - 2021-03-23 11:10:37.178974+00:00 - - - - renault - x1 - wrong_checkbox_value - qwerty - -1 - - - renault - x3 - false - qwerty - 1 - - - mazda - x3 - false - qwerty - 3 - - - mazda - x1 - false - qwerty - -2 - - - renault - x1 - false - qwerty - 0 - - - - - bmw - x3 - false - qwerty - -4 - - - - - \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-izmre8m7/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip deleted file mode 100644 index a16f9dede183d9a698489cd78d7e3dbec8cd1bdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5247 zcmdT|&649Z5T0d$LoOWH2XL7qiGSocKeLLtahWP=3b=4eDYhmt<3D71lgy1L;3c^7 zOgsv-WXqP5%#NoRc41PJNc|_NTm5z0w>PgpeRC!Le)wts{U6``_UB(;UR{a*FMvj} zEa!yBc~)A7G{M?D7#RkBM_CEXz_na#tBGKwloKHVLr%*3dI*y^3P2LRB@YN0NokOh zI5UJCw&h$g%lLr?9=7GLBBpsngKi_(mITGkVHXK00tee_s92k7%NYspDKqSL{g6?@ zX%rv_xf92mAkT2!YuC9(Gs{IjTB5HV=h^{tN>Z7tis-VYH?wArvv8M6Q%Ne#k`u<) zcT5}|4C~WQBrh5XBqZ9I5|G;KyEx&!<0NE5lTw`y{3{9FTzNbstnX_XsxVJ-7JP-A zg%gSs%W1Qs6d;_lcvEqzEzxJ_OG%ClXh{=01u0kx$x%ukA~Iq$6Bgid3lpcO zwp)MnkBuLpEAKNB#rey6Lz;YsGY*i3gM4vtM+Y=IKo-8J3&I@@?}xbHM^+8H57Oc$ zKRm+;clBi(+om>&b`0xE2tor5NBusU>R@EMNPgSOM`uH7##={BVq zZwUZo4M_*Sv+6D(Tb8%B&h_L)T??A})?-vG33i+p*R~C{hL@BD^pa6wZJ5oz z6>N8%5{|00xYU(+bIYACmh-9VEgC`CITX#N>B4bJw$#|sc)Q~((|1e*JZHj>IQ7bu z?6qV4Tx?BaA4hz*GF`_p>(gMsP-DyTs#psx*EHl+U764`m_{CkNfpuBT$xua1cNEb zDw3GSVZ%USY0aiE<_Roq`7k_6GW3W`7z?szi9J26a~4t1P%Fb3+QQjvRcjo~pe@F& zl=AHMvLcWpuqC!g*5~;gUR_`u?+!fLQ~|) zahqq4LWaxCP$b)h%)#}J|g1mHA$A1olyOg!xu zJs?f-eOl?CN8nNb8nh z?PbM(ISA)_!?p;5aC;Mlu-fEtq{ZNQK$WdLX=sieLfJ@-O6Qw6~cW9OP7V5ikO%GK zndiV+!XeN^i(WzwFLxD?8G2XYKGs##FxU$~ua{6TIYrjeAA68<&@G&VsB0O9LZf`< zKRMim5dUw0Q9P-f97iCdDEh;~1(iw<7rGd(HtMig_XaSyy?OP?o7a!OEtIbj;p_Kb Y#Yoc>?+$NoKKopdU%_Vuzhi0VZx5LOWdHyG diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1.zip deleted file mode 100644 index be24acd0d8c2492f8afde0430f368a9acc4ecc4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5301 zcmdT|J9FbU5YFY26l&7k58yCmEIvR{l6?@}rE%lA$<-Q=gk{Ej1q9EuyL9;>`DH2c zJ8l6IB&bJBdpzUB8dKOO!TlDyD_&o{|L(&#;_vUz_n-b*{Q21jQvCl2Jd)=HCp;;w0Z~%$ncK*XCs~!Dd)Imn$m-W+*`>s%~W7mjDG&^dCJKReEa1D=(p zvaHMagr#q-&JkMs%2H`6%Zd}mw>L~g0UYb(pi-2b1`--Qr4*#~_9jWWe6kU#bW#%1 zv{F%rxJ$-BD@Dp;@P9z>*lAUX*KsaYfSaYh~Vl2>aB_$H*il#K; zTd_X8tyIfuPQsK1zmT*79Ytz4mug8~)_lt!N*c62A;|{TzIIG+NS*TS7n0UA2(x=^ zk6HT$Qn3=6vy42(WX5PNJV4S57yD0b_wg7%Ha@{u(Pt!1ir0;Xboq>6G;lm8#iDU% z4VpD@I$t#e(JhVcri9>ER!_?Z=`k#tX9VGC3 z#7t1iuNs29&O*wjB*OH{(E5Bv80L$KA($^_i z7ERpM>d0BbXL_xkw4H8u{eE#pcNxuj&wxVKvGl@s(Dh}>mc6cTdLw<&W4TCbO`gVfN`DZ*}{ zfp&u#PBOBi21L$;Sx-Fm#+0nBWBpd{OyfR@`7Mls4v24Qvb*IQ(|64FnK0B-LuTs6 zgpt8CiYQ9!n6}=kqGl2J%Sc|6)HE8Ng01B*OyfZ;JqsKeO~}CgxwRB*xrQn7+%z7y z1&b-jKxfB_y4;FQy4{`O8TuyLZCe{6%%E?~y_Q1Zz;5WaW+2+$(-uQ>GJ~$}KW)?( zb2Ctt@@XTj{F%WVj>4V^46sGhVNn+8!>-6r;NhCaJ|1O}z?t2c$hVxunG4gc^U;H( z@z0QBA?KsJw3hxEK(hu2G&oL1a)f{!r}nmc1hrB0VTyR#;*Fwzm>JmaLaqUjCOJKU z00i+Q0xQdfs4oQqzGop=FUC;^_=ZD(CLV&9Kya92M?iZc2%wMcrAG^a2zrM>REI?p zPe%Z1k_$!2g-n-K2?%dxd9p6)l28zfr39tn42Tt+5osd`utCyBmxO}oZBhg_$Z`Qm zsD40rOUr|r*Mz!65)1gbC?uSL8svj7Z3NNV=#o$nolSpCk)AM9tET)>a}eYs3Glx; zwPJKT$eA`tx{TpuH%gbiGdiu359s`s({11p6I)Ht-!vKVJa_;196? diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml deleted file mode 100644 index 34117858730..00000000000 --- a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml +++ /dev/null @@ -1,138 +0,0 @@ - - 1.1 - - - 1 - main task - 3 - annotation - 0 - - 2021-03-23 10:47:03.729206+00:00 - 2021-03-23 10:47:05.792285+00:00 - 0 - 2 - - - - - - - - 1 - 0 - 2 - http://testserver/?id=1 - - - - admin - - - - user - - - - 2021-03-23 10:47:05.886102+00:00 - - - - renault - x1 - wrong_checkbox_value - qwerty - -2 - - - bmw - x3 - false - qwerty - 1 - - - bmw - x2 - false - qwerty - 0 - - - mazda - x3 - false - qwerty - -4 - - - renault - x2 - false - qwerty - -2 - - - - - bmw - x1 - false - qwerty - 3 - - - - - \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-jr3wulvw/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip deleted file mode 100644 index 295706cf93576a58e001f55bac92ce26c866090f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5241 zcmdT|yK>_;6!m746lzjrKY+u`q*wWc=CY+{W?0QUjlp8FDSZ(e@>>P-Co`P1fyKYn}n`(Iz5or(Xi zV2xy1&Iyn6thBaig0*=tF%0~cvJ!}aYq{7~6G2ERCxQcpoRkms5GHXH04ID)8Z2Za zr9n#K%n*FomUBfc<3}2J*p^SVnC1};x`SX_E+}dar$|TPq>=+ak`ic?9J zoG`w;W8&(dSf6$*dC_nn!O_kXgOpz0#R>0SCm}1El1S)Y+8&Y#yBQsoK8*g_bNvc=Y&Y|&&3QTVJT2=8h5FvbKwvTB?^ zNR6v}dx8<}YG)f|hlclAjlk*lnS(-TJi!3JY$)Tqk)EKKpVb6em98io;|Sw3L#^`! zGh9qZn&4tOnNCEh8=nnumn5|Gf$hD-d@NBHP+{}zFlpi@SBK6FKI3!ssN*!JYtM^I zx=v}v+XYBu&61w@4ywCM*|NN~b*{%R>RQm$w;rKlNpR13ac$dBYj{Z+ly&>NI9h=5 z1+h)sP#o*Csik(IJuJ>Q8D)wNN3TGiEK4LxW3X*I@3c~ANfND1uzNZ%Da&}BQ97hl zXd9=quLav(r-Y*_Ee5+1-@3e5;*uFNYI zg2I$!6-i8EyJ8@4WzD8A<_Twn)&Ad(Io(|58ugv z$c}37xC0>ez<@^LX$c*Srtm&3^v|t-=qT83Os)Zt#2M8B1brYtS~%vG3lPi%9KL5E z7*9V8f!jpmfH`|H@i7n_`q;oOp9lgdWqU~15D23;7=+a-k0T9%(^6F8LSAwq3`D+4 z(88P}%LNsXynr%?Fp(4n6oASX6t2r~U54v2T$9u9g>%|vOCU*@;!ZK_A6$E42x4ui;m+4D& z0TCofSvB2pCYf4e3HwXn+r{n4K zCQHdBd|96uuYj|)J>=RJ%cCMr^8MDX#m)TOz6@r>FbiguMOur%LmqK7Aq5!|RBFId z(CY561R{w8(1dR#14d3W7GyNZEvZKwMQdS|JhH$ij{4QitcY3AZ-h9Cp```vBBf>E z5=Sq!D6IE_)98-zfH(%BC8usFaj_U5iX$G+vc7udV-FgoAhjl25UbuV1-tTnY| zUB)LYedPM<^%`qSt*I?5LAlu7aESsqHpyP4C|eCIH9ATwDC^x#k_vUQ0jYIT8nU#~ zr~~eb(bGB-5#_@es1Qa)TJYc}?4G-kJia1Z*Ghp3!IQ8S%y`65U_MGoRG=%CvPkUY z`uMR*Evp3$Qx^O}(+YGnX*^u1C3#tkop>l&aPSF9*0aXiF}tC4Dt4b}TC*U`?uj#G zjSZAyB{gRmeT?ahvs`+Bq?aznr*=9#hQ}r+_!@mq|<^>?!9FlDk4z2F1f*@G)%9lcVd;tKz-7_v8CT47fsUE z>d0NeXL_xkw4HW$-F`{M_8H4X$ACiCvdqGF)b&-#R=uukdINpgp_@ zj1Pz3mJg$b>50&)O7=NpPq~&pU*dV_i#Yu>MdCUupBz_w9sZQUoaxP?*B1@SFQ_P1hdFJ1d^CIa=;QklB7VPvqa zB8t*FW(RLoQS%7=Wi+p8YFmv+!4@qSw)G&FJ_1Kp6LN6BK`Y5tYnUQ8w)MCxc+5Zs zI(uH!|6j&IBHsogs>33Qr-uQ`k_UCk zgM3$o2?&3Ud{vrENhpcMN=2p-9EdgC6lEg`u))g4l!TJ#Y*Gw17?9dIrb6^7@XzIpqBmg0QqT758jmN;n0Hy;Q#9Y zp?lT>qs{Wnhg)IJ37<2=zv|v}oJX=Z$@YFaTu>X#aN%de)kPf=qkm}_TwlHU_TAgl hFBsLENBH{Vceyew^Jb)!tYM``3Giv4e0;? diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml deleted file mode 100644 index 39e1cb6d263..00000000000 --- a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1/annotations.xml +++ /dev/null @@ -1,138 +0,0 @@ - - 1.1 - - - 1 - main task - 3 - annotation - 0 - - 2021-03-23 10:21:12.892906+00:00 - 2021-03-23 10:21:13.037772+00:00 - 0 - 2 - - - - - - - - 1 - 0 - 2 - http://testserver/?id=1 - - - - admin - - - - user - - - - 2021-03-23 10:21:13.132793+00:00 - - - - mazda - x2 - wrong_checkbox_value - qwerty - 3 - - - bmw - x1 - false - qwerty - -4 - - - renault - x1 - false - qwerty - -4 - - - bmw - x3 - false - qwerty - -3 - - - bmw - x3 - false - qwerty - 0 - - - - - bmw - x1 - false - qwerty - -3 - - - - - \ No newline at end of file diff --git a/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip b/temp_test_api_v1_tasks_annotations_update_wrong_value_in_checkbox-nmf5ig2l/test_api_v1_tasks_annotations_update_wrong_value_in_checkbox_CVAT for images 1.1_wrong_checkbox_value.zip deleted file mode 100644 index 88606cbf2450070ef93914c729d83a0d9d13b862..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5238 zcmds5$!_B|7|wLs9(?Jc^8kY8*o2ZOFL6dzZ@mNsf`Ebm!gl@ zQxE+~i4rB-6L}h-OM=AYzmfd@6~4QD{pFhr@$>up?fXBgAAkPi+lveF_YKfUmgSuA zIL}J7OA}Aq`xC?PK2TNy(|3^LS!yE~Ddj{+z><^lv0lO^4t|B?rUjHJ|0Nt_u% z&a>oRG0XUg`mSfmPen}gkow(4JWCQ3H-}p!r0{LeQcK0!R1s$+c%;m*+VcZO38$ft zZR}jx?iF?o$G*YNjf2tk5-;ufceZ_FgE=Ls%vD8rLeoXIyI3r+(o~X4v*d*F^*s|$ z2gCZd6UmE40t<PzC(4JGyg5NukAp* zSZLra>_fUm{+@K`C9R-9}S>ipV9&H&-Q z4z^J^G_o%W0;jtdP6}c13;=%JQpWcqBS8tjCl+uj11Sn(; zNiTc{-CdS!+1}bd*OM20&2Rc!k5RG2f8e~hu`K8{yrc};y7he=t^j<&YzsFu$NFxH z)Dqgudige^O!49B71)z)iG*nk*tYx5Dut0G(Z&R;XTu|98AlnV$BYVV<81b=cvd$l zd0~|nN2d}OIWAr-T{T-Yf^c(an$6JV#VLuX@j&C~fv?P&Z5n`_2_NFsD^s%9Hu|NA zOk*2|{9$D}wr$q0@t}qp5zDJ$EwmidkfFLVVP-ImJP491q_w#+uUG&EQ<7CAF^%1Z zfx;5ar?BP;9F1nM+)Fadh)Y-tvWvu>p4K@FDQKvZ;SFu$Y_6&e4knC=(2}(PR_GsS zb^X=!cMxB#)sq@sJ2L$(%d=>$+DSb;jIq&HbJJI)^7(_c`e%w!cc9@};El#FMV{=V zJUihI@Kce;kfSRT&yYR6bX>Hs-?=k%J-fsi@G4{9HFB)@*H=8Tu4!FmO*d zDU7X)pW~{3b#FQr;Wc#Q+y!k)cNaeDuGZ@i7~L0t{@v}XFW$U9{UxFN_7ML4_ED@f WP4SiC-R)Oj3-T-YUBTyDY3DEcUi=#X From 2673d18076e38fe1f3002339c739be22edb7f888 Mon Sep 17 00:00:00 2001 From: "Zuev,MikhailX" Date: Thu, 25 Mar 2021 01:58:01 +0300 Subject: [PATCH 11/43] Disable real API tests due for precommit timeout failures --- .../tests/test_rest_api_formats.py | 249 +++++++++--------- 1 file changed, 126 insertions(+), 123 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index e873414e06c..f1f4c7e3efb 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -149,7 +149,7 @@ def _create_annotations(self, task, name_ann, key_get_values): value = str(random.randrange(start, stop, step)) else: value = random.choice(task["labels"][0]["attributes"][index_attribute]["values"]) - elif key_get_values == "dafault": + elif key_get_values == "default": value = attribute["default_value"] if item == "tracks" and attribute["mutable"]: @@ -201,6 +201,9 @@ def _remove_annotations(self, url, user): return response class TaskDumpUploadTest(_DbTestBase): + def test_check_CI(self): + pass + # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # test_name = self._testMethodName # # get formats @@ -235,7 +238,7 @@ class TaskDumpUploadTest(_DbTestBase): # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ # "WiderFace 1.0", "VGGFace2 1.0", \ # ]: - # self._create_annotations(task, dump_format_name, "dafault") + # self._create_annotations(task, dump_format_name, "default") # else: # self._create_annotations(task, dump_format_name, "random") # @@ -279,122 +282,122 @@ class TaskDumpUploadTest(_DbTestBase): # data_from_task_after_upload = Dataset.from_extractors(extractor) # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) # - def test_api_v1_tasks_annotations_update_wrong_label(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "default") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - self._remove_annotations(url, self.admin) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_label = "wrong_label" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']") - element.attrib["label"] = wrong_label - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): - response = self._upload_file(url_upload, binary_file, self.admin) - - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) - - def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["wrong_checkbox_value"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir() as test_dir: - file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - self._remove_annotations(url, self.admin) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_checkbox_value = "wrong_checkbox_value" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") - element.text = wrong_checkbox_value - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): - response = self._upload_file(url_upload, binary_file, self.admin) - - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) - + # def test_api_v1_tasks_annotations_update_wrong_label(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "default") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') + # + # # download zip file + # self._download_file(url, data, self.admin, file_zip_name_before_change) + # self._check_downloaded_file(file_zip_name_before_change) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # + # # change right label to wrong + # wrong_label = "wrong_label" + # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + # root = tree.getroot() + # element = root.find("./image[@id='0']/box[@label='car']") + # element.attrib["label"] = wrong_label + # tree.write(osp.join(folder_name, 'annotations.xml')) + # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name_after_change, 'rb') as binary_file: + # with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): + # response = self._upload_file(url_upload, binary_file, self.admin) + # + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # self.assertEqual(len(response.data["tracks"]), 0) + # + # def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["wrong_checkbox_value"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir() as test_dir: + # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') + # + # # download zip file + # self._download_file(url, data, self.admin, file_zip_name_before_change) + # self._check_downloaded_file(file_zip_name_before_change) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # + # # change right label to wrong + # wrong_checkbox_value = "wrong_checkbox_value" + # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + # root = tree.getroot() + # element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") + # element.text = wrong_checkbox_value + # tree.write(osp.join(folder_name, 'annotations.xml')) + # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name_after_change, 'rb') as binary_file: + # with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): + # response = self._upload_file(url_upload, binary_file, self.admin) + # + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # self.assertEqual(len(response.data["tracks"]), 0) + # # def test_api_v1_tasks_annotations_dump_others_user(self): # test_name = self._testMethodName # dump_format_name = "CVAT for images 1.1" @@ -563,7 +566,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ # "WiderFace 1.0", "VGGFace2 1.0", \ # ]: - # self._create_annotations(task, dump_format_name, "dafault") + # self._create_annotations(task, dump_format_name, "default") # else: # self._create_annotations(task, dump_format_name, "random") # @@ -612,7 +615,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # # create task with annotations # images = self._generate_task_images(13) # task = self._create_task(tasks["many jobs"], images) - # self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + # self._create_annotations(task, f'{dump_format_name} many jobs', "default") # # task_id = task["id"] # task_ann = TaskAnnotation(task_id) @@ -657,7 +660,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # # create task with annotations # images = self._generate_task_images(5) # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, f'{dump_format_name} slice track', "dafault") + # self._create_annotations(task, f'{dump_format_name} slice track', "default") # # task_id = task["id"] # task_ann = TaskAnnotation(task_id) @@ -702,7 +705,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # # create task with annotations # images = self._generate_task_images(10) # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "dafault") + # self._create_annotations(task, f'{dump_format_name} merge', "default") # # task_id = task["id"] # task_ann = TaskAnnotation(task_id) @@ -748,7 +751,7 @@ def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # # create task with annotations # images = self._generate_task_images(10) # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "dafault") + # self._create_annotations(task, f'{dump_format_name} merge', "default") # # task_id = task["id"] # task_ann = TaskAnnotation(task_id) From f13230b43ce1a7cc94a80181bb16b785edcc120b Mon Sep 17 00:00:00 2001 From: "Zuev,MikhailX" Date: Thu, 25 Mar 2021 02:39:34 +0300 Subject: [PATCH 12/43] Reenable 1 test to check CI completion --- .../tests/test_rest_api_formats.py | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index f1f4c7e3efb..5adf06e78e7 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -201,87 +201,87 @@ def _remove_annotations(self, url, user): return response class TaskDumpUploadTest(_DbTestBase): - def test_check_CI(self): - pass - - # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): - # test_name = self._testMethodName - # # get formats - # dump_formats = dm.views.get_export_formats() - # - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # dump_format_name = dump_format.DISPLAY_NAME - # - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", # issues #2923 and #2924 - # "MOT 1.1", # issue #2925 - # "Datumaro 1.0", # not uploaded - # "WiderFace 1.0", # issue #2944 - # "CamVid 1.0", # issue #2840 and changed points values - # "MOTS PNG 1.0", # issue #2925 and changed points values - # "Segmentation mask 1.1", # changed points values - # ]: - # self.skipTest("Format is fail") - # - # for include_images in (False, True): - # # create task - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # - # # create annotations - # if dump_format_name in [ - # "MOT 1.1", "MOTS PNG 1.0", \ - # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - # "WiderFace 1.0", "VGGFace2 1.0", \ - # ]: - # self._create_annotations(task, dump_format_name, "default") - # else: - # self._create_annotations(task, dump_format_name, "random") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_before_upload = Dataset.from_extractors(extractor) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - # upload_format_name = "CVAT 1.1" - # else: - # upload_format_name = dump_format_name - # - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_after_upload = Dataset.from_extractors(extractor) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # + # def test_check_CI(self): + # pass + + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + test_name = self._testMethodName + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", # issues #2923 and #2924 + "MOT 1.1", # issue #2925 + "Datumaro 1.0", # not uploaded + "WiderFace 1.0", # issue #2944 + "CamVid 1.0", # issue #2840 and changed points values + "MOTS PNG 1.0", # issue #2925 and changed points values + "Segmentation mask 1.1", # changed points values + ]: + self.skipTest("Format is fail") + + for include_images in (False, True): + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # def test_api_v1_tasks_annotations_update_wrong_label(self): # test_name = self._testMethodName # dump_format_name = "CVAT for images 1.1" From d5e1bb572077131c5c5dc3206d98671536103fbe Mon Sep 17 00:00:00 2001 From: yasakova-anastasia Date: Thu, 25 Mar 2021 19:35:40 +0300 Subject: [PATCH 13/43] Add Market-1501 to tests --- .../tests/assets/annotations.json | 14 + .../dataset_manager/tests/assets/tasks.json | 37 + .../tests/test_rest_api_formats.py | 788 +++++++++--------- 3 files changed, 447 insertions(+), 392 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 3f1f3dec8c7..faa31ad28be 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -334,6 +334,20 @@ ], "tracks": [] }, + "Market-1501 1.0": { + "version": 0, + "tags": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [] + }, "MOT 1.1": { "version": 0, "tags": [], diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index ab51d2a8c23..9bd94a2f160 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -54,6 +54,43 @@ } ] }, + "market1501": { + "name": "market1501 task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "market-1501", + "attributes": [ + { + "name": "query", + "mutable": false, + "input_type": "select", + "values": ["True", "False"] + }, + { + "name": "camera_id", + "mutable": false, + "input_type": "number", + "values": ["1", "2", "3", "4", "5", "6"] + }, + { + "name": "person_id", + "mutable": false, + "input_type": "number", + "values": ["1", "2", "3"] + } + ] + }, + { + "name": "person", + "color": "#c06060", + "attributes": [] + } + ] + }, "wrong_checkbox_value": { "name": "wrong checkbox value task", "overlap": 0, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 5adf06e78e7..946052dfff1 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -201,9 +201,6 @@ def _remove_annotations(self, url, user): return response class TaskDumpUploadTest(_DbTestBase): - # def test_check_CI(self): - # pass - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName # get formats @@ -229,7 +226,10 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): for include_images in (False, True): # create task images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + else: + task = self._create_task(tasks["main"], images) # create annotations if dump_format_name in [ @@ -397,391 +397,395 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # self.assertEqual(len(response.data["tags"]), 0) # self.assertEqual(len(response.data["shapes"]), 0) # self.assertEqual(len(response.data["tracks"]), 0) - # - # def test_api_v1_tasks_annotations_dump_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - # - # def test_api_v1_tasks_dataset_export_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump dataset - # url = f"/api/v1/tasks/{task_id}/dataset" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - # - # def test_api_v1_tasks_annotations_update_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # for user in [self.admin, self.user, None]: - # with open(file_zip_name, 'rb') as binary_file: - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # response = self._upload_file(url_upload, binary_file, user) - # - # if user is None: - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # else: - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # # check for presence annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertNotEqual(len(response.data["tags"]), 0) - # self.assertNotEqual(len(response.data["shapes"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - # test_name = self._testMethodName - # importer_format_name = { - # 'COCO 1.0': 'coco', - # 'CVAT for images 1.1': 'cvat', - # 'CVAT for video 1.1': 'cvat', - # 'Datumaro 1.0': 'datumaro_project', - # 'LabelMe 3.0': 'label_me', - # 'MOT 1.1': 'mot_seq', - # 'MOTS PNG 1.0': 'mots_png', - # 'PASCAL VOC 1.1': 'voc', - # 'Segmentation mask 1.1': 'voc', - # 'TFRecord 1.0': 'tf_detection_api', - # 'YOLO 1.1': 'yolo', - # 'ImageNet 1.0': 'imagenet_txt', - # 'CamVid 1.0': 'camvid', - # 'WiderFace 1.0': 'wider_face', - # 'VGGFace2 1.0': 'vgg_face2', - # } - # - # # get formats - # dump_formats = dm.views.get_export_formats() - # - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # dump_format_name = dump_format.DISPLAY_NAME - # - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", - # "YOLO 1.1", - # "ImageNet 1.0", - # "Datumaro 1.0", - # ]: - # self.skipTest("Format is fail") - # - # # create task - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # - # # create annotations - # if dump_format_name in [ - # "MOT 1.1", "MOTS PNG 1.0", \ - # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - # "WiderFace 1.0", "VGGFace2 1.0", \ - # ]: - # self._create_annotations(task, dump_format_name, "default") - # else: - # self._create_annotations(task, dump_format_name, "random") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # data_datumaro = { - # "dataset": None, - # "annotations": None, - # } - # with TestDir() as test_dir: - # for type_file in ("dataset", "annotations"): - # # dump file - # url = f"/api/v1/tasks/{task_id}/{type_file}" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - # - # # equals dataset vs annotations - # compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - # - # def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): - # test_name = self._testMethodName - # upload_format_name = "CVAT 1.1" - # - # for include_images in (False, True): - # for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", # issues #2923 and #2945 - # ]: - # self.skipTest("Format is fail") - # - # # create task with annotations - # images = self._generate_task_images(13) - # task = self._create_task(tasks["many jobs"], images) - # self._create_annotations(task, f'{dump_format_name} many jobs', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_before_upload = Dataset.from_extractors(extractor) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_after_upload = Dataset.from_extractors(extractor) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for video 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(5) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, f'{dump_format_name} slice track', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data) - # data_from_task_before_upload = Dataset.from_extractors(extractor) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data) - # data_from_task_after_upload = Dataset.from_extractors(extractor) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_merge(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_dataset_export_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump dataset + url = f"/api/v1/tasks/{task_id}/dataset" + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_annotations_update_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + for user in [self.admin, self.user, None]: + with open(file_zip_name, 'rb') as binary_file: + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + response = self._upload_file(url_upload, binary_file, user) + + if user is None: + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + else: + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # check for presence annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNotEqual(len(response.data["tags"]), 0) + self.assertNotEqual(len(response.data["shapes"]), 0) + + def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + test_name = self._testMethodName + importer_format_name = { + 'COCO 1.0': 'coco', + 'CVAT for images 1.1': 'cvat', + 'CVAT for video 1.1': 'cvat', + 'Datumaro 1.0': 'datumaro_project', + 'LabelMe 3.0': 'label_me', + 'MOT 1.1': 'mot_seq', + 'MOTS PNG 1.0': 'mots_png', + 'PASCAL VOC 1.1': 'voc', + 'Segmentation mask 1.1': 'voc', + 'TFRecord 1.0': 'tf_detection_api', + 'YOLO 1.1': 'yolo', + 'ImageNet 1.0': 'imagenet_txt', + 'CamVid 1.0': 'camvid', + 'WiderFace 1.0': 'wider_face', + 'VGGFace2 1.0': 'vgg_face2', + 'Market-1501 1.0': 'market1501', + } + + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", + "YOLO 1.1", + # "ImageNet 1.0", + "Datumaro 1.0", + ]: + self.skipTest("Format is fail") + + # create task + images = self._generate_task_images(3) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + else: + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + data_datumaro = { + "dataset": None, + "annotations": None, + } + with TestDir() as test_dir: + for type_file in ("dataset", "annotations"): + # dump file + url = f"/api/v1/tasks/{task_id}/{type_file}" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + + # equals dataset vs annotations + compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + + def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + test_name = self._testMethodName + upload_format_name = "CVAT 1.1" + + for include_images in (False, True): + for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", # issues #2923 and #2945 + ]: + self.skipTest("Format is fail") + + # create task with annotations + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(5) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, f'{dump_format_name} slice track', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_merge(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) From 2fcbb8fdb1206847654fa443e4dfe6388c1fb347 Mon Sep 17 00:00:00 2001 From: "Zuev,MikhailX" Date: Fri, 26 Mar 2021 01:51:44 +0300 Subject: [PATCH 14/43] Enable all tests without exceptions --- .../tests/test_rest_api_formats.py | 777 +++++++++--------- 1 file changed, 387 insertions(+), 390 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 5adf06e78e7..22e1ab2da1c 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -201,9 +201,6 @@ def _remove_annotations(self, url, user): return response class TaskDumpUploadTest(_DbTestBase): - # def test_check_CI(self): - # pass - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName # get formats @@ -398,390 +395,390 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # self.assertEqual(len(response.data["shapes"]), 0) # self.assertEqual(len(response.data["tracks"]), 0) # - # def test_api_v1_tasks_annotations_dump_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - # - # def test_api_v1_tasks_dataset_export_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump dataset - # url = f"/api/v1/tasks/{task_id}/dataset" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - # - # def test_api_v1_tasks_annotations_update_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # for user in [self.admin, self.user, None]: - # with open(file_zip_name, 'rb') as binary_file: - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # response = self._upload_file(url_upload, binary_file, user) - # - # if user is None: - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # else: - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # # check for presence annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertNotEqual(len(response.data["tags"]), 0) - # self.assertNotEqual(len(response.data["shapes"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - # test_name = self._testMethodName - # importer_format_name = { - # 'COCO 1.0': 'coco', - # 'CVAT for images 1.1': 'cvat', - # 'CVAT for video 1.1': 'cvat', - # 'Datumaro 1.0': 'datumaro_project', - # 'LabelMe 3.0': 'label_me', - # 'MOT 1.1': 'mot_seq', - # 'MOTS PNG 1.0': 'mots_png', - # 'PASCAL VOC 1.1': 'voc', - # 'Segmentation mask 1.1': 'voc', - # 'TFRecord 1.0': 'tf_detection_api', - # 'YOLO 1.1': 'yolo', - # 'ImageNet 1.0': 'imagenet_txt', - # 'CamVid 1.0': 'camvid', - # 'WiderFace 1.0': 'wider_face', - # 'VGGFace2 1.0': 'vgg_face2', - # } - # - # # get formats - # dump_formats = dm.views.get_export_formats() - # - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # dump_format_name = dump_format.DISPLAY_NAME - # - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", - # "YOLO 1.1", - # "ImageNet 1.0", - # "Datumaro 1.0", - # ]: - # self.skipTest("Format is fail") - # - # # create task - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # - # # create annotations - # if dump_format_name in [ - # "MOT 1.1", "MOTS PNG 1.0", \ - # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - # "WiderFace 1.0", "VGGFace2 1.0", \ - # ]: - # self._create_annotations(task, dump_format_name, "default") - # else: - # self._create_annotations(task, dump_format_name, "random") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # data_datumaro = { - # "dataset": None, - # "annotations": None, - # } - # with TestDir() as test_dir: - # for type_file in ("dataset", "annotations"): - # # dump file - # url = f"/api/v1/tasks/{task_id}/{type_file}" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - # - # # equals dataset vs annotations - # compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - # - # def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): - # test_name = self._testMethodName - # upload_format_name = "CVAT 1.1" - # - # for include_images in (False, True): - # for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", # issues #2923 and #2945 - # ]: - # self.skipTest("Format is fail") - # - # # create task with annotations - # images = self._generate_task_images(13) - # task = self._create_task(tasks["many jobs"], images) - # self._create_annotations(task, f'{dump_format_name} many jobs', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_before_upload = Dataset.from_extractors(extractor) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - # data_from_task_after_upload = Dataset.from_extractors(extractor) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for video 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(5) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, f'{dump_format_name} slice track', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data) - # data_from_task_before_upload = Dataset.from_extractors(extractor) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # extractor = CvatTaskDataExtractor(task_data) - # data_from_task_after_upload = Dataset.from_extractors(extractor) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_merge(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change ovelap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir() as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) + def test_api_v1_tasks_annotations_dump_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_dataset_export_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump dataset + url = f"/api/v1/tasks/{task_id}/dataset" + data = { + "format": dump_format_name, + "action": "download", + } + + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + response = self._download_file(url, data, self.user, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self._check_downloaded_file(file_zip_name) + + file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + response = self._download_file(url, data, None, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + with self.assertRaises(FileNotFoundError): + self._check_downloaded_file(file_zip_name) + + def test_api_v1_tasks_annotations_update_others_user(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + for user in [self.admin, self.user, None]: + with open(file_zip_name, 'rb') as binary_file: + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + response = self._upload_file(url_upload, binary_file, user) + + if user is None: + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + else: + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # check for presence annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertNotEqual(len(response.data["tags"]), 0) + self.assertNotEqual(len(response.data["shapes"]), 0) + + def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + test_name = self._testMethodName + importer_format_name = { + 'COCO 1.0': 'coco', + 'CVAT for images 1.1': 'cvat', + 'CVAT for video 1.1': 'cvat', + 'Datumaro 1.0': 'datumaro_project', + 'LabelMe 3.0': 'label_me', + 'MOT 1.1': 'mot_seq', + 'MOTS PNG 1.0': 'mots_png', + 'PASCAL VOC 1.1': 'voc', + 'Segmentation mask 1.1': 'voc', + 'TFRecord 1.0': 'tf_detection_api', + 'YOLO 1.1': 'yolo', + 'ImageNet 1.0': 'imagenet_txt', + 'CamVid 1.0': 'camvid', + 'WiderFace 1.0': 'wider_face', + 'VGGFace2 1.0': 'vgg_face2', + } + + # get formats + dump_formats = dm.views.get_export_formats() + + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", + "YOLO 1.1", + "ImageNet 1.0", + "Datumaro 1.0", + ]: + self.skipTest("Format is fail") + + # create task + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + data_datumaro = { + "dataset": None, + "annotations": None, + } + with TestDir() as test_dir: + for type_file in ("dataset", "annotations"): + # dump file + url = f"/api/v1/tasks/{task_id}/{type_file}" + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + + # equals dataset vs annotations + compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + + def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + test_name = self._testMethodName + upload_format_name = "CVAT 1.1" + + for include_images in (False, True): + for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + with self.subTest(): + # TODO skip failed formats + if dump_format_name in [ + "CVAT for video 1.1", # issues #2923 and #2945 + ]: + self.skipTest("Format is fail") + + # create task with annotations + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(5) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, f'{dump_format_name} slice track', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_merge(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(10) + task = self._create_task(tasks["change ovelap and segment size"], images) + self._create_annotations(task, f'{dump_format_name} merge', "default") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 1) + self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + self.assertEqual(len(response.data["tracks"]), 0) From 908d1e1aa1269dd1dae20336d95e7eb8225bbfdf Mon Sep 17 00:00:00 2001 From: yasakova-anastasia Date: Mon, 29 Mar 2021 09:55:50 +0300 Subject: [PATCH 15/43] some fixes --- .../dataset_manager/tests/assets/tasks.json | 9 +--- .../tests/test_rest_api_formats.py | 51 +++++++------------ 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 9bd94a2f160..89d2922765b 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -83,11 +83,6 @@ "values": ["1", "2", "3"] } ] - }, - { - "name": "person", - "color": "#c06060", - "attributes": [] } ] }, @@ -172,8 +167,8 @@ } ] }, - "change ovelap and segment size": { - "name": "change ovelap and segment size", + "change overlap and segment size": { + "name": "change overlap and segment size", "overlap": 3, "segment_size": 6, "owner_id": 1, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 946052dfff1..f2f89a75f9d 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -200,6 +200,14 @@ def _remove_annotations(self, url, user): self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) return response + def _get_data_from_task(self, task_id, include_images=False): + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task = Dataset.from_extractors(extractor) + return data_from_task + class TaskDumpUploadTest(_DbTestBase): def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName @@ -211,7 +219,6 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): dump_format_name = dump_format.DISPLAY_NAME with self.subTest(): - # TODO skip failed formats if dump_format_name in [ "CVAT for video 1.1", # issues #2923 and #2924 "MOT 1.1", # issue #2925 @@ -243,11 +250,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): self._create_annotations(task, dump_format_name, "random") task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_before_upload = Dataset.from_extractors(extractor) + data_from_task_before_upload = self._get_data_from_task(task_id, include_images) # dump annotations url = self._generate_url_dump_tasks_annotations(task_id) @@ -275,11 +278,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): self.assertEqual(response.status_code, status.HTTP_201_CREATED) # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_after_upload = Dataset.from_extractors(extractor) + data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) # def test_api_v1_tasks_annotations_update_wrong_label(self): @@ -551,7 +550,7 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): if dump_format_name in [ "CVAT for video 1.1", "YOLO 1.1", - # "ImageNet 1.0", + "ImageNet 1.0", "Datumaro 1.0", ]: self.skipTest("Format is fail") @@ -622,11 +621,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): self._create_annotations(task, f'{dump_format_name} many jobs', "default") task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_before_upload = Dataset.from_extractors(extractor) + data_from_task_before_upload = self._get_data_from_task(task_id, include_images) # dump annotations url = self._generate_url_dump_tasks_annotations(task_id) @@ -649,11 +644,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): self.assertEqual(response.status_code, status.HTTP_201_CREATED) # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_after_upload = Dataset.from_extractors(extractor) + data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): @@ -667,11 +658,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self self._create_annotations(task, f'{dump_format_name} slice track', "default") task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_before_upload = Dataset.from_extractors(extractor) + data_from_task_before_upload = self._get_data_from_task(task_id) # dump annotations url = self._generate_url_dump_tasks_annotations(task_id) @@ -694,11 +681,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self self.assertEqual(response.status_code, status.HTTP_201_CREATED) # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data) - data_from_task_after_upload = Dataset.from_extractors(extractor) + data_from_task_after_upload = self._get_data_from_task(task_id) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) def test_api_v1_tasks_annotations_dump_and_upload_merge(self): @@ -708,7 +691,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_merge(self): # create task with annotations images = self._generate_task_images(10) - task = self._create_task(tasks["change ovelap and segment size"], images) + task = self._create_task(tasks["change overlap and segment size"], images) self._create_annotations(task, f'{dump_format_name} merge', "default") task_id = task["id"] @@ -754,7 +737,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): # create task with annotations images = self._generate_task_images(10) - task = self._create_task(tasks["change ovelap and segment size"], images) + task = self._create_task(tasks["change overlap and segment size"], images) self._create_annotations(task, f'{dump_format_name} merge', "default") task_id = task["id"] From cfe22a414232646be425cdbeeb483efd5132b31d Mon Sep 17 00:00:00 2001 From: yasakova-anastasia Date: Mon, 29 Mar 2021 13:39:10 +0300 Subject: [PATCH 16/43] Add ICDAR to tests --- .../tests/assets/annotations.json | 72 +++++++++++++++++++ .../dataset_manager/tests/assets/tasks.json | 58 +++++++++++++++ .../tests/test_rest_api_formats.py | 14 ++++ 3 files changed, 144 insertions(+) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index faa31ad28be..12a6eba6ba9 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -291,6 +291,78 @@ ], "tracks": [] }, + "ICDAR Localization 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [10.0, 8.79, 20.5, 15.69], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [35.0, 22.5, 53.32, 30.63, 22.34, 29.45, 47.43, 38.21], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, + "ICDAR Recognition 1.0": { + "version": 0, + "tags": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [] + }, + "ICDAR Segmentation 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [10.0, 12.1, 25.6, 21.9], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [35.0, 22.5, 53.32, 30.63, 22.34, 29.45], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] + }, "ImageNet 1.0": { "version": 0, "tags": [ diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 89d2922765b..6b2ea747bfd 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -54,6 +54,64 @@ } ] }, + "icdar_localization_and_recognition": { + "name": "icdar localization/recogntion task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "icdar", + "attributes": [ + { + "name": "text", + "mutable": false, + "input_type": "text", + "values": ["word_1", "word_2", "word_3"] + } + ] + } + ] + }, + "icdar_segmentation": { + "name": "icdar segmentation task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "icdar", + "attributes": [ + { + "name": "text", + "mutable": false, + "input_type": "text", + "values": ["word_1", "word_2", "word_3"] + }, + { + "name": "index", + "mutable": false, + "input_type": "number", + "values": ["0", "1", "2"] + }, + { + "name": "color", + "mutable": false, + "input_type": "text", + "values": ["100 110 240", "10 15 20", "120 128 64"] + }, + { + "name": "center", + "mutable": false, + "input_type": "text", + "values": ["1 2", "2 4", "10 45"] + } + ] + } + ] + }, "market1501": { "name": "market1501 task", "overlap": 0, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index f2f89a75f9d..7851ee5bf81 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -227,6 +227,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): "CamVid 1.0", # issue #2840 and changed points values "MOTS PNG 1.0", # issue #2925 and changed points values "Segmentation mask 1.1", # changed points values + "ICDAR Segmentation 1.0", # changed points values ]: self.skipTest("Format is fail") @@ -235,6 +236,11 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): images = self._generate_task_images(3) if dump_format_name == "Market-1501 1.0": task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) else: task = self._create_task(tasks["main"], images) @@ -536,6 +542,9 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): 'WiderFace 1.0': 'wider_face', 'VGGFace2 1.0': 'vgg_face2', 'Market-1501 1.0': 'market1501', + 'ICDAR Localization 1.0': 'icdar_text_localization', + 'ICDAR Recognition 1.0': 'icdar_word_recognition', + 'ICDAR Segmentation 1.0': 'icdar_text_segmentation', } # get formats @@ -559,6 +568,11 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): images = self._generate_task_images(3) if dump_format_name == "Market-1501 1.0": task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) else: task = self._create_task(tasks["main"], images) From 07b7c4da8ffeef854eaff8e2c90580cfe8ac9bae Mon Sep 17 00:00:00 2001 From: "Zuev,MikhailX" Date: Tue, 30 Mar 2021 12:48:30 +0300 Subject: [PATCH 17/43] Move test data to /tmp/cvat --- .../tests/test_rest_api_formats.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 946052dfff1..c08c768449c 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -32,6 +32,8 @@ with open(path) as f: annotations = json.load(f) +TEST_DATA_ROOT = "/tmp/cvat" + def generate_image_file(filename, size=(100, 50)): f = BytesIO() image = Image.new('RGB', size=size) @@ -255,7 +257,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) @@ -417,7 +419,7 @@ def test_api_v1_tasks_annotations_dump_others_user(self): "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -453,7 +455,7 @@ def test_api_v1_tasks_dataset_export_others_user(self): "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -489,7 +491,7 @@ def test_api_v1_tasks_annotations_update_others_user(self): "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) @@ -582,7 +584,7 @@ def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): "dataset": None, "annotations": None, } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: for type_file in ("dataset", "annotations"): # dump file url = f"/api/v1/tasks/{task_id}/{type_file}" @@ -634,7 +636,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) @@ -679,7 +681,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) @@ -722,7 +724,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_merge(self): "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) @@ -768,7 +770,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): "format": dump_format_name, "action": "download", } - with TestDir() as test_dir: + with TestDir(path = TEST_DATA_ROOT) as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) From 8202829816fcb5b30c1bb7ec24f346fa806f305f Mon Sep 17 00:00:00 2001 From: "Zuev,MikhailX" Date: Thu, 22 Apr 2021 17:04:14 +0300 Subject: [PATCH 18/43] Extra changes --- .../tests/test_rest_api_formats.py | 1030 +++++++++-------- 1 file changed, 554 insertions(+), 476 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 0686caaaf65..66e0b280f1d 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -87,16 +87,35 @@ def _put_api_v1_task_id_annotations(self, tid, data): return response - def _generate_task_images(self, count): # pylint: disable=no-self-use - images = { - "client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) - for i in range(count) - } + @staticmethod + def _generate_task_images(count): # pylint: disable=no-self-use + images = {"client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) for i in range(count)} images["image_quality"] = 75 return images + # def _create_task(self, data, image_data): + # with ForceLogin(self.admin, self.client): + # response = self.client.post('/api/v1/tasks', data=data, format="json") + # assert response.status_code == status.HTTP_201_CREATED, response.status_code + # tid = response.data["id"] + # + # response = self.client.post("/api/v1/tasks/%s/data" % tid, + # data=image_data) + # assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code + # + # for _ in range(5): + # response = self.client.get("/api/v1/tasks/%s/status" % tid) + # if response.status_code == status.HTTP_200_OK: + # break + # assert response.status_code == status.HTTP_200_OK, response.status_code + # + # response = self.client.get("/api/v1/tasks/%s" % tid) + # task = response.data + # + # return task + def _create_task(self, data, image_data): - with ForceLogin(self.admin, self.client): + with ForceLogin(self.user, self.client): response = self.client.post('/api/v1/tasks', data=data, format="json") assert response.status_code == status.HTTP_201_CREATED, response.status_code tid = response.data["id"] @@ -105,17 +124,12 @@ def _create_task(self, data, image_data): data=image_data) assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - for _ in range(5): - response = self.client.get("/api/v1/tasks/%s/status" % tid) - if response.status_code == status.HTTP_200_OK: - break - assert response.status_code == status.HTTP_200_OK, response.status_code - response = self.client.get("/api/v1/tasks/%s" % tid) task = response.data return task + def _get_request(self, path, user): with ForceLogin(user, self.client): response = self.client.get(path) @@ -172,7 +186,7 @@ def _create_annotations(self, task, name_ann, key_get_values): def _download_file(self, url, data, user, file_name): for _ in range(5): response = self._get_request_with_data(url, data, user) - if response.status_code == 200: + if response.status_code == status.HTTP_200_OK: content = BytesIO(b"".join(response.streaming_content)) with open(file_name, "wb") as f: f.write(content.getvalue()) @@ -183,7 +197,7 @@ def _upload_file(self, url, binary_file, user): with ForceLogin(user, self.client): for _ in range(5): response = self.client.put(url, {"annotation_file": binary_file}) - if response.status_code == 201: + if response.status_code == status.HTTP_201_CREATED: break return response @@ -209,86 +223,148 @@ def _get_data_from_task(self, task_id, include_images=False): extractor = CvatTaskDataExtractor(task_data, include_images=include_images) data_from_task = Dataset.from_extractors(extractor) return data_from_task +""" +Need to write REST API tests for server (dataset manager): + # Dump annotations with objects type is shape + # Upload annotations with objects type is shape + # Dump annotations with objects type is track + # Upload annotations with objects type is track + # Dump tag annotations + # Dump/upload annotations with objects are different types (images) + # Dump/upload annotations with objects are different types (video) + # Dump/upload with objects type is track and outside property + # Dump/upload with objects type is track and keyframe property + # Dump/upload annotations from several jobs + # Dump annotations with objects type is shape from several jobs + # Dump annotations with objects type is track from several jobs + # Export dataset + # Wrong label in input file + # Wrong value checkbox in input file + # Dump annotations with attributes + # Upload annotations with attributes + # Dump empty frames + # Upload empty frames + # Rewriting annotations + # Dump one type and upload another type + # Unit test on to_track function + # Unit test on normalize_shape function + # Unit test on export_job function +""" class TaskDumpUploadTest(_DbTestBase): - def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + def test_api_v1_dump_annotations_with_objects_type_is_shape(self): + # Dump annotations with objects type is shape test_name = self._testMethodName - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - with self.subTest(): - if dump_format_name in [ - "CVAT for video 1.1", # issues #2923 and #2924 - "MOT 1.1", # issue #2925 - "Datumaro 1.0", # not uploaded - "WiderFace 1.0", # issue #2944 - "CamVid 1.0", # issue #2840 and changed points values - "MOTS PNG 1.0", # issue #2925 and changed points values - "Segmentation mask 1.1", # changed points values - "ICDAR Segmentation 1.0", # changed points values - ]: - self.skipTest("Format is fail") - - for include_images in (False, True): - # create task - images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - upload_format_name = "CVAT 1.1" - else: - upload_format_name = dump_format_name + dump_format_name = "CVAT for images 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + } - # equals annotations - data_from_task_after_upload = self._get_data_from_task(task_id, include_images) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + with TestDir(path=TEST_DATA_ROOT, ignore_errors=True) as test_dir: + for user, edata in list(expected.items()): + user_name = edata['name'] + # for shape in ['rectangle','polygon','polyline','points','cuboid','tag']: + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + # test_name = self._testMethodName + # # get formats + # dump_formats = dm.views.get_export_formats() + # + # for dump_format in dump_formats: + # if dump_format.ENABLED: + # dump_format_name = dump_format.DISPLAY_NAME + # + # with self.subTest(): + # if dump_format_name in [ + # "CVAT for video 1.1", # issues #2923 and #2924 + # "MOT 1.1", # issue #2925 + # "Datumaro 1.0", # not uploaded + # "WiderFace 1.0", # issue #2944 + # "CamVid 1.0", # issue #2840 and changed points values + # "MOTS PNG 1.0", # issue #2925 and changed points values + # "Segmentation mask 1.1", # changed points values + # "ICDAR Segmentation 1.0", # changed points values + # ]: + # self.skipTest("Format is fail") + # + # for include_images in (False, True): + # # create task + # images = self._generate_task_images(3) + # if dump_format_name == "Market-1501 1.0": + # task = self._create_task(tasks["market1501"], images) + # elif dump_format_name in ["ICDAR Localization 1.0", + # "ICDAR Recognition 1.0"]: + # task = self._create_task(tasks["icdar_localization_and_recognition"], images) + # elif dump_format_name == "ICDAR Segmentation 1.0": + # task = self._create_task(tasks["icdar_segmentation"], images) + # else: + # task = self._create_task(tasks["main"], images) + # + # # create annotations + # if dump_format_name in [ + # "MOT 1.1", "MOTS PNG 1.0", \ + # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + # "WiderFace 1.0", "VGGFace2 1.0", \ + # ]: + # self._create_annotations(task, dump_format_name, "default") + # else: + # self._create_annotations(task, dump_format_name, "random") + # + # task_id = task["id"] + # data_from_task_before_upload = self._get_data_from_task(task_id, include_images) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + # upload_format_name = "CVAT 1.1" + # else: + # upload_format_name = dump_format_name + # + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # # def test_api_v1_tasks_annotations_update_wrong_label(self): # test_name = self._testMethodName # dump_format_name = "CVAT for images 1.1" @@ -308,7 +384,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # "format": dump_format_name, # "action": "download", # } - # with TestDir() as test_dir: + # with TestDir(path = TEST_DATA_ROOT) as test_dir: # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') # @@ -337,8 +413,10 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # # upload annotations # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) # with open(file_zip_name_after_change, 'rb') as binary_file: - # with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): - # response = self._upload_file(url_upload, binary_file, self.admin) + # # with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): + # # response = self._upload_file(url_upload, binary_file, self.admin) + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) # # # check for missing annotations # response = self._get_request(url, self.admin) @@ -346,7 +424,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # self.assertEqual(len(response.data["tags"]), 0) # self.assertEqual(len(response.data["shapes"]), 0) # self.assertEqual(len(response.data["tracks"]), 0) - # + # def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): # test_name = self._testMethodName # dump_format_name = "CVAT for images 1.1" @@ -366,7 +444,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # "format": dump_format_name, # "action": "download", # } - # with TestDir() as test_dir: + # with TestDir(path = TEST_DATA_ROOT) as test_dir: # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') # @@ -405,386 +483,386 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # self.assertEqual(len(response.data["shapes"]), 0) # self.assertEqual(len(response.data["tracks"]), 0) - def test_api_v1_tasks_annotations_dump_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_dataset_export_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump dataset - url = f"/api/v1/tasks/{task_id}/dataset" - data = { - "format": dump_format_name, - "action": "download", - } - - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - response = self._download_file(url, data, self.user, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self._check_downloaded_file(file_zip_name) - - file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - response = self._download_file(url, data, None, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - with self.assertRaises(FileNotFoundError): - self._check_downloaded_file(file_zip_name) - - def test_api_v1_tasks_annotations_update_others_user(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - for user in [self.admin, self.user, None]: - with open(file_zip_name, 'rb') as binary_file: - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - response = self._upload_file(url_upload, binary_file, user) - - if user is None: - self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - else: - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # check for presence annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertNotEqual(len(response.data["tags"]), 0) - self.assertNotEqual(len(response.data["shapes"]), 0) - - def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - test_name = self._testMethodName - importer_format_name = { - 'COCO 1.0': 'coco', - 'CVAT for images 1.1': 'cvat', - 'CVAT for video 1.1': 'cvat', - 'Datumaro 1.0': 'datumaro_project', - 'LabelMe 3.0': 'label_me', - 'MOT 1.1': 'mot_seq', - 'MOTS PNG 1.0': 'mots_png', - 'PASCAL VOC 1.1': 'voc', - 'Segmentation mask 1.1': 'voc', - 'TFRecord 1.0': 'tf_detection_api', - 'YOLO 1.1': 'yolo', - 'ImageNet 1.0': 'imagenet_txt', - 'CamVid 1.0': 'camvid', - 'WiderFace 1.0': 'wider_face', - 'VGGFace2 1.0': 'vgg_face2', - 'Market-1501 1.0': 'market1501', - 'ICDAR Localization 1.0': 'icdar_text_localization', - 'ICDAR Recognition 1.0': 'icdar_word_recognition', - 'ICDAR Segmentation 1.0': 'icdar_text_segmentation', - } - - # get formats - dump_formats = dm.views.get_export_formats() - - for dump_format in dump_formats: - if dump_format.ENABLED: - dump_format_name = dump_format.DISPLAY_NAME - - with self.subTest(): - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", - "YOLO 1.1", - "ImageNet 1.0", - "Datumaro 1.0", - ]: - self.skipTest("Format is fail") - - # create task - images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - - # create annotations - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - data_datumaro = { - "dataset": None, - "annotations": None, - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - for type_file in ("dataset", "annotations"): - # dump file - url = f"/api/v1/tasks/{task_id}/{type_file}" - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - zip_ref.extractall(folder_name) - data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - - # equals dataset vs annotations - compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - - def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): - test_name = self._testMethodName - upload_format_name = "CVAT 1.1" - - for include_images in (False, True): - for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - with self.subTest(): - # TODO skip failed formats - if dump_format_name in [ - "CVAT for video 1.1", # issues #2923 and #2945 - ]: - self.skipTest("Format is fail") - - # create task with annotations - images = self._generate_task_images(13) - task = self._create_task(tasks["many jobs"], images) - self._create_annotations(task, f'{dump_format_name} many jobs', "default") - - task_id = task["id"] - data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - # equals annotations - data_from_task_after_upload = self._get_data_from_task(task_id, include_images) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): - test_name = self._testMethodName - dump_format_name = "CVAT for video 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(5) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, f'{dump_format_name} slice track', "default") - - task_id = task["id"] - data_from_task_before_upload = self._get_data_from_task(task_id) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - # equals annotations - data_from_task_after_upload = self._get_data_from_task(task_id) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - def test_api_v1_tasks_annotations_dump_and_upload_merge(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(10) - task = self._create_task(tasks["change overlap and segment size"], images) - self._create_annotations(task, f'{dump_format_name} merge', "default") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 1) - self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - self.assertEqual(len(response.data["tracks"]), 0) - - def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(10) - task = self._create_task(tasks["change overlap and segment size"], images) - self._create_annotations(task, f'{dump_format_name} merge', "default") - - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 1) - self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - self.assertEqual(len(response.data["tracks"]), 0) + # def test_api_v1_tasks_annotations_dump_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + # response = self._download_file(url, data, self.user, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + # response = self._download_file(url, data, None, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # with self.assertRaises(FileNotFoundError): + # self._check_downloaded_file(file_zip_name) + # + # def test_api_v1_tasks_dataset_export_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump dataset + # url = f"/api/v1/tasks/{task_id}/dataset" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') + # response = self._download_file(url, data, self.user, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self._check_downloaded_file(file_zip_name) + # + # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') + # response = self._download_file(url, data, None, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # with self.assertRaises(FileNotFoundError): + # self._check_downloaded_file(file_zip_name) + # + # def test_api_v1_tasks_annotations_update_others_user(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # for user in [self.admin, self.user, None]: + # with open(file_zip_name, 'rb') as binary_file: + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # response = self._upload_file(url_upload, binary_file, user) + # + # if user is None: + # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # else: + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # # check for presence annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertNotEqual(len(response.data["tags"]), 0) + # self.assertNotEqual(len(response.data["shapes"]), 0) + # + # def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): + # test_name = self._testMethodName + # importer_format_name = { + # 'COCO 1.0': 'coco', + # 'CVAT for images 1.1': 'cvat', + # 'CVAT for video 1.1': 'cvat', + # 'Datumaro 1.0': 'datumaro_project', + # 'LabelMe 3.0': 'label_me', + # 'MOT 1.1': 'mot_seq', + # 'MOTS PNG 1.0': 'mots_png', + # 'PASCAL VOC 1.1': 'voc', + # 'Segmentation mask 1.1': 'voc', + # 'TFRecord 1.0': 'tf_detection_api', + # 'YOLO 1.1': 'yolo', + # 'ImageNet 1.0': 'imagenet_txt', + # 'CamVid 1.0': 'camvid', + # 'WiderFace 1.0': 'wider_face', + # 'VGGFace2 1.0': 'vgg_face2', + # 'Market-1501 1.0': 'market1501', + # 'ICDAR Localization 1.0': 'icdar_text_localization', + # 'ICDAR Recognition 1.0': 'icdar_word_recognition', + # 'ICDAR Segmentation 1.0': 'icdar_text_segmentation', + # } + # + # # get formats + # dump_formats = dm.views.get_export_formats() + # + # for dump_format in dump_formats: + # if dump_format.ENABLED: + # dump_format_name = dump_format.DISPLAY_NAME + # + # with self.subTest(): + # # TODO skip failed formats + # if dump_format_name in [ + # "CVAT for video 1.1", + # "YOLO 1.1", + # "ImageNet 1.0", + # "Datumaro 1.0", + # ]: + # self.skipTest("Format is fail") + # + # # create task + # images = self._generate_task_images(3) + # if dump_format_name == "Market-1501 1.0": + # task = self._create_task(tasks["market1501"], images) + # elif dump_format_name in ["ICDAR Localization 1.0", + # "ICDAR Recognition 1.0"]: + # task = self._create_task(tasks["icdar_localization_and_recognition"], images) + # elif dump_format_name == "ICDAR Segmentation 1.0": + # task = self._create_task(tasks["icdar_segmentation"], images) + # else: + # task = self._create_task(tasks["main"], images) + # + # # create annotations + # if dump_format_name in [ + # "MOT 1.1", "MOTS PNG 1.0", \ + # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + # "WiderFace 1.0", "VGGFace2 1.0", \ + # ]: + # self._create_annotations(task, dump_format_name, "default") + # else: + # self._create_annotations(task, dump_format_name, "random") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # data_datumaro = { + # "dataset": None, + # "annotations": None, + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # for type_file in ("dataset", "annotations"): + # # dump file + # url = f"/api/v1/tasks/{task_id}/{type_file}" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) + # + # # equals dataset vs annotations + # compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) + # + # def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + # test_name = self._testMethodName + # upload_format_name = "CVAT 1.1" + # + # for include_images in (False, True): + # for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + # with self.subTest(): + # # TODO skip failed formats + # if dump_format_name in [ + # "CVAT for video 1.1", # issues #2923 and #2945 + # ]: + # self.skipTest("Format is fail") + # + # # create task with annotations + # images = self._generate_task_images(13) + # task = self._create_task(tasks["many jobs"], images) + # self._create_annotations(task, f'{dump_format_name} many jobs', "default") + # + # task_id = task["id"] + # data_from_task_before_upload = self._get_data_from_task(task_id, include_images) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # + # def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for video 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(5) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, f'{dump_format_name} slice track', "default") + # + # task_id = task["id"] + # data_from_task_before_upload = self._get_data_from_task(task_id) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # data_from_task_after_upload = self._get_data_from_task(task_id) + # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # + # def test_api_v1_tasks_annotations_dump_and_upload_merge(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(10) + # task = self._create_task(tasks["change overlap and segment size"], images) + # self._create_annotations(task, f'{dump_format_name} merge', "default") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 1) + # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + # self.assertEqual(len(response.data["tracks"]), 0) + # + # def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(10) + # task = self._create_task(tasks["change overlap and segment size"], images) + # self._create_annotations(task, f'{dump_format_name} merge', "default") + # + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # self._download_file(url, data, self.admin, file_zip_name) + # self._check_downloaded_file(file_zip_name) + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # + # # equals annotations + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + # + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 1) + # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes + # self.assertEqual(len(response.data["tracks"]), 0) From df20b6a16346a4081fac641edb44e6c5f321cd76 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 13 May 2021 23:48:50 +0300 Subject: [PATCH 19/43] Extend server tests for dataset manager --- .../tests/assets/annotations.json | 109 ++ .../tests/test_rest_api_formats.py | 1077 ++++++++++++++--- 2 files changed, 1047 insertions(+), 139 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 12a6eba6ba9..b4f8986c642 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -942,5 +942,114 @@ "attributes": [] } ] + }, + "CVAT for images 1.1 tag": { + "version": 0, + "tags": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "frame": 8, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [] + }, + "CVAT for video 1.1 slice track keyframe": { + "version": 0, + "tags": [], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [66.45, 147.08, 182.16, 204.56], + "frame": 0, + "outside": false, + "outside": true, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [66.45, 147.08, 182.16, 204.56], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "empty annotation": { + "version": 0, + "tags": [], + "shapes": [], + "tracks": [] + }, + "CVAT for images 1.1 different types": { + "version": 0, + "tags": [ + ], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [11.545, 11.7, 19.44, 17.4], + "frame": 3, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [4.54, 19.59, 21.34, 26.89], + "frame": 0, + "outside": false, + "attributes": [] + }, + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [4.54, 19.59, 21.34, 26.89], + "frame": 6, + "outside": true, + "attributes": [] + } + ], + "attributes": [] + } + ] } } diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 66e0b280f1d..0204630c70f 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -7,10 +7,16 @@ import copy import json import os.path as osp +import os +import shutil import random +import sys import xml.etree.ElementTree as ET import zipfile +from shutil import copyfile from io import BytesIO +import av +import numpy as np from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir @@ -22,6 +28,7 @@ import cvat.apps.dataset_manager as dm from cvat.apps.dataset_manager.bindings import CvatTaskDataExtractor, TaskData from cvat.apps.dataset_manager.task import TaskAnnotation +from cvat.apps.dataset_manager.annotation import TrackManager from cvat.apps.engine.models import Task path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') @@ -42,6 +49,43 @@ def generate_image_file(filename, size=(100, 50)): f.seek(0) return f + +def generate_video_file(filename, width=1280, height=720, duration=1, fps=25, codec_name='mpeg4'): + f = BytesIO() + total_frames = duration * fps + file_ext = os.path.splitext(filename)[1][1:] + container = av.open(f, mode='w', format=file_ext) + + stream = container.add_stream(codec_name=codec_name, rate=fps) + stream.width = width + stream.height = height + stream.pix_fmt = 'yuv420p' + + for frame_i in range(total_frames): + img = np.empty((stream.width, stream.height, 3)) + img[:, :, 0] = 0.5 + 0.5 * np.sin(2 * np.pi * (0 / 3 + frame_i / total_frames)) + img[:, :, 1] = 0.5 + 0.5 * np.sin(2 * np.pi * (1 / 3 + frame_i / total_frames)) + img[:, :, 2] = 0.5 + 0.5 * np.sin(2 * np.pi * (2 / 3 + frame_i / total_frames)) + + img = np.round(255 * img).astype(np.uint8) + img = np.clip(img, 0, 255) + + frame = av.VideoFrame.from_ndarray(img, format='rgb24') + for packet in stream.encode(frame): + container.mux(packet) + + # Flush stream + for packet in stream.encode(): + container.mux(packet) + + # Close the file + container.close() + f.name = filename + f.seek(0) + + return [(width, height)] * total_frames, f + + class ForceLogin: def __init__(self, user, client): self.user = user @@ -87,12 +131,25 @@ def _put_api_v1_task_id_annotations(self, tid, data): return response + def _put_api_v1_job_id_annotations(self, jid, data): + with ForceLogin(self.admin, self.client): + response = self.client.put("/api/v1/jobs/%s/annotations" % jid, + data=data, format="json") + + return response + @staticmethod def _generate_task_images(count): # pylint: disable=no-self-use images = {"client_files[%d]" % i: generate_image_file("image_%d.jpg" % i) for i in range(count)} images["image_quality"] = 75 return images + @staticmethod + def _generate_task_videos(count): # pylint: disable=no-self-use + videos = {"client_files[%d]" % i: generate_video_file("video_%d.mp4" % i) for i in range(count)} + videos["image_quality"] = 75 + return videos + # def _create_task(self, data, image_data): # with ForceLogin(self.admin, self.client): # response = self.client.post('/api/v1/tasks', data=data, format="json") @@ -129,6 +186,10 @@ def _create_task(self, data, image_data): return task + def _get_jobs(self, task_id): + with ForceLogin(self.admin, self.client): + response = self.client.get("/api/v1/tasks/{}/jobs".format(task_id)) + return response.data def _get_request(self, path, user): with ForceLogin(user, self.client): @@ -183,6 +244,44 @@ def _create_annotations(self, task, name_ann, key_get_values): response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) + def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): + tmp_annotations = copy.deepcopy(annotations[name_ann]) + + # change attributes in all annotations + for item in tmp_annotations: + if item in ["tags", "shapes", "tracks"]: + for index_elem, _ in enumerate(tmp_annotations[item]): + tmp_annotations[item][index_elem]["label_id"] = task["labels"][0]["id"] + + for index_attribute, attribute in enumerate(task["labels"][0]["attributes"]): + spec_id = task["labels"][0]["attributes"][index_attribute]["id"] + + if key_get_values == "random": + if attribute["input_type"] == "number": + start = int(attribute["values"][0]) + stop = int(attribute["values"][1]) + 1 + step = int(attribute["values"][2]) + value = str(random.randrange(start, stop, step)) + else: + value = random.choice(task["labels"][0]["attributes"][index_attribute]["values"]) + elif key_get_values == "default": + value = attribute["default_value"] + + if item == "tracks" and attribute["mutable"]: + for index_shape, _ in enumerate(tmp_annotations[item][index_elem]["shapes"]): + tmp_annotations[item][index_elem]["shapes"][index_shape]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + else: + tmp_annotations[item][index_elem]["attributes"].append({ + "spec_id": spec_id, + "value": value, + }) + + response = self._put_api_v1_job_id_annotations(job_id, tmp_annotations) + self.assertEqual(response.status_code, status.HTTP_200_OK) + def _download_file(self, url, data, user, file_name): for _ in range(5): response = self._get_request_with_data(url, data, user) @@ -211,6 +310,18 @@ def _generate_url_dump_tasks_annotations(self, task_id): def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" + def _generate_url_dump_job_annotations(self, job_id): + return f"/api/v1/jobs/{job_id}/annotations" + + def _generate_url_upload_job_annotations(self, job_id, upload_format_name): + return f"/api/v1/jobs/{job_id}/annotations?format={upload_format_name}" + + def _generate_url_dump_dataset(self, task_id): + return f"/api/v1/tasks/{task_id}/dataset" + + def _generate_url_dump_dataset_with_name(self, task_id, dataset_name): + return f"/api/v1/tasks/{task_id}/dataset&format={dataset_name}" + def _remove_annotations(self, url, user): response = self._delete_request(url, user) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) @@ -250,52 +361,741 @@ def _get_data_from_task(self, task_id, include_images=False): # Unit test on normalize_shape function # Unit test on export_job function """ - +# coverage run -a manage.py test --settings=cvat.settings.testing cvat.apps.dataset_manager.tests.test_rest_api_formats.TaskDumpUploadTest class TaskDumpUploadTest(_DbTestBase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.assets_path = osp.join(osp.dirname(__file__), 'assets') + cls.dumped_files_names = [] + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + for dumped_file in cls.dumped_files_names: + os.remove(osp.join(cls.assets_path, dumped_file)) + def test_api_v1_dump_annotations_with_objects_type_is_shape(self): - # Dump annotations with objects type is shape test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" + dump_formats = dm.views.get_export_formats() + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + } + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + # Dump annotations with objects type is shape + for dump_format in dump_formats: + if dump_format.ENABLED: + with self.subTest(): + dump_format_name = dump_format.DISPLAY_NAME + images = self._generate_task_images(3) + # create task with annotations + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + if osp.exists(file_zip_name) and user == self.admin: + new_name = f'shape_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) + + # 3, 4 + def test_api_v1_upload_annotations_with_objects_type_is_shape(self): + upload_formats = dm.views.get_import_formats() + + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'annotation_loaded': False}, + } + # Upload annotations with objects type is shape + for upload_format in upload_formats: + if upload_format.ENABLED: + with self.subTest(): + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') + if osp.exists(file_zip_name): + for user, edata in list(expected.items()): + # remove all annotations from task (create new task without annotation) + images = self._generate_task_images(3) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif upload_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, user) + self.assertEqual(response.status_code, edata['code']) + + # 5, 6 + def test_api_v1_dump_annotations_with_objects_type_is_track(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) + video = self._generate_task_videos(1) + + task = self._create_task(tasks["main"], video) self._create_annotations(task, dump_format_name, "random") task_id = task["id"] task_ann = TaskAnnotation(task_id) task_ann.init_from_db() - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) + dump_formats = dm.views.get_export_formats() + + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + } + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + # Dump annotations with objects type is shape + for dump_format in dump_formats: + if dump_format.ENABLED: + with self.subTest(): + dump_format_name = dump_format.DISPLAY_NAME + # create task with annotations + video = self._generate_task_videos(1) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], video) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], video) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], video) + else: + task = self._create_task(tasks["main"], video) + task_id = task["id"] + + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + if osp.exists(file_zip_name) and user == self.admin: + new_name = f'track_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) + + # 7,8 + def test_api_v1_upload_annotations_with_objects_type_is_track(self): + upload_formats = dm.views.get_import_formats() + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'annotation_loaded': False}, + } + # Upload annotations with objects type is shape + for upload_format in upload_formats: + if upload_format.ENABLED: + with self.subTest(): + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'track_CVAT for video 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'track_{upload_format_name}.zip') + if osp.exists(file_zip_name): + for user, edata in list(expected.items()): + # remove all annotations from task (create new task without annotation) + video = self._generate_task_videos(1) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], video) + elif upload_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], video) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], video) + else: + task = self._create_task(tasks["main"], video) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, user) + self.assertEqual(response.status_code, edata['code']) + + # 9, 10 + def test_api_v1_dump_tag_annotations(self): + dump_format_name = "CVAT for images 1.1" data = { "format": dump_format_name, "action": "download", } - + test_cases = ['all' 'first'] expected = { self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } + for test_case in test_cases: + images = self._generate_task_images(10) + task = self._create_task(tasks["change overlap and segment size"], images) + task_id = task["id"] + jobs = self._get_jobs(task_id) + + if test_case == "all": + for job in jobs: + self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 tag", "default") + else: + self._create_annotations_in_job(task, jobs[0]["id"], "CVAT for images 1.1 tag", "default") - with TestDir(path=TEST_DATA_ROOT, ignore_errors=True) as test_dir: for user, edata in list(expected.items()): - user_name = edata['name'] - # for shape in ['rectangle','polygon','polyline','points','cuboid','tag']: - file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) - self.assertEqual(response.status_code, edata['code']) - self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + with self.subTest(): + with TestDir(path=TEST_DATA_ROOT) as test_dir: + user_name = edata['name'] + url = self._generate_url_dump_tasks_annotations(task_id) + + file_zip_name = osp.join(test_dir, f'{user_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + + + + def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + upload_types = ["task", "job"] + + images = self._generate_task_images(1) + task = self._create_task(tasks["main"], images) + task_id = task["id"] + + for type in upload_types: + with self.subTest(): + with TestDir(path=TEST_DATA_ROOT) as test_dir: + if type == "task": + self._create_annotations(task, "CVAT for images 1.1 different types", "random") + else: + jobs = self._get_jobs(task_id) + job_id = jobs[0]["id"] + self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') + + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + self._remove_annotations(url, self.admin) + if type == "task": + url_upload = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + else: + jobs = self._get_jobs(task_id) + url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + response = self._get_request(url, self.admin) + self.assertEqual(len(response.data["shapes"]), 2) + self.assertEqual(len(response.data["tracks"]), 0) + + def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + upload_types = ["task", "job"] + + video = self._generate_task_videos(1) + task = self._create_task(tasks["main"], video) + task_id = task["id"] + + for type in upload_types: + with self.subTest(): + with TestDir(path=TEST_DATA_ROOT) as test_dir: + if type == "task": + self._create_annotations(task, "CVAT for images 1.1 different types", "random") + else: + jobs = self._get_jobs(task_id) + job_id = jobs[0]["id"] + self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') + + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + self._remove_annotations(url, self.admin) + if type == "task": + url_upload = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + else: + jobs = self._get_jobs(task_id) + url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url_upload, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(osp.exists(file_zip_name), True) + + response = self._get_request(url, self.admin) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 2) + + + def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + video = self._generate_task_videos(1) + task = self._create_task(tasks["main"], video) + self._create_annotations(task, "CVAT for video 1.1 slice track", "random") + task_id = task["id"] + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + with open(file_zip_name, 'rb') as binary_file: + url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + + def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): + test_name = self._testMethodName + dump_format_name = "CVAT for video 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + video = self._generate_task_videos(1) + task = self._create_task(tasks["main"], video) + self._create_annotations(task, "CVAT for video 1.1 slice track keyframe", "random") + task_id = task["id"] + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + with open(file_zip_name, 'rb') as binary_file: + url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + def test_api_v1_dump_upload_annotations_from_several_jobs(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + + images = self._generate_task_images(10) + task = self._create_task(tasks["change overlap and segment size"], images) + task_id = task["id"] + jobs = self._get_jobs(task_id) + for job in jobs: + self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 merge", "random") + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + # remove annotations + self._remove_annotations(url, self.admin) + url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + data = { + "format": dump_format_name, + "action": "download", + } + test_cases = ['all', 'first'] + + images = self._generate_task_images(10) + task = self._create_task(tasks["change overlap and segment size"], images) + task_id = task["id"] + + for test_case in test_cases: + with TestDir(path=TEST_DATA_ROOT) as test_dir: + jobs = self._get_jobs(task_id) + if test_case == "all": + for job in jobs: + self._create_annotations_in_job(task, job["id"], dump_format_name, "default") + else: + self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default") + + url = self._generate_url_dump_tasks_annotations(task_id) + + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + # remove annotations + self._remove_annotations(url, self.admin) + url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # # # 20, 21 TODO + # def test_api_v1_dump_annotations_with_objects_type_is_track_from_several_jobs(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for video 1.1" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # test_cases = ['all', 'first'] + # + # images = self._generate_task_images(10) + # task = self._create_task(tasks["change overlap and segment size"], images) + # task_id = task["id"] + # + # for test_case in test_cases: + # with TestDir(path=TEST_DATA_ROOT) as test_dir: + # jobs = self._get_jobs(task_id) + # if test_case == "all": + # for job in jobs: + # self._create_annotations_in_job(task, job["id"], dump_format_name, "default") + # else: + # self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default") + # + # url = self._generate_url_dump_tasks_annotations(task_id) + # + # file_zip_name = osp.join(test_dir, f'{test_name}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(osp.exists(file_zip_name), True) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # # + # #22, 23 TODO + # def test_api_v1_export_dataset(self): + # test_name = self._testMethodName + # dump_formats = dm.views.get_export_formats() + # + # expected = { + # self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, + # self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + # None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + # } + # + # with TestDir(path=TEST_DATA_ROOT) as test_dir: + # # Dump annotations with objects type is shape + # for dump_format in dump_formats: + # if dump_format.ENABLED: + # with self.subTest(): + # dump_format_name = dump_format.DISPLAY_NAME + # images = self._generate_task_images(3) + # # create task with annotations + # if dump_format_name == "Market-1501 1.0": + # task = self._create_task(tasks["market1501"], images) + # elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + # task = self._create_task(tasks["icdar_localization_and_recognition"], images) + # elif dump_format_name == "ICDAR Segmentation 1.0": + # task = self._create_task(tasks["icdar_segmentation"], images) + # else: + # task = self._create_task(tasks["main"], images) + # task_id = task["id"] + # # dump annotations + # url = self._generate_url_dump_dataset_with_name(task_id, dump_format_name) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # for user, edata in list(expected.items()): + # user_name = edata['name'] + # file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + # response = self._download_file(url, data, user, file_zip_name) + # self.assertEqual(response.status_code, edata['code']) + # self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + # if osp.exists(file_zip_name) and user == self.admin: + # new_name = f'shape_{dump_format_name}.zip' + # copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + # self.dumped_files_names.append(new_name) + + def test_api_v1_dump_empty_frames(self): + dump_formats = dm.views.get_export_formats() + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + for dump_format in dump_formats: + if dump_format.ENABLED: + with self.subTest(): + dump_format_name = dump_format.DISPLAY_NAME + images = self._generate_task_images(3) + task = self._create_task(tasks["no attributes"], images) + task_id = task["id"] + self._create_annotations(task, "empty annotation", "default") + url = self._generate_url_dump_tasks_annotations(task_id) + + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + if osp.exists(file_zip_name): + new_name = f'empty_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) + + def test_api_v1_upload_empty_frames(self): + upload_formats = dm.views.get_import_formats() + + with TestDir(path=TEST_DATA_ROOT): + for upload_format in upload_formats: + if upload_format.ENABLED: + with self.subTest(): + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + images = self._generate_task_images(3) + task = self._create_task(tasks["no attributes"], images) + task_id = task["id"] + + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'empty_CVAT for images 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'empty_{upload_format_name}.zip') + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertIsNone(response.data) + + def test_api_v1_rewriting_annotations(self): + dump_formats = dm.views.get_export_formats() + with TestDir(path=TEST_DATA_ROOT) as test_dir: + for dump_format in dump_formats: + if dump_format.ENABLED: + with self.subTest(): + dump_format_name = dump_format.DISPLAY_NAME + if dump_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + "Datumaro 1.0" # Datumaro 1.0 is not in the list of import format + ]: + self.skipTest("Format is fail") + images = self._generate_task_images(3) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_ann_prev_data = task_ann.data + url = self._generate_url_dump_tasks_annotations(task_id) + + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + + self._remove_annotations(url, self.admin) + + self._create_annotations(task, "CVAT for images 1.1 many jobs", "default") + + if dump_format_name == "CVAT for images 1.1" or dump_format_name == "CVAT for video 1.1": + dump_format_name = "CVAT 1.1" + url = self._generate_url_upload_tasks_annotations(task_id, dump_format_name) + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_ann_data = task_ann.data + self.assertEqual(len(task_ann_data["shapes"]), len(task_ann_prev_data["shapes"])) + + + # def test_api_v1_dump_one_type_and_upload_another_type(self): + # test_name = self._testMethodName + # upload_formats = dm.views.get_import_formats() + # dump_formats = dm.views.get_export_formats() + # with TestDir(path=TEST_DATA_ROOT) as test_dir: + # for dump_format in dump_formats: + # images = self._generate_task_images(3) + # # create task with annotations + # task = self._create_task(tasks["main"], images) + # task_id = task["id"] + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # dump_format_name = "CVAT for images 1.1" + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format}.zip') + # response = self._download_file(url, data, self.admin, file_zip_name) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # for upload_format in upload_formats: + # if upload_format.ENABLED: + # with self.subTest(): + # upload_format_name = upload_format.DISPLAY_NAME + # if upload_format_name == "CVAT 1.1" or upload_format_name == "COCO 1.0": + # self.skipTest("Skip upload format") + # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name, 'rb') as binary_file: + # response = self._upload_file(url, binary_file, self.admin) + + # def test_api_v1_unit_test_on_to_track_function(self): + # pass + # + + def test_api_v1_unit_test_on_normalize_shape_function(self): + # 3 points + norm_shape = TrackManager.normalize_shape({ + "points": [1.5, 2.5], + }) + + # 4 points + norm_shape = TrackManager.normalize_shape({ + "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], + }) + # 1 point + norm_shape = TrackManager.normalize_shape({ + "points": [1.5, 2.5], + }) + # empty shape + with self.assertRaises(ValueError): + norm_shape = TrackManager.normalize_shape({ + "points": [], + }) + # invalid count of points + with self.assertRaises(ValueError): + norm_shape = TrackManager.normalize_shape({ + "points": [1.5, 2.5, 7.5], + }) + # negative points + norm_shape = TrackManager.normalize_shape({ + "points": [-1.5, 2.5, -9.8, -4.6], + }) + # integer + norm_shape = TrackManager.normalize_shape({ + "points": [1, 2, 9, 4], + }) + + def test_api_v1_unit_test_on_export_job_function(self): + pass # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # test_name = self._testMethodName # # get formats # dump_formats = dm.views.get_export_formats() - # # for dump_format in dump_formats: # if dump_format.ENABLED: # dump_format_name = dump_format.DISPLAY_NAME - # # with self.subTest(): # if dump_format_name in [ # "CVAT for video 1.1", # issues #2923 and #2924 @@ -355,7 +1155,6 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): # upload_format_name = "CVAT 1.1" # else: # upload_format_name = dump_format_name - # # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) # with open(file_zip_name, 'rb') as binary_file: # response = self._upload_file(url, binary_file, self.admin) @@ -364,124 +1163,125 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): # # equals annotations # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_update_wrong_label(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "default") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') - # - # # download zip file - # self._download_file(url, data, self.admin, file_zip_name_before_change) - # self._check_downloaded_file(file_zip_name_before_change) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # - # # change right label to wrong - # wrong_label = "wrong_label" - # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - # root = tree.getroot() - # element = root.find("./image[@id='0']/box[@label='car']") - # element.attrib["label"] = wrong_label - # tree.write(osp.join(folder_name, 'annotations.xml')) - # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name_after_change, 'rb') as binary_file: - # # with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): - # # response = self._upload_file(url_upload, binary_file, self.admin) - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - # - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # self.assertEqual(len(response.data["tracks"]), 0) - # def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["wrong_checkbox_value"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') - # - # # download zip file - # self._download_file(url, data, self.admin, file_zip_name_before_change) - # self._check_downloaded_file(file_zip_name_before_change) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # - # # change right label to wrong - # wrong_checkbox_value = "wrong_checkbox_value" - # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - # root = tree.getroot() - # element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") - # element.text = wrong_checkbox_value - # tree.write(osp.join(folder_name, 'annotations.xml')) - # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name_after_change, 'rb') as binary_file: - # with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): - # response = self._upload_file(url_upload, binary_file, self.admin) - # - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # self.assertEqual(len(response.data["tracks"]), 0) + # 24 + def test_api_v1_tasks_annotations_update_wrong_label(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["main"], images) + self._create_annotations(task, dump_format_name, "default") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir(path = TEST_DATA_ROOT) as test_dir: + file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + self._remove_annotations(url, self.admin) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_label = "wrong_label" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']") + element.attrib["label"] = wrong_label + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): + self._upload_file(url_upload, binary_file, self.admin) + + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) + + # 25 + def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): + test_name = self._testMethodName + dump_format_name = "CVAT for images 1.1" + upload_format_name = "CVAT 1.1" + + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["wrong_checkbox_value"], images) + self._create_annotations(task, dump_format_name, "random") + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir(path = TEST_DATA_ROOT) as test_dir: + file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') + + # download zip file + self._download_file(url, data, self.admin, file_zip_name_before_change) + self._check_downloaded_file(file_zip_name_before_change) + + # remove annotations + self._remove_annotations(url, self.admin) + + # extract zip + folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + # change right label to wrong + wrong_checkbox_value = "wrong_checkbox_value" + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") + element.text = wrong_checkbox_value + tree.write(osp.join(folder_name, 'annotations.xml')) + with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + + # upload annotations + url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name_after_change, 'rb') as binary_file: + with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): + self._upload_file(url_upload, binary_file, self.admin) + #with self.assertRaises(ValueError):#, f"Label '{wrong_label}' is not registered for this task"): + # self._upload_file(url_upload, binary_file, self.admin) + # check for missing annotations + response = self._get_request(url, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data["tags"]), 0) + self.assertEqual(len(response.data["shapes"]), 0) + self.assertEqual(len(response.data["tracks"]), 0) # def test_api_v1_tasks_annotations_dump_others_user(self): # test_name = self._testMethodName @@ -518,11 +1318,10 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) # with self.assertRaises(FileNotFoundError): # self._check_downloaded_file(file_zip_name) - # + # def test_api_v1_tasks_dataset_export_others_user(self): # test_name = self._testMethodName # dump_format_name = "CVAT for images 1.1" - # # # create task with annotations # images = self._generate_task_images(3) # task = self._create_task(tasks["main"], images) @@ -532,7 +1331,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): # task_ann.init_from_db() # # # dump dataset - # url = f"/api/v1/tasks/{task_id}/dataset" + # url = f"/api/v1/tasks/{task_id}/dataset" # data = { # "format": dump_format_name, # "action": "download", From f840aacf01959931c7354ba0feeff0fc5c332a2a Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 18 May 2021 21:47:10 +0300 Subject: [PATCH 20/43] Add test for #2924 issue --- .../tests/assets/annotations.json | 69 +++++ .../tests/test_rest_api_formats.py | 289 ++++++++++-------- 2 files changed, 223 insertions(+), 135 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index b4f8986c642..3e828f0231c 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -1051,5 +1051,74 @@ "attributes": [] } ] + }, + "CVAT for video 1.1 polygon": { + "version": 0, + "tags": [ + { + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 1, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + }, + { + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": false, + "attributes": [] + } + ], + "attributes": [] + } + ] } } diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 0204630c70f..fe123203897 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -361,7 +361,7 @@ def _get_data_from_task(self, task_id, include_images=False): # Unit test on normalize_shape function # Unit test on export_job function """ -# coverage run -a manage.py test --settings=cvat.settings.testing cvat.apps.dataset_manager.tests.test_rest_api_formats.TaskDumpUploadTest + class TaskDumpUploadTest(_DbTestBase): @classmethod def setUpClass(cls): @@ -430,7 +430,6 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): copyfile(file_zip_name, osp.join(self.assets_path, new_name)) self.dumped_files_names.append(new_name) - # 3, 4 def test_api_v1_upload_annotations_with_objects_type_is_shape(self): upload_formats = dm.views.get_import_formats() @@ -472,7 +471,6 @@ def test_api_v1_upload_annotations_with_objects_type_is_shape(self): response = self._upload_file(url, binary_file, user) self.assertEqual(response.status_code, edata['code']) - # 5, 6 def test_api_v1_dump_annotations_with_objects_type_is_track(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" @@ -538,7 +536,6 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): copyfile(file_zip_name, osp.join(self.assets_path, new_name)) self.dumped_files_names.append(new_name) - # 7,8 def test_api_v1_upload_annotations_with_objects_type_is_track(self): upload_formats = dm.views.get_import_formats() expected = { @@ -579,7 +576,6 @@ def test_api_v1_upload_annotations_with_objects_type_is_track(self): response = self._upload_file(url, binary_file, user) self.assertEqual(response.status_code, edata['code']) - # 9, 10 def test_api_v1_dump_tag_annotations(self): dump_format_name = "CVAT for images 1.1" data = { @@ -614,8 +610,6 @@ def test_api_v1_dump_tag_annotations(self): self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - - def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" @@ -703,7 +697,6 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel self.assertEqual(len(response.data["shapes"]), 0) self.assertEqual(len(response.data["tracks"]), 2) - def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" @@ -728,7 +721,6 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( response = self._upload_file(url, binary_file, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" @@ -818,7 +810,6 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se response = self._upload_file(url, binary_file, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # # # 20, 21 TODO # def test_api_v1_dump_annotations_with_objects_type_is_track_from_several_jobs(self): # test_name = self._testMethodName # dump_format_name = "CVAT for video 1.1" @@ -957,6 +948,7 @@ def test_api_v1_upload_empty_frames(self): self.assertIsNone(response.data) def test_api_v1_rewriting_annotations(self): + test_name = self._testMethodName dump_formats = dm.views.get_export_formats() with TestDir(path=TEST_DATA_ROOT) as test_dir: for dump_format in dump_formats: @@ -997,7 +989,7 @@ def test_api_v1_rewriting_annotations(self): "format": dump_format_name, "action": "download", } - file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(osp.exists(file_zip_name), True) @@ -1049,10 +1041,6 @@ def test_api_v1_rewriting_annotations(self): # with open(file_zip_name, 'rb') as binary_file: # response = self._upload_file(url, binary_file, self.admin) - # def test_api_v1_unit_test_on_to_track_function(self): - # pass - # - def test_api_v1_unit_test_on_normalize_shape_function(self): # 3 points norm_shape = TrackManager.normalize_shape({ @@ -1086,8 +1074,37 @@ def test_api_v1_unit_test_on_normalize_shape_function(self): "points": [1, 2, 9, 4], }) - def test_api_v1_unit_test_on_export_job_function(self): - pass + def test_api_v1_check_duplicated_polygon_points(self): + # issue 2924 + test_name = self._testMethodName + images = self._generate_task_images(10) + task = self._create_task(tasks["main"], images) + task_id = task["id"] + annotation_name = "CVAT for video 1.1 polygon" + data = { + "format": "CVAT for video 1.1", + "action": "download", + } + self._create_annotations(task, annotation_name, "default") + annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] + with TestDir(path=TEST_DATA_ROOT) as test_dir: + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) + # extract zip + folder_name = osp.join(test_dir, f'{test_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + for polygon in root.findall("./track[@id='0']/polygon"): + polygon_points = polygon.attrib["points"].replace(",", ";") + polygon_points = polygon_points.split(";") + polygon_points = [float(p) for p in polygon_points] + self.assertEqual(polygon_points, annotation_points) # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): # test_name = self._testMethodName @@ -1164,124 +1181,126 @@ def test_api_v1_unit_test_on_export_job_function(self): # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # 24 - def test_api_v1_tasks_annotations_update_wrong_label(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["main"], images) - self._create_annotations(task, dump_format_name, "default") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - self._remove_annotations(url, self.admin) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_label = "wrong_label" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']") - element.attrib["label"] = wrong_label - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): - self._upload_file(url_upload, binary_file, self.admin) - - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) - - # 25 - def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): - test_name = self._testMethodName - dump_format_name = "CVAT for images 1.1" - upload_format_name = "CVAT 1.1" - - # create task with annotations - images = self._generate_task_images(3) - task = self._create_task(tasks["wrong_checkbox_value"], images) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - with TestDir(path = TEST_DATA_ROOT) as test_dir: - file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') - - # download zip file - self._download_file(url, data, self.admin, file_zip_name_before_change) - self._check_downloaded_file(file_zip_name_before_change) - - # remove annotations - self._remove_annotations(url, self.admin) - - # extract zip - folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - # change right label to wrong - wrong_checkbox_value = "wrong_checkbox_value" - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") - element.text = wrong_checkbox_value - tree.write(osp.join(folder_name, 'annotations.xml')) - with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - - # upload annotations - url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name_after_change, 'rb') as binary_file: - with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): - self._upload_file(url_upload, binary_file, self.admin) - #with self.assertRaises(ValueError):#, f"Label '{wrong_label}' is not registered for this task"): - # self._upload_file(url_upload, binary_file, self.admin) - # check for missing annotations - response = self._get_request(url, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data["tags"]), 0) - self.assertEqual(len(response.data["shapes"]), 0) - self.assertEqual(len(response.data["tracks"]), 0) + # # 24 + # def test_api_v1_tasks_annotations_update_wrong_label(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["main"], images) + # self._create_annotations(task, dump_format_name, "default") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') + # + # # download zip file + # self._download_file(url, data, self.admin, file_zip_name_before_change) + # self._check_downloaded_file(file_zip_name_before_change) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # + # # change right label to wrong + # wrong_label = "wrong_label" + # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + # root = tree.getroot() + # element = root.find("./image[@id='0']/box[@label='car']") + # element.attrib["label"] = wrong_label + # tree.write(osp.join(folder_name, 'annotations.xml')) + # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name_after_change, 'rb') as binary_file: + # #with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): + # # self._upload_file(url_upload, binary_file, self.admin) + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + # + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # self.assertEqual(len(response.data["tracks"]), 0) + # + # # 25 + # def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): + # test_name = self._testMethodName + # dump_format_name = "CVAT for images 1.1" + # upload_format_name = "CVAT 1.1" + # + # # create task with annotations + # images = self._generate_task_images(3) + # task = self._create_task(tasks["wrong_checkbox_value"], images) + # self._create_annotations(task, dump_format_name, "random") + # task_id = task["id"] + # task_ann = TaskAnnotation(task_id) + # task_ann.init_from_db() + # + # # dump annotations + # url = self._generate_url_dump_tasks_annotations(task_id) + # data = { + # "format": dump_format_name, + # "action": "download", + # } + # with TestDir(path = TEST_DATA_ROOT) as test_dir: + # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') + # + # # download zip file + # self._download_file(url, data, self.admin, file_zip_name_before_change) + # self._check_downloaded_file(file_zip_name_before_change) + # + # # remove annotations + # self._remove_annotations(url, self.admin) + # + # # extract zip + # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') + # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: + # zip_ref.extractall(folder_name) + # + # # change right label to wrong + # wrong_checkbox_value = "wrong_checkbox_value" + # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + # root = tree.getroot() + # element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") + # element.text = wrong_checkbox_value + # tree.write(osp.join(folder_name, 'annotations.xml')) + # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: + # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') + # + # # upload annotations + # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # with open(file_zip_name_after_change, 'rb') as binary_file: + # #with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): + # # self._upload_file(url_upload, binary_file, self.admin) + # response = self._upload_file(url_upload, binary_file, self.admin) + # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + # # check for missing annotations + # response = self._get_request(url, self.admin) + # self.assertEqual(response.status_code, status.HTTP_200_OK) + # self.assertEqual(len(response.data["tags"]), 0) + # self.assertEqual(len(response.data["shapes"]), 0) + # self.assertEqual(len(response.data["tracks"]), 0) # def test_api_v1_tasks_annotations_dump_others_user(self): # test_name = self._testMethodName From e5a010bfbf0e4324e3e053451dca39d01ae77585 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 18 May 2021 23:19:56 +0300 Subject: [PATCH 21/43] fix export dataset test --- .../tests/test_rest_api_formats.py | 91 +++++++++---------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index fe123203897..27aeb0c6cf0 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -319,9 +319,6 @@ def _generate_url_upload_job_annotations(self, job_id, upload_format_name): def _generate_url_dump_dataset(self, task_id): return f"/api/v1/tasks/{task_id}/dataset" - def _generate_url_dump_dataset_with_name(self, task_id, dataset_name): - return f"/api/v1/tasks/{task_id}/dataset&format={dataset_name}" - def _remove_annotations(self, url, user): response = self._delete_request(url, user) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) @@ -845,51 +842,49 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se # with open(file_zip_name, 'rb') as binary_file: # response = self._upload_file(url, binary_file, self.admin) # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # # - # #22, 23 TODO - # def test_api_v1_export_dataset(self): - # test_name = self._testMethodName - # dump_formats = dm.views.get_export_formats() - # - # expected = { - # self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, - # self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - # None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, - # } - # - # with TestDir(path=TEST_DATA_ROOT) as test_dir: - # # Dump annotations with objects type is shape - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # with self.subTest(): - # dump_format_name = dump_format.DISPLAY_NAME - # images = self._generate_task_images(3) - # # create task with annotations - # if dump_format_name == "Market-1501 1.0": - # task = self._create_task(tasks["market1501"], images) - # elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - # task = self._create_task(tasks["icdar_localization_and_recognition"], images) - # elif dump_format_name == "ICDAR Segmentation 1.0": - # task = self._create_task(tasks["icdar_segmentation"], images) - # else: - # task = self._create_task(tasks["main"], images) - # task_id = task["id"] - # # dump annotations - # url = self._generate_url_dump_dataset_with_name(task_id, dump_format_name) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # for user, edata in list(expected.items()): - # user_name = edata['name'] - # file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - # response = self._download_file(url, data, user, file_zip_name) - # self.assertEqual(response.status_code, edata['code']) - # self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - # if osp.exists(file_zip_name) and user == self.admin: - # new_name = f'shape_{dump_format_name}.zip' - # copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - # self.dumped_files_names.append(new_name) + + def test_api_v1_export_dataset(self): + test_name = self._testMethodName + dump_formats = dm.views.get_export_formats() + + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + } + + with TestDir(path=TEST_DATA_ROOT) as test_dir: + # Dump annotations with objects type is shape + for dump_format in dump_formats: + if dump_format.ENABLED: + if dump_format.DISPLAY_NAME != "CVAT for images 1.1": + continue + with self.subTest(): + dump_format_name = dump_format.DISPLAY_NAME + images = self._generate_task_images(3) + # create task with annotations + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + # dump annotations + url = self._generate_url_dump_dataset(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + # print(response.description) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) def test_api_v1_dump_empty_frames(self): dump_formats = dm.views.get_export_formats() From 205134fe74bebba3cc913ffd67ffbe694b356fc7 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 27 May 2021 10:54:48 +0300 Subject: [PATCH 22/43] fix tests --- cvat/apps/dataset_manager/tests/assets/annotations.json | 2 +- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 3e828f0231c..370d74760be 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -252,7 +252,7 @@ "type": "polygon", "occluded": false, "z_order": 0, - "points": [83.0, 228.5, 69.5, 228.0, 69.0, 183.5, 164.5, 223.0, 164.0, 224.5, 83.0, 228.5], + "points": [35.0, 22.5, 53.32, 30.63, 22.34, 29.45, 47.43, 38.21], "frame": 0, "label_id": null, "group": 0, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 27aeb0c6cf0..9686f3bed9d 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -616,7 +616,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se } upload_types = ["task", "job"] - images = self._generate_task_images(1) + images = self._generate_task_images(2) task = self._create_task(tasks["main"], images) task_id = task["id"] From 002fb2dda256c3819b8ef8678ff47c5d61e5ec05 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Fri, 28 May 2021 19:07:20 +0300 Subject: [PATCH 23/43] code review --- .../tests/assets/annotations.json | 23 +- .../tests/test_rest_api_formats.py | 1249 +++++------------ 2 files changed, 333 insertions(+), 939 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 370d74760be..1af76596b14 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -88,15 +88,7 @@ }, "CVAT for video 1.1": { "version": 0, - "tags": [ - { - "frame": 1, - "label_id": null, - "group": 0, - "source": "manual", - "attributes": [] - } - ], + "tags": [], "shapes": [], "tracks": [ { @@ -1007,8 +999,7 @@ }, "CVAT for images 1.1 different types": { "version": 0, - "tags": [ - ], + "tags": [], "shapes": [ { "type": "rectangle", @@ -1054,15 +1045,7 @@ }, "CVAT for video 1.1 polygon": { "version": 0, - "tags": [ - { - "frame": 1, - "label_id": null, - "group": 0, - "source": "manual", - "attributes": [] - } - ], + "tags": [], "shapes": [], "tracks": [ { diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 9686f3bed9d..a65cd4ec4a9 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -17,6 +17,8 @@ from io import BytesIO import av import numpy as np +import random +import string from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir @@ -39,7 +41,7 @@ with open(path) as f: annotations = json.load(f) -TEST_DATA_ROOT = "/tmp/cvat" + def generate_image_file(filename, size=(100, 50)): f = BytesIO() @@ -365,6 +367,7 @@ def setUpClass(cls): super().setUpClass() cls.assets_path = osp.join(osp.dirname(__file__), 'assets') cls.dumped_files_names = [] + cls.path = "/tmp/cvat_".join(random.choice(string.ascii_lowercase) for i in range(10)) @classmethod def tearDownClass(cls): @@ -382,50 +385,51 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: # Dump annotations with objects type is shape for dump_format in dump_formats: - if dump_format.ENABLED: - with self.subTest(): - dump_format_name = dump_format.DISPLAY_NAME - images = self._generate_task_images(3) - # create task with annotations - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - task_id = task["id"] - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) + if not dump_format.ENABLED: + continue + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(format=dump_format_name): + images = self._generate_task_images(3) + # create task with annotations + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - for user, edata in list(expected.items()): - user_name = edata['name'] - file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) - self.assertEqual(response.status_code, edata['code']) - self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - if osp.exists(file_zip_name) and user == self.admin: - new_name = f'shape_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + if osp.exists(file_zip_name) and user == self.admin: + new_name = f'shape_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) def test_api_v1_upload_annotations_with_objects_type_is_shape(self): upload_formats = dm.views.get_import_formats() @@ -437,36 +441,40 @@ def test_api_v1_upload_annotations_with_objects_type_is_shape(self): } # Upload annotations with objects type is shape for upload_format in upload_formats: - if upload_format.ENABLED: - with self.subTest(): - upload_format_name = upload_format.DISPLAY_NAME - if upload_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - ]: - self.skipTest("Format is fail") - if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') - else: - file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') - if osp.exists(file_zip_name): - for user, edata in list(expected.items()): - # remove all annotations from task (create new task without annotation) - images = self._generate_task_images(3) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif upload_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - task_id = task["id"] - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') + if not upload_format.ENABLED or not osp.exists(file_zip_name): + continue + with self.subTest(format=upload_format_name): + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') + if osp.exists(file_zip_name): + for user, edata in list(expected.items()): + # remove all annotations from task (create new task without annotation) + images = self._generate_task_images(3) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, user) - self.assertEqual(response.status_code, edata['code']) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, user) + self.assertEqual(response.status_code, edata['code']) def test_api_v1_dump_annotations_with_objects_type_is_track(self): test_name = self._testMethodName @@ -488,50 +496,51 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: # Dump annotations with objects type is shape for dump_format in dump_formats: - if dump_format.ENABLED: - with self.subTest(): - dump_format_name = dump_format.DISPLAY_NAME - # create task with annotations - video = self._generate_task_videos(1) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], video) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], video) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], video) - else: - task = self._create_task(tasks["main"], video) - task_id = task["id"] + if not dump_format.ENABLED: + continue + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(format=dump_format_name): + # create task with annotations + video = self._generate_task_videos(1) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], video) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], video) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], video) + else: + task = self._create_task(tasks["main"], video) + task_id = task["id"] - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - for user, edata in list(expected.items()): - user_name = edata['name'] - file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) - self.assertEqual(response.status_code, edata['code']) - self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - if osp.exists(file_zip_name) and user == self.admin: - new_name = f'track_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + if osp.exists(file_zip_name) and user == self.admin: + new_name = f'track_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) def test_api_v1_upload_annotations_with_objects_type_is_track(self): upload_formats = dm.views.get_import_formats() @@ -542,36 +551,36 @@ def test_api_v1_upload_annotations_with_objects_type_is_track(self): } # Upload annotations with objects type is shape for upload_format in upload_formats: - if upload_format.ENABLED: - with self.subTest(): - upload_format_name = upload_format.DISPLAY_NAME - if upload_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - ]: - self.skipTest("Format is fail") - if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'track_CVAT for video 1.1.zip') - else: - file_zip_name = osp.join(self.assets_path, f'track_{upload_format_name}.zip') - if osp.exists(file_zip_name): - for user, edata in list(expected.items()): - # remove all annotations from task (create new task without annotation) - video = self._generate_task_videos(1) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], video) - elif upload_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], video) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], video) - else: - task = self._create_task(tasks["main"], video) - task_id = task["id"] - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, user) - self.assertEqual(response.status_code, edata['code']) + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'track_CVAT for video 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'track_{upload_format_name}.zip') + if not upload_format.ENABLED or not osp.exists(file_zip_name): + continue + with self.subTest(format=upload_format_name): + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if osp.exists(file_zip_name): + for user, edata in list(expected.items()): + # remove all annotations from task (create new task without annotation) + video = self._generate_task_videos(1) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], video) + elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], video) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], video) + else: + task = self._create_task(tasks["main"], video) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, user) + self.assertEqual(response.status_code, edata['code']) def test_api_v1_dump_tag_annotations(self): dump_format_name = "CVAT for images 1.1" @@ -597,8 +606,8 @@ def test_api_v1_dump_tag_annotations(self): self._create_annotations_in_job(task, jobs[0]["id"], "CVAT for images 1.1 tag", "default") for user, edata in list(expected.items()): - with self.subTest(): - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with self.subTest(format=f"{edata['name']}"): + with TestDir(path=self.path) as test_dir: user_name = edata['name'] url = self._generate_url_dump_tasks_annotations(task_id) @@ -621,8 +630,8 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se task_id = task["id"] for type in upload_types: - with self.subTest(): - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with self.subTest(format=type): + with TestDir(path=self.path) as test_dir: if type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: @@ -664,8 +673,8 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel task_id = task["id"] for type in upload_types: - with self.subTest(): - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with self.subTest(format=type): + with TestDir(path=self.path) as test_dir: if type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: @@ -706,7 +715,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( self._create_annotations(task, "CVAT for video 1.1 slice track", "random") task_id = task["id"] - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -730,7 +739,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property self._create_annotations(task, "CVAT for video 1.1 slice track keyframe", "random") task_id = task["id"] - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -757,7 +766,7 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): for job in jobs: self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 merge", "random") - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -785,7 +794,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se task_id = task["id"] for test_case in test_cases: - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: jobs = self._get_jobs(task_id) if test_case == "all": for job in jobs: @@ -807,42 +816,6 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se response = self._upload_file(url, binary_file, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # def test_api_v1_dump_annotations_with_objects_type_is_track_from_several_jobs(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for video 1.1" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # test_cases = ['all', 'first'] - # - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change overlap and segment size"], images) - # task_id = task["id"] - # - # for test_case in test_cases: - # with TestDir(path=TEST_DATA_ROOT) as test_dir: - # jobs = self._get_jobs(task_id) - # if test_case == "all": - # for job in jobs: - # self._create_annotations_in_job(task, job["id"], dump_format_name, "default") - # else: - # self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default") - # - # url = self._generate_url_dump_tasks_annotations(task_id) - # - # file_zip_name = osp.join(test_dir, f'{test_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(osp.exists(file_zip_name), True) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - def test_api_v1_export_dataset(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() @@ -853,188 +826,158 @@ def test_api_v1_export_dataset(self): None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: # Dump annotations with objects type is shape for dump_format in dump_formats: - if dump_format.ENABLED: - if dump_format.DISPLAY_NAME != "CVAT for images 1.1": - continue - with self.subTest(): - dump_format_name = dump_format.DISPLAY_NAME - images = self._generate_task_images(3) - # create task with annotations - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - task_id = task["id"] - # dump annotations - url = self._generate_url_dump_dataset(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - for user, edata in list(expected.items()): - user_name = edata['name'] - file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) - # print(response.description) - self.assertEqual(response.status_code, edata['code']) - self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) + if not dump_format.ENABLED or dump_format.DISPLAY_NAME != "CVAT for images 1.1": + continue + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(format=dump_format_name): + images = self._generate_task_images(3) + # create task with annotations + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + # dump annotations + url = self._generate_url_dump_dataset(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + for user, edata in list(expected.items()): + user_name = edata['name'] + file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') + response = self._download_file(url, data, user, file_zip_name) + self.assertEqual(response.status_code, edata['code']) + self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) def test_api_v1_dump_empty_frames(self): dump_formats = dm.views.get_export_formats() - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: for dump_format in dump_formats: - if dump_format.ENABLED: - with self.subTest(): - dump_format_name = dump_format.DISPLAY_NAME - images = self._generate_task_images(3) - task = self._create_task(tasks["no attributes"], images) - task_id = task["id"] - self._create_annotations(task, "empty annotation", "default") - url = self._generate_url_dump_tasks_annotations(task_id) + if not dump_format.ENABLED: + continue + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(format=dump_format_name): + images = self._generate_task_images(3) + task = self._create_task(tasks["no attributes"], images) + task_id = task["id"] + self._create_annotations(task, "empty annotation", "default") + url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(osp.exists(file_zip_name), True) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) - if osp.exists(file_zip_name): - new_name = f'empty_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) + if osp.exists(file_zip_name): + new_name = f'empty_{dump_format_name}.zip' + copyfile(file_zip_name, osp.join(self.assets_path, new_name)) + self.dumped_files_names.append(new_name) def test_api_v1_upload_empty_frames(self): upload_formats = dm.views.get_import_formats() - with TestDir(path=TEST_DATA_ROOT): + with TestDir(path=self.path): for upload_format in upload_formats: - if upload_format.ENABLED: - with self.subTest(): - upload_format_name = upload_format.DISPLAY_NAME - if upload_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - ]: - self.skipTest("Format is fail") - images = self._generate_task_images(3) - task = self._create_task(tasks["no attributes"], images) - task_id = task["id"] + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(self.assets_path, f'empty_CVAT for images 1.1.zip') + else: + file_zip_name = osp.join(self.assets_path, f'empty_{upload_format_name}.zip') + if not osp.exists(file_zip_name) or not upload_format.ENABLED: + continue + with self.subTest(format=upload_format_name): + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + images = self._generate_task_images(3) + task = self._create_task(tasks["no attributes"], images) + task_id = task["id"] - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'empty_CVAT for images 1.1.zip') - else: - file_zip_name = osp.join(self.assets_path, f'empty_{upload_format_name}.zip') + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertIsNone(response.data) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertIsNone(response.data) def test_api_v1_rewriting_annotations(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: for dump_format in dump_formats: - if dump_format.ENABLED: - with self.subTest(): - dump_format_name = dump_format.DISPLAY_NAME - if dump_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - "Datumaro 1.0" # Datumaro 1.0 is not in the list of import format - ]: - self.skipTest("Format is fail") - images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - task_id = task["id"] - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") + if not dump_format.ENABLED: + continue + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(format=dump_format_name): + if dump_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + "Datumaro 1.0" # Datumaro 1.0 is not in the list of import format + ]: + self.skipTest("Format is fail") + images = self._generate_task_images(3) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_ann_prev_data = task_ann.data - url = self._generate_url_dump_tasks_annotations(task_id) + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_ann_prev_data = task_ann.data + url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(osp.exists(file_zip_name), True) + data = { + "format": dump_format_name, + "action": "download", + } + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + response = self._download_file(url, data, self.admin, file_zip_name) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(osp.exists(file_zip_name), True) - self._remove_annotations(url, self.admin) + self._remove_annotations(url, self.admin) - self._create_annotations(task, "CVAT for images 1.1 many jobs", "default") + self._create_annotations(task, "CVAT for images 1.1 many jobs", "default") - if dump_format_name == "CVAT for images 1.1" or dump_format_name == "CVAT for video 1.1": - dump_format_name = "CVAT 1.1" - url = self._generate_url_upload_tasks_annotations(task_id, dump_format_name) + if dump_format_name == "CVAT for images 1.1" or dump_format_name == "CVAT for video 1.1": + dump_format_name = "CVAT 1.1" + url = self._generate_url_upload_tasks_annotations(task_id, dump_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_ann_data = task_ann.data - self.assertEqual(len(task_ann_data["shapes"]), len(task_ann_prev_data["shapes"])) - - - # def test_api_v1_dump_one_type_and_upload_another_type(self): - # test_name = self._testMethodName - # upload_formats = dm.views.get_import_formats() - # dump_formats = dm.views.get_export_formats() - # with TestDir(path=TEST_DATA_ROOT) as test_dir: - # for dump_format in dump_formats: - # images = self._generate_task_images(3) - # # create task with annotations - # task = self._create_task(tasks["main"], images) - # task_id = task["id"] - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # dump_format_name = "CVAT for images 1.1" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # for upload_format in upload_formats: - # if upload_format.ENABLED: - # with self.subTest(): - # upload_format_name = upload_format.DISPLAY_NAME - # if upload_format_name == "CVAT 1.1" or upload_format_name == "COCO 1.0": - # self.skipTest("Skip upload format") - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_ann_data = task_ann.data + self.assertEqual(len(task_ann_data["shapes"]), len(task_ann_prev_data["shapes"])) def test_api_v1_unit_test_on_normalize_shape_function(self): # 3 points @@ -1082,7 +1025,7 @@ def test_api_v1_check_duplicated_polygon_points(self): } self._create_annotations(task, annotation_name, "default") annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] - with TestDir(path=TEST_DATA_ROOT) as test_dir: + with TestDir(path=self.path) as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -1101,581 +1044,49 @@ def test_api_v1_check_duplicated_polygon_points(self): polygon_points = [float(p) for p in polygon_points] self.assertEqual(polygon_points, annotation_points) - # def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): - # test_name = self._testMethodName - # # get formats - # dump_formats = dm.views.get_export_formats() - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # dump_format_name = dump_format.DISPLAY_NAME - # with self.subTest(): - # if dump_format_name in [ - # "CVAT for video 1.1", # issues #2923 and #2924 - # "MOT 1.1", # issue #2925 - # "Datumaro 1.0", # not uploaded - # "WiderFace 1.0", # issue #2944 - # "CamVid 1.0", # issue #2840 and changed points values - # "MOTS PNG 1.0", # issue #2925 and changed points values - # "Segmentation mask 1.1", # changed points values - # "ICDAR Segmentation 1.0", # changed points values - # ]: - # self.skipTest("Format is fail") - # - # for include_images in (False, True): - # # create task - # images = self._generate_task_images(3) - # if dump_format_name == "Market-1501 1.0": - # task = self._create_task(tasks["market1501"], images) - # elif dump_format_name in ["ICDAR Localization 1.0", - # "ICDAR Recognition 1.0"]: - # task = self._create_task(tasks["icdar_localization_and_recognition"], images) - # elif dump_format_name == "ICDAR Segmentation 1.0": - # task = self._create_task(tasks["icdar_segmentation"], images) - # else: - # task = self._create_task(tasks["main"], images) - # - # # create annotations - # if dump_format_name in [ - # "MOT 1.1", "MOTS PNG 1.0", \ - # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - # "WiderFace 1.0", "VGGFace2 1.0", \ - # ]: - # self._create_annotations(task, dump_format_name, "default") - # else: - # self._create_annotations(task, dump_format_name, "random") - # - # task_id = task["id"] - # data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - # upload_format_name = "CVAT 1.1" - # else: - # upload_format_name = dump_format_name - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - - # # 24 - # def test_api_v1_tasks_annotations_update_wrong_label(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "default") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_label.zip') - # - # # download zip file - # self._download_file(url, data, self.admin, file_zip_name_before_change) - # self._check_downloaded_file(file_zip_name_before_change) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # - # # change right label to wrong - # wrong_label = "wrong_label" - # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - # root = tree.getroot() - # element = root.find("./image[@id='0']/box[@label='car']") - # element.attrib["label"] = wrong_label - # tree.write(osp.join(folder_name, 'annotations.xml')) - # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name_after_change, 'rb') as binary_file: - # #with self.assertRaisesRegex(ValueError, f"Label '{wrong_label}' is not registered for this task"): - # # self._upload_file(url_upload, binary_file, self.admin) - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - # - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # self.assertEqual(len(response.data["tracks"]), 0) - # - # # 25 - # def test_api_v1_tasks_annotations_update_wrong_value_in_checkbox(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["wrong_checkbox_value"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name_before_change = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # file_zip_name_after_change = osp.join(test_dir, f'{test_name}_{dump_format_name}_wrong_checkbox_value.zip') - # - # # download zip file - # self._download_file(url, data, self.admin, file_zip_name_before_change) - # self._check_downloaded_file(file_zip_name_before_change) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name_before_change, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # - # # change right label to wrong - # wrong_checkbox_value = "wrong_checkbox_value" - # tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - # root = tree.getroot() - # element = root.find("./image[@id='0']/box[@label='car']/attribute[@name='check_name']") - # element.text = wrong_checkbox_value - # tree.write(osp.join(folder_name, 'annotations.xml')) - # with zipfile.ZipFile(file_zip_name_after_change, 'w') as zip_ref: - # zip_ref.write(osp.join(folder_name, 'annotations.xml'), 'annotations.xml') - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name_after_change, 'rb') as binary_file: - # #with self.assertRaisesRegex(Exception, f"Failed to convert attribute 'car'='{wrong_checkbox_value}'"): - # # self._upload_file(url_upload, binary_file, self.admin) - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # self.assertEqual(len(response.data["tracks"]), 0) - - # def test_api_v1_tasks_annotations_dump_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - - # def test_api_v1_tasks_dataset_export_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump dataset - # url = f"/api/v1/tasks/{task_id}/dataset" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_admin_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_user_{dump_format_name}.zip') - # response = self._download_file(url, data, self.user, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self._check_downloaded_file(file_zip_name) - # - # file_zip_name = osp.join(test_dir, f'{test_name}_None_{dump_format_name}.zip') - # response = self._download_file(url, data, None, file_zip_name) - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # with self.assertRaises(FileNotFoundError): - # self._check_downloaded_file(file_zip_name) - # - # def test_api_v1_tasks_annotations_update_others_user(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(3) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, dump_format_name, "random") - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # response = self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # for user in [self.admin, self.user, None]: - # with open(file_zip_name, 'rb') as binary_file: - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # response = self._upload_file(url_upload, binary_file, user) - # - # if user is None: - # self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) - # # check for missing annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 0) - # self.assertEqual(len(response.data["shapes"]), 0) - # else: - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # # check for presence annotations - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertNotEqual(len(response.data["tags"]), 0) - # self.assertNotEqual(len(response.data["shapes"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_dataset_export_with_datumaro(self): - # test_name = self._testMethodName - # importer_format_name = { - # 'COCO 1.0': 'coco', - # 'CVAT for images 1.1': 'cvat', - # 'CVAT for video 1.1': 'cvat', - # 'Datumaro 1.0': 'datumaro_project', - # 'LabelMe 3.0': 'label_me', - # 'MOT 1.1': 'mot_seq', - # 'MOTS PNG 1.0': 'mots_png', - # 'PASCAL VOC 1.1': 'voc', - # 'Segmentation mask 1.1': 'voc', - # 'TFRecord 1.0': 'tf_detection_api', - # 'YOLO 1.1': 'yolo', - # 'ImageNet 1.0': 'imagenet_txt', - # 'CamVid 1.0': 'camvid', - # 'WiderFace 1.0': 'wider_face', - # 'VGGFace2 1.0': 'vgg_face2', - # 'Market-1501 1.0': 'market1501', - # 'ICDAR Localization 1.0': 'icdar_text_localization', - # 'ICDAR Recognition 1.0': 'icdar_word_recognition', - # 'ICDAR Segmentation 1.0': 'icdar_text_segmentation', - # } - # - # # get formats - # dump_formats = dm.views.get_export_formats() - # - # for dump_format in dump_formats: - # if dump_format.ENABLED: - # dump_format_name = dump_format.DISPLAY_NAME - # - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", - # "YOLO 1.1", - # "ImageNet 1.0", - # "Datumaro 1.0", - # ]: - # self.skipTest("Format is fail") - # - # # create task - # images = self._generate_task_images(3) - # if dump_format_name == "Market-1501 1.0": - # task = self._create_task(tasks["market1501"], images) - # elif dump_format_name in ["ICDAR Localization 1.0", - # "ICDAR Recognition 1.0"]: - # task = self._create_task(tasks["icdar_localization_and_recognition"], images) - # elif dump_format_name == "ICDAR Segmentation 1.0": - # task = self._create_task(tasks["icdar_segmentation"], images) - # else: - # task = self._create_task(tasks["main"], images) - # - # # create annotations - # if dump_format_name in [ - # "MOT 1.1", "MOTS PNG 1.0", \ - # "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - # "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - # "WiderFace 1.0", "VGGFace2 1.0", \ - # ]: - # self._create_annotations(task, dump_format_name, "default") - # else: - # self._create_annotations(task, dump_format_name, "random") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # - # data_datumaro = { - # "dataset": None, - # "annotations": None, - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # for type_file in ("dataset", "annotations"): - # # dump file - # url = f"/api/v1/tasks/{task_id}/{type_file}" - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # file_zip_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # extract zip - # folder_name = osp.join(test_dir, f'{test_name}_{type_file}_{dump_format_name}') - # with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - # zip_ref.extractall(folder_name) - # data_datumaro[type_file] = Dataset.import_from(folder_name, importer_format_name[dump_format_name]) - # - # # equals dataset vs annotations - # compare_datasets(self, data_datumaro["dataset"], data_datumaro["annotations"]) - # - # def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): - # test_name = self._testMethodName - # upload_format_name = "CVAT 1.1" - # - # for include_images in (False, True): - # for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - # with self.subTest(): - # # TODO skip failed formats - # if dump_format_name in [ - # "CVAT for video 1.1", # issues #2923 and #2945 - # ]: - # self.skipTest("Format is fail") - # - # # create task with annotations - # images = self._generate_task_images(13) - # task = self._create_task(tasks["many jobs"], images) - # self._create_annotations(task, f'{dump_format_name} many jobs', "default") - # - # task_id = task["id"] - # data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # data_from_task_after_upload = self._get_data_from_task(task_id, include_images) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_slice_track_with_datumaro(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for video 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(5) - # task = self._create_task(tasks["main"], images) - # self._create_annotations(task, f'{dump_format_name} slice track', "default") - # - # task_id = task["id"] - # data_from_task_before_upload = self._get_data_from_task(task_id) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # data_from_task_after_upload = self._get_data_from_task(task_id) - # compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) - # - # def test_api_v1_tasks_annotations_dump_and_upload_merge(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change overlap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # remove annotations - # self._remove_annotations(url, self.admin) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) - # - # def test_api_v1_tasks_annotations_dump_and_upload_rewrite(self): - # test_name = self._testMethodName - # dump_format_name = "CVAT for images 1.1" - # upload_format_name = "CVAT 1.1" - # - # # create task with annotations - # images = self._generate_task_images(10) - # task = self._create_task(tasks["change overlap and segment size"], images) - # self._create_annotations(task, f'{dump_format_name} merge', "default") - # - # task_id = task["id"] - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # # dump annotations - # url = self._generate_url_dump_tasks_annotations(task_id) - # data = { - # "format": dump_format_name, - # "action": "download", - # } - # with TestDir(path = TEST_DATA_ROOT) as test_dir: - # file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - # self._download_file(url, data, self.admin, file_zip_name) - # self._check_downloaded_file(file_zip_name) - # - # # upload annotations - # url_upload = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - # with open(file_zip_name, 'rb') as binary_file: - # response = self._upload_file(url_upload, binary_file, self.admin) - # self.assertEqual(response.status_code, status.HTTP_201_CREATED) - # - # # equals annotations - # task_ann = TaskAnnotation(task_id) - # task_ann.init_from_db() - # TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - # - # response = self._get_request(url, self.admin) - # self.assertEqual(response.status_code, status.HTTP_200_OK) - # self.assertEqual(len(response.data["tags"]), 1) - # self.assertEqual(len(response.data["shapes"]), 14) # convert tracks to shapes - # self.assertEqual(len(response.data["tracks"]), 0) + def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): + test_name = self._testMethodName + upload_format_name = "CVAT 1.1" + + for include_images in (False, True): + for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): + with self.subTest(): + # create task with annotations + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, binary_file, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) From b5e15af742a4368a9dd3ccac952377d1a6510677 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 1 Jun 2021 21:57:26 +0300 Subject: [PATCH 24/43] Test refactoring and code review --- .../tests/assets/annotations.json | 17 +- .../tests/test_rest_api_formats.py | 317 ++++++++---------- 2 files changed, 140 insertions(+), 194 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 1af76596b14..d5e70e0bae4 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -753,22 +753,7 @@ }, "CVAT for video 1.1 many jobs": { "version": 0, - "tags": [ - { - "frame": 1, - "label_id": null, - "group": 0, - "source": "manual", - "attributes": [] - }, - { - "frame": 8, - "label_id": null, - "group": 0, - "source": "manual", - "attributes": [] - } - ], +/E "tags": [], "shapes": [], "tracks": [ { diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index a65cd4ec4a9..309d2ebb892 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -152,27 +152,6 @@ def _generate_task_videos(count): # pylint: disable=no-self-use videos["image_quality"] = 75 return videos - # def _create_task(self, data, image_data): - # with ForceLogin(self.admin, self.client): - # response = self.client.post('/api/v1/tasks', data=data, format="json") - # assert response.status_code == status.HTTP_201_CREATED, response.status_code - # tid = response.data["id"] - # - # response = self.client.post("/api/v1/tasks/%s/data" % tid, - # data=image_data) - # assert response.status_code == status.HTTP_202_ACCEPTED, response.status_code - # - # for _ in range(5): - # response = self.client.get("/api/v1/tasks/%s/status" % tid) - # if response.status_code == status.HTTP_200_OK: - # break - # assert response.status_code == status.HTTP_200_OK, response.status_code - # - # response = self.client.get("/api/v1/tasks/%s" % tid) - # task = response.data - # - # return task - def _create_task(self, data, image_data): with ForceLogin(self.user, self.client): response = self.client.post('/api/v1/tasks', data=data, format="json") @@ -294,13 +273,10 @@ def _download_file(self, url, data, user, file_name): break return response - def _upload_file(self, url, binary_file, user): + def _upload_file(self, url, data, user): with ForceLogin(user, self.client): - for _ in range(5): - response = self.client.put(url, {"annotation_file": binary_file}) - if response.status_code == status.HTTP_201_CREATED: - break - return response + response = self.client.put(url, data) + return response def _check_downloaded_file(self, file_name): if not osp.exists(file_name): @@ -362,30 +338,26 @@ def _get_data_from_task(self, task_id, include_images=False): """ class TaskDumpUploadTest(_DbTestBase): - @classmethod - def setUpClass(cls): - super().setUpClass() - cls.assets_path = osp.join(osp.dirname(__file__), 'assets') - cls.dumped_files_names = [] - cls.path = "/tmp/cvat_".join(random.choice(string.ascii_lowercase) for i in range(10)) - - @classmethod - def tearDownClass(cls): - super().tearDownClass() - for dumped_file in cls.dumped_files_names: - os.remove(osp.join(cls.assets_path, dumped_file)) - def test_api_v1_dump_annotations_with_objects_type_is_shape(self): + def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() - - expected = { + upload_formats = dm.views.get_import_formats() + expected_dump = { + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + } + expected_upload = { + self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, + 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, + 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'accept code': status.HTTP_401_UNAUTHORIZED, + 'annotation_loaded': False}, } - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: # Dump annotations with objects type is shape for dump_format in dump_formats: if not dump_format.ENABLED: @@ -419,85 +391,74 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape(self): "format": dump_format_name, "action": "download", } - for user, edata in list(expected.items()): + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + prev_data = task_ann.data + for user, edata in list(expected_dump.items()): user_name = edata['name'] file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') response = self._download_file(url, data, user, file_zip_name) self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - if osp.exists(file_zip_name) and user == self.admin: - new_name = f'shape_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) - def test_api_v1_upload_annotations_with_objects_type_is_shape(self): - upload_formats = dm.views.get_import_formats() - - expected = { - self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, - self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'annotation_loaded': False}, - } - # Upload annotations with objects type is shape - for upload_format in upload_formats: - upload_format_name = upload_format.DISPLAY_NAME - if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') - else: - file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') - if not upload_format.ENABLED or not osp.exists(file_zip_name): - continue - with self.subTest(format=upload_format_name): - if upload_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - ]: - self.skipTest("Format is fail") + # Upload annotations with objects type is shape + for upload_format in upload_formats: + upload_format_name = upload_format.DISPLAY_NAME if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'shape_CVAT for images 1.1.zip') + file_zip_name = osp.join(test_dir, f'{test_name}_admin_CVAT for images 1.1.zip.zip') else: - file_zip_name = osp.join(self.assets_path, f'shape_{upload_format_name}.zip') - if osp.exists(file_zip_name): - for user, edata in list(expected.items()): - # remove all annotations from task (create new task without annotation) - images = self._generate_task_images(3) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) - task_id = task["id"] - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, user) - self.assertEqual(response.status_code, edata['code']) + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{upload_format_name}.zip') + if not upload_format.ENABLED or not osp.exists(file_zip_name): + continue + with self.subTest(format=upload_format_name): + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if osp.exists(file_zip_name): + for user, edata in list(expected_upload.items()): + # remove all annotations from task (create new task without annotation) + images = self._generate_task_images(3) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, {"annotation_file": binary_file}, user) + self.assertEqual(response.status_code, edata['accept code']) + response = self._upload_file(url, {}, user) + self.assertEqual(response.status_code, edata['code']) def test_api_v1_dump_annotations_with_objects_type_is_track(self): test_name = self._testMethodName - dump_format_name = "CVAT for video 1.1" - # create task with annotations - video = self._generate_task_videos(1) - - task = self._create_task(tasks["main"], video) - self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() dump_formats = dm.views.get_export_formats() - - expected = { + upload_formats = dm.views.get_import_formats() + expected_upload = { + self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, + 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, + 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'accept code': status.HTTP_401_UNAUTHORIZED, + 'annotation_loaded': False}, + } + expected_dump = { self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } - with TestDir(path=self.path) as test_dir: - # Dump annotations with objects type is shape + with TestDir() as test_dir: + # Dump annotations with objects type is track for dump_format in dump_formats: if not dump_format.ENABLED: continue @@ -531,56 +492,46 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): "format": dump_format_name, "action": "download", } - for user, edata in list(expected.items()): + for user, edata in list(expected_dump.items()): user_name = edata['name'] file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') response = self._download_file(url, data, user, file_zip_name) self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) - if osp.exists(file_zip_name) and user == self.admin: - new_name = f'track_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) - - def test_api_v1_upload_annotations_with_objects_type_is_track(self): - upload_formats = dm.views.get_import_formats() - expected = { - self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, - self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'annotation_loaded': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'annotation_loaded': False}, - } - # Upload annotations with objects type is shape - for upload_format in upload_formats: - upload_format_name = upload_format.DISPLAY_NAME - if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'track_CVAT for video 1.1.zip') - else: - file_zip_name = osp.join(self.assets_path, f'track_{upload_format_name}.zip') - if not upload_format.ENABLED or not osp.exists(file_zip_name): - continue - with self.subTest(format=upload_format_name): - if upload_format_name in [ - "MOTS PNG 1.0", # issue #2925 and changed points values - ]: - self.skipTest("Format is fail") - if osp.exists(file_zip_name): - for user, edata in list(expected.items()): - # remove all annotations from task (create new task without annotation) - video = self._generate_task_videos(1) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], video) - elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], video) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], video) - else: - task = self._create_task(tasks["main"], video) - task_id = task["id"] - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + # Upload annotations with objects type is track + for upload_format in upload_formats: + upload_format_name = upload_format.DISPLAY_NAME + if upload_format_name == "CVAT 1.1": + file_zip_name = osp.join(test_dir, f'{test_name}_admin_CVAT for video 1.1.zip') + else: + file_zip_name = osp.join(test_dir, f'{test_name}_admin_{upload_format_name}.zip') + if not upload_format.ENABLED or not osp.exists(file_zip_name): + continue + with self.subTest(format=upload_format_name): + if upload_format_name in [ + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + if osp.exists(file_zip_name): + for user, edata in list(expected_upload.items()): + # remove all annotations from task (create new task without annotation) + video = self._generate_task_videos(1) + if upload_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], video) + elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], video) + elif upload_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], video) + else: + task = self._create_task(tasks["main"], video) + task_id = task["id"] + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, user) - self.assertEqual(response.status_code, edata['code']) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, {"annotation_file": binary_file}, user) + self.assertEqual(response.status_code, edata['accept code']) + response = self._upload_file(url, {}, user) + self.assertEqual(response.status_code, edata['code']) def test_api_v1_dump_tag_annotations(self): dump_format_name = "CVAT for images 1.1" @@ -607,7 +558,7 @@ def test_api_v1_dump_tag_annotations(self): for user, edata in list(expected.items()): with self.subTest(format=f"{edata['name']}"): - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: user_name = edata['name'] url = self._generate_url_dump_tasks_annotations(task_id) @@ -631,7 +582,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se for type in upload_types: with self.subTest(format=type): - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: if type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: @@ -652,7 +603,9 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) + response = self._upload_file(url_upload, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url_upload, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) response = self._get_request(url, self.admin) @@ -674,7 +627,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel for type in upload_types: with self.subTest(format=type): - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: if type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: @@ -695,7 +648,9 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, binary_file, self.admin) + response = self._upload_file(url_upload, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url_upload, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(osp.exists(file_zip_name), True) @@ -715,7 +670,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( self._create_annotations(task, "CVAT for video 1.1 slice track", "random") task_id = task["id"] - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -724,7 +679,9 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( with open(file_zip_name, 'rb') as binary_file: url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): @@ -739,7 +696,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property self._create_annotations(task, "CVAT for video 1.1 slice track keyframe", "random") task_id = task["id"] - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -748,7 +705,9 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property with open(file_zip_name, 'rb') as binary_file: url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def test_api_v1_dump_upload_annotations_from_several_jobs(self): @@ -766,7 +725,7 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): for job in jobs: self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 merge", "random") - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -777,7 +736,9 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): self._remove_annotations(url, self.admin) url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): @@ -794,7 +755,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se task_id = task["id"] for test_case in test_cases: - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: jobs = self._get_jobs(task_id) if test_case == "all": for job in jobs: @@ -813,7 +774,9 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se self._remove_annotations(url, self.admin) url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) def test_api_v1_export_dataset(self): @@ -826,7 +789,7 @@ def test_api_v1_export_dataset(self): None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: # Dump annotations with objects type is shape for dump_format in dump_formats: if not dump_format.ENABLED or dump_format.DISPLAY_NAME != "CVAT for images 1.1": @@ -859,8 +822,9 @@ def test_api_v1_export_dataset(self): def test_api_v1_dump_empty_frames(self): dump_formats = dm.views.get_export_formats() + upload_formats = dm.views.get_import_formats() - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: for dump_format in dump_formats: if not dump_format.ENABLED: continue @@ -882,21 +846,12 @@ def test_api_v1_dump_empty_frames(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(osp.exists(file_zip_name), True) - if osp.exists(file_zip_name): - new_name = f'empty_{dump_format_name}.zip' - copyfile(file_zip_name, osp.join(self.assets_path, new_name)) - self.dumped_files_names.append(new_name) - - def test_api_v1_upload_empty_frames(self): - upload_formats = dm.views.get_import_formats() - - with TestDir(path=self.path): for upload_format in upload_formats: upload_format_name = upload_format.DISPLAY_NAME if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(self.assets_path, f'empty_CVAT for images 1.1.zip') + file_zip_name = osp.join(test_dir, f'empty_CVAT for images 1.1.zip') else: - file_zip_name = osp.join(self.assets_path, f'empty_{upload_format_name}.zip') + file_zip_name = osp.join(test_dir, f'empty_{upload_format_name}.zip') if not osp.exists(file_zip_name) or not upload_format.ENABLED: continue with self.subTest(format=upload_format_name): @@ -911,14 +866,16 @@ def test_api_v1_upload_empty_frames(self): url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertIsNone(response.data) def test_api_v1_rewriting_annotations(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: for dump_format in dump_formats: if not dump_format.ENABLED: continue @@ -972,7 +929,9 @@ def test_api_v1_rewriting_annotations(self): url = self._generate_url_upload_tasks_annotations(task_id, dump_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) task_ann = TaskAnnotation(task_id) task_ann.init_from_db() @@ -1025,7 +984,7 @@ def test_api_v1_check_duplicated_polygon_points(self): } self._create_annotations(task, annotation_name, "default") annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] - with TestDir(path=self.path) as test_dir: + with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') response = self._download_file(url, data, self.admin, file_zip_name) @@ -1080,7 +1039,9 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): # upload annotations url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, binary_file, self.admin) + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) # equals annotations From 35482c4cc28259e5f1510579b7e64bf844815e4e Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 1 Jun 2021 22:02:17 +0300 Subject: [PATCH 25/43] Small fix --- cvat/apps/dataset_manager/tests/assets/annotations.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index d5e70e0bae4..38c8655f7f3 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -753,7 +753,7 @@ }, "CVAT for video 1.1 many jobs": { "version": 0, -/E "tags": [], + "tags": [], "shapes": [], "tracks": [ { From 0ef79a5b1e12b7fc3dd4d82ad7d76aa1eb583d97 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Wed, 2 Jun 2021 12:45:57 +0300 Subject: [PATCH 26/43] Put back test test_api_v1_tasks_annotations_dump_and_upload_with_datumaro --- .../tests/test_rest_api_formats.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 309d2ebb892..a1de9e3e375 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1051,3 +1051,74 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): extractor = CvatTaskDataExtractor(task_data, include_images=include_images) data_from_task_after_upload = Dataset.from_extractors(extractor) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): + test_name = self._testMethodName + # get formats + dump_formats = dm.views.get_export_formats() + for dump_format in dump_formats: + if dump_format.ENABLED: + dump_format_name = dump_format.DISPLAY_NAME + with self.subTest(): + if dump_format_name in [ + "MOT 1.1", # issue #2925 + "Datumaro 1.0", # not uploaded + "MOTS PNG 1.0", # issue #2925 and changed points values + ]: + self.skipTest("Format is fail") + + for include_images in (False, True): + # create task + images = self._generate_task_images(3) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) + + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") + + task_id = task["id"] + data_from_task_before_upload = self._get_data_from_task(task_id, include_images) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._upload_file(url, {}, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + # equals annotations + data_from_task_after_upload = self._get_data_from_task(task_id, include_images) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) From a12f3d83b7902c432000a8636f00b77264a7c9d1 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Wed, 2 Jun 2021 13:48:45 +0300 Subject: [PATCH 27/43] Small corrections of test test_api_v1_tasks_annotations_dump_and_upload_with_datumaro --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index a1de9e3e375..fa744fe12e4 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1063,7 +1063,11 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): if dump_format_name in [ "MOT 1.1", # issue #2925 "Datumaro 1.0", # not uploaded + "WiderFace 1.0", # issue #2944 + "CamVid 1.0", # issue #2840 and changed points values "MOTS PNG 1.0", # issue #2925 and changed points values + "Segmentation mask 1.1", # changed points values + "ICDAR Segmentation 1.0", # changed points values ]: self.skipTest("Format is fail") From c80db55a69f4d69e5575f8c115b25245d346683e Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 3 Jun 2021 12:30:08 +0300 Subject: [PATCH 28/43] Change download file logic. --- .../tests/test_rest_api_formats.py | 426 ++++++++++++------ 1 file changed, 298 insertions(+), 128 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index fa744fe12e4..35587b3f5e9 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -263,14 +263,9 @@ def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): response = self._put_api_v1_job_id_annotations(job_id, tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) - def _download_file(self, url, data, user, file_name): - for _ in range(5): - response = self._get_request_with_data(url, data, user) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_name, "wb") as f: - f.write(content.getvalue()) - break + def _dump_api_v1_tasks_id_annotations(self, url, data, user): + with ForceLogin(user, self.client): + response = self.client.get(url, data) return response def _upload_file(self, url, data, user): @@ -282,8 +277,8 @@ def _check_downloaded_file(self, file_name): if not osp.exists(file_name): raise FileNotFoundError(f"File '{file_name}' was not downloaded") - def _generate_url_dump_tasks_annotations(self, task_id): - return f"/api/v1/tasks/{task_id}/annotations" + def _generate_url_dump_tasks_annotations(self, task_id, dump_format_name): + return f"/api/v1/tasks/{task_id}/annotations?format={dump_format_name}" def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" @@ -343,18 +338,13 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() upload_formats = dm.views.get_import_formats() - expected_dump = { - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, - self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, - self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - } - expected_upload = { - self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, - 'annotation_loaded': True}, - self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, - 'annotation_loaded': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'accept code': status.HTTP_401_UNAUTHORIZED, - 'annotation_loaded': False}, + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED,'file_exists': True, 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True, 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'create code': status.HTTP_401_UNAUTHORIZED, + 'accept code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False, 'annotation_loaded': False}, } with TestDir() as test_dir: @@ -385,21 +375,33 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): else: self._create_annotations(task, dump_format_name, "random") # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) - data = { - "format": dump_format_name, - "action": "download", - } - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - prev_data = task_ann.data - for user, edata in list(expected_dump.items()): + for user, edata in list(expected.items()): user_name = edata['name'] file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) - + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['accept code']) + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['create code']) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['create code']) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) self.assertEqual(response.status_code, edata['code']) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) # Upload annotations with objects type is shape @@ -418,7 +420,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): ]: self.skipTest("Format is fail") if osp.exists(file_zip_name): - for user, edata in list(expected_upload.items()): + for user, edata in list(expected.items()): # remove all annotations from task (create new task without annotation) images = self._generate_task_images(3) if upload_format_name == "Market-1501 1.0": @@ -436,25 +438,20 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): response = self._upload_file(url, {"annotation_file": binary_file}, user) self.assertEqual(response.status_code, edata['accept code']) response = self._upload_file(url, {}, user) - self.assertEqual(response.status_code, edata['code']) + self.assertEqual(response.status_code, edata['create code']) def test_api_v1_dump_annotations_with_objects_type_is_track(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() upload_formats = dm.views.get_import_formats() - expected_upload = { - self.admin: {'name': 'admin', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, - 'annotation_loaded': True}, - self.user: {'name': 'user', 'code': status.HTTP_201_CREATED, 'accept code': status.HTTP_202_ACCEPTED, - 'annotation_loaded': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'accept code': status.HTTP_401_UNAUTHORIZED, - 'annotation_loaded': False}, - } - expected_dump = { - self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, - self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + expected = { + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True, 'annotation_loaded': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True, 'annotation_loaded': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'create code': status.HTTP_401_UNAUTHORIZED, + 'accept code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False, 'annotation_loaded': False}, } with TestDir() as test_dir: @@ -486,17 +483,28 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): else: self._create_annotations(task, dump_format_name, "random") # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) - data = { - "format": dump_format_name, - "action": "download", - } - for user, edata in list(expected_dump.items()): + for user, edata in list(expected.items()): user_name = edata['name'] file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['accept code']) + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['create code']) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) self.assertEqual(response.status_code, edata['code']) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) # Upload annotations with objects type is track for upload_format in upload_formats: @@ -513,7 +521,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): ]: self.skipTest("Format is fail") if osp.exists(file_zip_name): - for user, edata in list(expected_upload.items()): + for user, edata in list(expected.items()): # remove all annotations from task (create new task without annotation) video = self._generate_task_videos(1) if upload_format_name == "Market-1501 1.0": @@ -531,7 +539,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): response = self._upload_file(url, {"annotation_file": binary_file}, user) self.assertEqual(response.status_code, edata['accept code']) response = self._upload_file(url, {}, user) - self.assertEqual(response.status_code, edata['code']) + self.assertEqual(response.status_code, edata['create code']) def test_api_v1_dump_tag_annotations(self): dump_format_name = "CVAT for images 1.1" @@ -541,8 +549,12 @@ def test_api_v1_dump_tag_annotations(self): } test_cases = ['all' 'first'] expected = { - self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, - self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'create code': status.HTTP_401_UNAUTHORIZED, + 'accept code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } for test_case in test_cases: images = self._generate_task_images(10) @@ -560,20 +572,31 @@ def test_api_v1_dump_tag_annotations(self): with self.subTest(format=f"{edata['name']}"): with TestDir() as test_dir: user_name = edata['name'] - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{user_name}.zip') - response = self._download_file(url, data, user, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['accept code']) + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata['create code']) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) self.assertEqual(response.status_code, edata['code']) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" - data = { - "format": dump_format_name, - "action": "download", - } upload_types = ["task", "job"] images = self._generate_task_images(2) @@ -589,11 +612,26 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if type == "task": @@ -608,17 +646,13 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se response = self._upload_file(url_upload, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) - response = self._get_request(url, self.admin) + response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) self.assertEqual(len(response.data["shapes"]), 2) self.assertEqual(len(response.data["tracks"]), 0) def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" - data = { - "format": dump_format_name, - "action": "download", - } upload_types = ["task", "job"] video = self._generate_task_videos(1) @@ -634,11 +668,25 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') - - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if type == "task": @@ -654,27 +702,38 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(osp.exists(file_zip_name), True) - response = self._get_request(url, self.admin) + response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) self.assertEqual(len(response.data["shapes"]), 0) self.assertEqual(len(response.data["tracks"]), 2) def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" - data = { - "format": dump_format_name, - "action": "download", - } video = self._generate_task_videos(1) task = self._create_task(tasks["main"], video) self._create_annotations(task, "CVAT for video 1.1 slice track", "random") task_id = task["id"] with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) with open(file_zip_name, 'rb') as binary_file: @@ -687,19 +746,32 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): test_name = self._testMethodName dump_format_name = "CVAT for video 1.1" - data = { - "format": dump_format_name, - "action": "download", - } + video = self._generate_task_videos(1) task = self._create_task(tasks["main"], video) self._create_annotations(task, "CVAT for video 1.1 slice track keyframe", "random") task_id = task["id"] with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(osp.exists(file_zip_name), True) @@ -713,10 +785,6 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property def test_api_v1_dump_upload_annotations_from_several_jobs(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" - data = { - "format": dump_format_name, - "action": "download", - } images = self._generate_task_images(10) task = self._create_task(tasks["change overlap and segment size"], images) @@ -726,10 +794,25 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 merge", "random") with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -763,11 +846,26 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se else: self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default") - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -784,9 +882,12 @@ def test_api_v1_export_dataset(self): dump_formats = dm.views.get_export_formats() expected = { - self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'file_exists': True}, - self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'file_exists': True}, - None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, + self.admin: {'name': 'admin', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True}, + self.user: {'name': 'user', 'code': status.HTTP_200_OK, 'create code': status.HTTP_201_CREATED, + 'accept code': status.HTTP_202_ACCEPTED, 'file_exists': True}, + None: {'name': 'none', 'code': status.HTTP_401_UNAUTHORIZED, 'create code': status.HTTP_401_UNAUTHORIZED, + 'accept code': status.HTTP_401_UNAUTHORIZED, 'file_exists': False}, } with TestDir() as test_dir: @@ -809,14 +910,26 @@ def test_api_v1_export_dataset(self): task_id = task["id"] # dump annotations url = self._generate_url_dump_dataset(task_id) - data = { - "format": dump_format_name, - "action": "download", - } for user, edata in list(expected.items()): user_name = edata['name'] file_zip_name = osp.join(test_dir, f'{test_name}_{user_name}_{dump_format_name}.zip') - response = self._download_file(url, data, user, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata["accept code"]) + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata["create code"]) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, user) + self.assertEqual(response.status_code, edata["code"]) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(response.status_code, edata['code']) self.assertEqual(osp.exists(file_zip_name), edata['file_exists']) @@ -834,16 +947,26 @@ def test_api_v1_dump_empty_frames(self): task = self._create_task(tasks["no attributes"], images) task_id = task["id"] self._create_annotations(task, "empty annotation", "default") - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) - + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) for upload_format in upload_formats: @@ -909,15 +1032,26 @@ def test_api_v1_rewriting_annotations(self): task_ann = TaskAnnotation(task_id) task_ann.init_from_db() task_ann_prev_data = task_ann.data - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) @@ -978,17 +1112,29 @@ def test_api_v1_check_duplicated_polygon_points(self): task = self._create_task(tasks["main"], images) task_id = task["id"] annotation_name = "CVAT for video 1.1 polygon" - data = { - "format": "CVAT for video 1.1", - "action": "download", - } + dump_format_name = "CVAT for video 1.1" self._create_annotations(task, annotation_name, "default") annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id) + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - response = self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # extract zip folder_name = osp.join(test_dir, f'{test_name}') @@ -1023,14 +1169,26 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): data_from_task_before_upload = Dataset.from_extractors(extractor) # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self._check_downloaded_file(file_zip_name) # remove annotations @@ -1099,14 +1257,26 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): data_from_task_before_upload = self._get_data_from_task(task_id, include_images) # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - data = { - "format": dump_format_name, - "action": "download", - } + url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - self._download_file(url, data, self.admin, file_zip_name) + data = { + "format": dump_format_name, + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { + "format": dump_format_name, + "action": "download", + } + response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) + self.assertEqual(response.status_code, status.HTTP_200_OK) + if response.status_code == status.HTTP_200_OK: + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self._check_downloaded_file(file_zip_name) # remove annotations From 49c50d9f436ef549d7590cd839fc9db74132332d Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 3 Jun 2021 12:32:13 +0300 Subject: [PATCH 29/43] Fix a typo. --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 35587b3f5e9..f82401c7d37 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -408,7 +408,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): for upload_format in upload_formats: upload_format_name = upload_format.DISPLAY_NAME if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(test_dir, f'{test_name}_admin_CVAT for images 1.1.zip.zip') + file_zip_name = osp.join(test_dir, f'{test_name}_admin_CVAT for images 1.1.zip') else: file_zip_name = osp.join(test_dir, f'{test_name}_admin_{upload_format_name}.zip') From e2e8c2e1436043b6a21106cf5736626a7740548b Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 3 Jun 2021 14:40:05 +0300 Subject: [PATCH 30/43] Remove Pylint warnings. --- .../tests/test_rest_api_formats.py | 85 ++++++------------- 1 file changed, 24 insertions(+), 61 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index f82401c7d37..7ed58b33827 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -8,17 +8,12 @@ import json import os.path as osp import os -import shutil -import random -import sys import xml.etree.ElementTree as ET import zipfile -from shutil import copyfile from io import BytesIO import av import numpy as np import random -import string from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir @@ -33,14 +28,13 @@ from cvat.apps.dataset_manager.annotation import TrackManager from cvat.apps.engine.models import Task -path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') -with open(path) as f: - tasks = json.load(f) - -path = osp.join(osp.dirname(__file__), 'assets', 'annotations.json') -with open(path) as f: - annotations = json.load(f) +tasks_path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') +with open(tasks_path) as file: + tasks = json.load(file) +annotation_path = osp.join(osp.dirname(__file__), 'assets', 'annotations.json') +with open(annotation_path) as file: + annotations = json.load(file) def generate_image_file(filename, size=(100, 50)): @@ -270,7 +264,7 @@ def _dump_api_v1_tasks_id_annotations(self, url, data, user): def _upload_file(self, url, data, user): with ForceLogin(user, self.client): - response = self.client.put(url, data) + response = self.client.put(url, data) return response def _check_downloaded_file(self, file_name): @@ -304,36 +298,9 @@ def _get_data_from_task(self, task_id, include_images=False): extractor = CvatTaskDataExtractor(task_data, include_images=include_images) data_from_task = Dataset.from_extractors(extractor) return data_from_task -""" -Need to write REST API tests for server (dataset manager): - # Dump annotations with objects type is shape - # Upload annotations with objects type is shape - # Dump annotations with objects type is track - # Upload annotations with objects type is track - # Dump tag annotations - # Dump/upload annotations with objects are different types (images) - # Dump/upload annotations with objects are different types (video) - # Dump/upload with objects type is track and outside property - # Dump/upload with objects type is track and keyframe property - # Dump/upload annotations from several jobs - # Dump annotations with objects type is shape from several jobs - # Dump annotations with objects type is track from several jobs - # Export dataset - # Wrong label in input file - # Wrong value checkbox in input file - # Dump annotations with attributes - # Upload annotations with attributes - # Dump empty frames - # Upload empty frames - # Rewriting annotations - # Dump one type and upload another type - # Unit test on to_track function - # Unit test on normalize_shape function - # Unit test on export_job function -""" -class TaskDumpUploadTest(_DbTestBase): +class TaskDumpUploadTest(_DbTestBase): def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): test_name = self._testMethodName dump_formats = dm.views.get_export_formats() @@ -603,17 +570,17 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se task = self._create_task(tasks["main"], images) task_id = task["id"] - for type in upload_types: + for upload_type in upload_types: with self.subTest(format=type): with TestDir() as test_dir: - if type == "task": + if upload_type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) - file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') + file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') data = { "format": dump_format_name, @@ -634,7 +601,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) - if type == "task": + if upload_type == "task": url_upload = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") else: jobs = self._get_jobs(task_id) @@ -659,17 +626,17 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel task = self._create_task(tasks["main"], video) task_id = task["id"] - for type in upload_types: + for upload_type in upload_types: with self.subTest(format=type): with TestDir() as test_dir: - if type == "task": + if upload_type == "task": self._create_annotations(task, "CVAT for images 1.1 different types", "random") else: jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) - file_zip_name = osp.join(test_dir, f'{test_name}_{type}.zip') + file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') data = { "format": dump_format_name, } @@ -689,7 +656,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) - if type == "task": + if upload_type == "task": url_upload = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") else: jobs = self._get_jobs(task_id) @@ -827,10 +794,6 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): test_name = self._testMethodName dump_format_name = "CVAT for images 1.1" - data = { - "format": dump_format_name, - "action": "download", - } test_cases = ['all', 'first'] images = self._generate_task_images(10) @@ -972,7 +935,7 @@ def test_api_v1_dump_empty_frames(self): for upload_format in upload_formats: upload_format_name = upload_format.DISPLAY_NAME if upload_format_name == "CVAT 1.1": - file_zip_name = osp.join(test_dir, f'empty_CVAT for images 1.1.zip') + file_zip_name = osp.join(test_dir, 'empty_CVAT for images 1.1.zip') else: file_zip_name = osp.join(test_dir, f'empty_{upload_format_name}.zip') if not osp.exists(file_zip_name) or not upload_format.ENABLED: @@ -1074,34 +1037,34 @@ def test_api_v1_rewriting_annotations(self): def test_api_v1_unit_test_on_normalize_shape_function(self): # 3 points - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [1.5, 2.5], }) # 4 points - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], }) # 1 point - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [1.5, 2.5], }) # empty shape with self.assertRaises(ValueError): - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [], }) # invalid count of points with self.assertRaises(ValueError): - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [1.5, 2.5, 7.5], }) # negative points - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [-1.5, 2.5, -9.8, -4.6], }) # integer - norm_shape = TrackManager.normalize_shape({ + TrackManager.normalize_shape({ "points": [1, 2, 9, 4], }) From e91b7a039793ccc52aad0f798cdbdcd076822ba9 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 3 Jun 2021 21:05:37 +0300 Subject: [PATCH 31/43] Remove useless lines. --- .../tests/test_rest_api_formats.py | 77 ++++++++----------- 1 file changed, 33 insertions(+), 44 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 7ed58b33827..2e8af537c3c 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -595,10 +595,9 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if upload_type == "task": @@ -650,10 +649,9 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if upload_type == "task": @@ -697,10 +695,9 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) with open(file_zip_name, 'rb') as binary_file: @@ -735,10 +732,9 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(osp.exists(file_zip_name), True) @@ -776,10 +772,9 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -825,10 +820,9 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -926,10 +920,9 @@ def test_api_v1_dump_empty_frames(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) for upload_format in upload_formats: @@ -1011,10 +1004,9 @@ def test_api_v1_rewriting_annotations(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) @@ -1094,10 +1086,9 @@ def test_api_v1_check_duplicated_polygon_points(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self.assertEqual(osp.exists(file_zip_name), True) # extract zip folder_name = osp.join(test_dir, f'{test_name}') @@ -1148,10 +1139,9 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self._check_downloaded_file(file_zip_name) # remove annotations @@ -1236,10 +1226,9 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): } response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) self.assertEqual(response.status_code, status.HTTP_200_OK) - if response.status_code == status.HTTP_200_OK: - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + content = BytesIO(b"".join(response.streaming_content)) + with open(file_zip_name, "wb") as f: + f.write(content.getvalue()) self._check_downloaded_file(file_zip_name) # remove annotations From 5e722b9f547f2f1353ee1498bd99371bac1a8431 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Fri, 4 Jun 2021 12:46:49 +0300 Subject: [PATCH 32/43] fix a typo. --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 2e8af537c3c..19d793aa462 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1113,7 +1113,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): # create task with annotations images = self._generate_task_images(13) task = self._create_task(tasks["many jobs"], images) - self._create_annotations(task, f'{dump_format_name} many jobs', "dafault") + self._create_annotations(task, f'{dump_format_name} many jobs', "default") task_id = task["id"] task_ann = TaskAnnotation(task_id) From a4c9d0d7df3ed6366b7198bafeff5d045b4b5234 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Fri, 4 Jun 2021 14:08:30 +0300 Subject: [PATCH 33/43] Remove duplicated polygon pounts test. --- .../tests/test_rest_api_formats.py | 43 ------------------- 1 file changed, 43 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 19d793aa462..efc31b8c894 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1060,49 +1060,6 @@ def test_api_v1_unit_test_on_normalize_shape_function(self): "points": [1, 2, 9, 4], }) - def test_api_v1_check_duplicated_polygon_points(self): - # issue 2924 - test_name = self._testMethodName - images = self._generate_task_images(10) - task = self._create_task(tasks["main"], images) - task_id = task["id"] - annotation_name = "CVAT for video 1.1 polygon" - dump_format_name = "CVAT for video 1.1" - self._create_annotations(task, annotation_name, "default") - annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] - with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) - file_zip_name = osp.join(test_dir, f'{test_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - data = { - "format": dump_format_name, - "action": "download", - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) - self.assertEqual(osp.exists(file_zip_name), True) - # extract zip - folder_name = osp.join(test_dir, f'{test_name}') - with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: - zip_ref.extractall(folder_name) - - tree = ET.parse(osp.join(folder_name, 'annotations.xml')) - root = tree.getroot() - for polygon in root.findall("./track[@id='0']/polygon"): - polygon_points = polygon.attrib["points"].replace(",", ";") - polygon_points = polygon_points.split(";") - polygon_points = [float(p) for p in polygon_points] - self.assertEqual(polygon_points, annotation_points) - def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): test_name = self._testMethodName upload_format_name = "CVAT 1.1" From 9e11dc1fa73f721738a20ca5986bac6c45485765 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 8 Jun 2021 15:19:24 +0300 Subject: [PATCH 34/43] Remove useless import. --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index efc31b8c894..5b9b521c906 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -8,8 +8,6 @@ import json import os.path as osp import os -import xml.etree.ElementTree as ET -import zipfile from io import BytesIO import av import numpy as np From ed011c16fece708a04246c0b2e2b62ae630fde3a Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 8 Jun 2021 16:54:10 +0300 Subject: [PATCH 35/43] Fix merge issues. --- .../tests/assets/annotations.json | 73 +++++++ .../dataset_manager/tests/assets/tasks.json | 44 ++++ .../tests/test_rest_api_formats.py | 188 ++++++++++++------ 3 files changed, 245 insertions(+), 60 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 38c8655f7f3..3aed3290e28 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -1088,5 +1088,78 @@ "attributes": [] } ] + }, + "CVAT for video 1.1 polygon": { + "version": 0, + "tags": [], + "shapes": [], + "tracks": [ + { + "frame": 0, + "label_id": null, + "group": 1, + "source": "manual", + "shapes": [ + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 0, + "outside": false, + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 1, + "outside": true, + "attributes": [] + }, + { + "type": "polygon", + "occluded": false, + "z_order": 0, + "points": [24.62, 13.01, 34.88, 20.03, 18.14, 18.08], + "frame": 2, + "outside": false, + "keyframe": true, + "attributes": [] + } + ], + "attributes": [] + } + ] + }, + "WiderFace 1.0": { + "version": 0, + "tags": [], + "shapes": [ + { + "type": "rectangle", + "occluded": false, + "z_order": 0, + "points": [7.55, 9.75, 16.44, 15.85], + "frame": 0, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + }, + { + "type": "rectangle", + "occluded": true, + "z_order": 0, + "points": [3.55, 27.75, 11.33, 33.71], + "frame": 1, + "label_id": null, + "group": 0, + "source": "manual", + "attributes": [] + } + ], + "tracks": [] } } diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 6b2ea747bfd..ec79e2e1f05 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -237,5 +237,49 @@ "attributes": [] } ] + }, + "widerface with all attributes": { + "name": "widerface task", + "overlap": 0, + "segment_size": 100, + "owner_id": 1, + "assignee_id": 2, + "labels": [ + { + "name": "face", + "attributes": [ + { + "name": "blur", + "mutable": false, + "input_type": "select", + "values": ["0", "1", "2"] + }, + { + "name": "expression", + "mutable": false, + "input_type": "select", + "values": ["0", "1"] + }, + { + "name": "illumination", + "mutable": false, + "input_type": "select", + "values": ["0", "1"] + }, + { + "name": "pose", + "mutable": false, + "input_type": "select", + "values": ["0", "1"] + }, + { + "name": "invalid", + "mutable": false, + "input_type": "select", + "values": ["0", "1"] + } + ] + } + ] } } diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 5b9b521c906..0cd3dc5f76d 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -12,6 +12,8 @@ import av import numpy as np import random +import xml.etree.ElementTree as ET +import zipfile from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir @@ -174,6 +176,11 @@ def _get_request_with_data(self, path, data, user): response = self.client.get(path, data) return response + def _put_request_with_data(self, path, data, user): + with ForceLogin(user, self.client): + response = self.client.put(path, data) + return response + def _delete_request(self, path, user): with ForceLogin(user, self.client): response = self.client.delete(path) @@ -260,17 +267,28 @@ def _dump_api_v1_tasks_id_annotations(self, url, data, user): response = self.client.get(url, data) return response + def _download_file(self, url, data, user, file_name): + response = self._get_request_with_data(url, data, user) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._get_request_with_data(url, data, user) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + content = BytesIO(b"".join(response.streaming_content)) + with open(file_name, "wb") as f: + f.write(content.getvalue()) + def _upload_file(self, url, data, user): - with ForceLogin(user, self.client): - response = self.client.put(url, data) - return response + response = self._put_request_with_data(url, {"annotation_file": data}, user) + self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) + response = self._put_request_with_data(url, {}, user) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) def _check_downloaded_file(self, file_name): if not osp.exists(file_name): raise FileNotFoundError(f"File '{file_name}' was not downloaded") - def _generate_url_dump_tasks_annotations(self, task_id, dump_format_name): - return f"/api/v1/tasks/{task_id}/annotations?format={dump_format_name}" + def _generate_url_dump_tasks_annotations(self, task_id): + return f"/api/v1/tasks/{task_id}/annotations" def _generate_url_upload_tasks_annotations(self, task_id, upload_format_name): return f"/api/v1/tasks/{task_id}/annotations?format={upload_format_name}" @@ -340,7 +358,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): else: self._create_annotations(task, dump_format_name, "random") # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) for user, edata in list(expected.items()): user_name = edata['name'] @@ -400,9 +418,9 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, user) + response = self._put_request_with_data(url, {"annotation_file": binary_file}, user) self.assertEqual(response.status_code, edata['accept code']) - response = self._upload_file(url, {}, user) + response = self._put_request_with_data(url, {}, user) self.assertEqual(response.status_code, edata['create code']) def test_api_v1_dump_annotations_with_objects_type_is_track(self): @@ -448,7 +466,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): else: self._create_annotations(task, dump_format_name, "random") # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) for user, edata in list(expected.items()): user_name = edata['name'] @@ -501,9 +519,9 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, user) + response = self._put_request_with_data(url, {"annotation_file": binary_file}, user) self.assertEqual(response.status_code, edata['accept code']) - response = self._upload_file(url, {}, user) + response = self._put_request_with_data(url, {}, user) self.assertEqual(response.status_code, edata['create code']) def test_api_v1_dump_tag_annotations(self): @@ -537,7 +555,7 @@ def test_api_v1_dump_tag_annotations(self): with self.subTest(format=f"{edata['name']}"): with TestDir() as test_dir: user_name = edata['name'] - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{user_name}.zip') data = { @@ -577,7 +595,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') data = { @@ -605,10 +623,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url_upload, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url_upload, binary_file, self.admin) response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) self.assertEqual(len(response.data["shapes"]), 2) @@ -632,7 +647,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel jobs = self._get_jobs(task_id) job_id = jobs[0]["id"] self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') data = { "format": dump_format_name, @@ -659,10 +674,7 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel url_upload = self._generate_url_upload_job_annotations(jobs[0]["id"], "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url_upload, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url_upload, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url_upload, binary_file, self.admin) self.assertEqual(osp.exists(file_zip_name), True) response = self._get_request(f"/api/v1/tasks/{task_id}/annotations", self.admin) @@ -678,7 +690,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( task_id = task["id"] with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') data = { "format": dump_format_name, @@ -700,10 +712,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( with open(file_zip_name, 'rb') as binary_file: url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property(self): test_name = self._testMethodName @@ -715,7 +724,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property task_id = task["id"] with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') data = { "format": dump_format_name, @@ -738,10 +747,7 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property with open(file_zip_name, 'rb') as binary_file: url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) def test_api_v1_dump_upload_annotations_from_several_jobs(self): test_name = self._testMethodName @@ -755,7 +761,7 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): self._create_annotations_in_job(task, job["id"], "CVAT for images 1.1 merge", "random") with TestDir() as test_dir: - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') data = { "format": dump_format_name, @@ -779,10 +785,7 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): self._remove_annotations(url, self.admin) url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(self): test_name = self._testMethodName @@ -802,7 +805,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se else: self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default") - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') data = { @@ -827,10 +830,7 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se self._remove_annotations(url, self.admin) url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1") with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) def test_api_v1_export_dataset(self): test_name = self._testMethodName @@ -902,7 +902,7 @@ def test_api_v1_dump_empty_frames(self): task = self._create_task(tasks["no attributes"], images) task_id = task["id"] self._create_annotations(task, "empty annotation", "default") - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') data = { @@ -943,9 +943,9 @@ def test_api_v1_dump_empty_frames(self): url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) + response = self._put_request_with_data(url, {"annotation_file": binary_file}, self.admin) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) + response = self._put_request_with_data(url, {}, self.admin) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertIsNone(response.data) @@ -986,7 +986,7 @@ def test_api_v1_rewriting_annotations(self): task_ann = TaskAnnotation(task_id) task_ann.init_from_db() task_ann_prev_data = task_ann.data - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') data = { @@ -1016,10 +1016,7 @@ def test_api_v1_rewriting_annotations(self): url = self._generate_url_upload_tasks_annotations(task_id, dump_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) task_ann = TaskAnnotation(task_id) task_ann.init_from_db() task_ann_data = task_ann.data @@ -1078,7 +1075,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): data_from_task_before_upload = Dataset.from_extractors(extractor) # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') data = { @@ -1105,10 +1102,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): # upload annotations url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) # equals annotations task_ann = TaskAnnotation(task_id) @@ -1165,7 +1159,7 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): data_from_task_before_upload = self._get_data_from_task(task_id, include_images) # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id, dump_format_name) + url = self._generate_url_dump_tasks_annotations(task_id) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') data = { @@ -1196,10 +1190,84 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): upload_format_name = dump_format_name url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) with open(file_zip_name, 'rb') as binary_file: - response = self._upload_file(url, {"annotation_file": binary_file}, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._upload_file(url, {}, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self._upload_file(url, binary_file, self.admin) + # equals annotations data_from_task_after_upload = self._get_data_from_task(task_id, include_images) compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + + def test_api_v1_check_duplicated_polygon_points(self): + test_name = self._testMethodName + images = self._generate_task_images(10) + task = self._create_task(tasks["main"], images) + task_id = task["id"] + data = { + "format": "CVAT for video 1.1", + "action": "download", + } + annotation_name = "CVAT for video 1.1 polygon" + self._create_annotations(task, annotation_name, "default") + annotation_points = annotations[annotation_name]["tracks"][0]["shapes"][0]['points'] + + with TestDir() as test_dir: + url = self._generate_url_dump_tasks_annotations(task_id) + file_zip_name = osp.join(test_dir, f'{test_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + folder_name = osp.join(test_dir, f'{test_name}') + with zipfile.ZipFile(file_zip_name, 'r') as zip_ref: + zip_ref.extractall(folder_name) + + tree = ET.parse(osp.join(folder_name, 'annotations.xml')) + root = tree.getroot() + for polygon in root.findall("./track[@id='0']/polygon"): + polygon_points = polygon.attrib["points"].replace(",", ";") + polygon_points = [float(p) for p in polygon_points.split(";")] + self.assertEqual(polygon_points, annotation_points) + + def test_api_v1_check_widerface_with_all_attributes(self): + test_name = self._testMethodName + dump_format_name = "WiderFace 1.0" + upload_format_name = "WiderFace 1.0" + + for include_images in (False, True): + with self.subTest(): + # create task with annotations + images = self._generate_task_images(3) + task = self._create_task(tasks["widerface with all attributes"], images) + self._create_annotations(task, f'{dump_format_name}', "random") + + task_id = task["id"] + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_before_upload = Dataset.from_extractors(extractor) + + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + data = { + "format": dump_format_name, + "action": "download", + } + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + self._upload_file(url, binary_file, self.admin) + + # equals annotations + task_ann = TaskAnnotation(task_id) + task_ann.init_from_db() + task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) + extractor = CvatTaskDataExtractor(task_data, include_images=include_images) + data_from_task_after_upload = Dataset.from_extractors(extractor) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) From 273c727d8542ea57a8062207f6e1d8cd6dab230e Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 8 Jun 2021 17:30:18 +0300 Subject: [PATCH 36/43] Use download_file function. --- .../tests/test_rest_api_formats.py | 169 +++--------------- 1 file changed, 25 insertions(+), 144 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 0cd3dc5f76d..d24e088be70 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -262,11 +262,6 @@ def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): response = self._put_api_v1_job_id_annotations(job_id, tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) - def _dump_api_v1_tasks_id_annotations(self, url, data, user): - with ForceLogin(user, self.client): - response = self.client.get(url, data) - return response - def _download_file(self, url, data, user, file_name): response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) @@ -366,20 +361,15 @@ def test_api_v1_dump_and_upload_annotations_with_objects_type_is_shape(self): data = { "format": dump_format_name, } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['accept code']) - response = self._dump_api_v1_tasks_id_annotations(url, data, user) - self.assertEqual(response.status_code, edata['create code']) - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['create code']) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['code']) if response.status_code == status.HTTP_200_OK: content = BytesIO(b"".join(response.streaming_content)) @@ -474,15 +464,15 @@ def test_api_v1_dump_annotations_with_objects_type_is_track(self): data = { "format": dump_format_name, } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['accept code']) - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['create code']) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['code']) if response.status_code == status.HTTP_200_OK: content = BytesIO(b"".join(response.streaming_content)) @@ -561,15 +551,15 @@ def test_api_v1_dump_tag_annotations(self): data = { "format": dump_format_name, } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['accept code']) - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['create code']) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata['code']) if response.status_code == status.HTTP_200_OK: content = BytesIO(b"".join(response.streaming_content)) @@ -597,23 +587,11 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_images(se self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') - - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if upload_type == "task": @@ -649,22 +627,12 @@ def test_api_v1_dump_and_upload_annotations_with_objects_are_different_video(sel self._create_annotations_in_job(task, job_id, "CVAT for images 1.1 different types", "random") url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{upload_type}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) if upload_type == "task": @@ -692,22 +660,11 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_outside_property( with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) with open(file_zip_name, 'rb') as binary_file: @@ -726,23 +683,12 @@ def test_api_v1_dump_and_upload_with_objects_type_is_track_and_keyframe_property with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) - self.assertEqual(response.status_code, status.HTTP_200_OK) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) with open(file_zip_name, 'rb') as binary_file: @@ -763,22 +709,11 @@ def test_api_v1_dump_upload_annotations_from_several_jobs(self): with TestDir() as test_dir: url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -808,22 +743,11 @@ def test_api_v1_dump_annotations_with_objects_type_is_shape_from_several_jobs(se url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) # remove annotations @@ -871,15 +795,15 @@ def test_api_v1_export_dataset(self): data = { "format": dump_format_name, } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata["accept code"]) - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata["create code"]) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, user) + response = self._get_request_with_data(url, data, user) self.assertEqual(response.status_code, edata["code"]) if response.status_code == status.HTTP_200_OK: content = BytesIO(b"".join(response.streaming_content)) @@ -905,22 +829,11 @@ def test_api_v1_dump_empty_frames(self): url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'empty_{dump_format_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) for upload_format in upload_formats: @@ -989,22 +902,11 @@ def test_api_v1_rewriting_annotations(self): url = self._generate_url_dump_tasks_annotations(task_id) file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self.assertEqual(osp.exists(file_zip_name), True) self._remove_annotations(url, self.admin) @@ -1078,22 +980,12 @@ def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): url = self._generate_url_dump_tasks_annotations(task_id) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) + data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) # remove annotations @@ -1162,22 +1054,11 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): url = self._generate_url_dump_tasks_annotations(task_id) with TestDir() as test_dir: file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - data = { - "format": dump_format_name, - } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED) - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) data = { "format": dump_format_name, "action": "download", } - response = self._dump_api_v1_tasks_id_annotations(url, data, self.admin) - self.assertEqual(response.status_code, status.HTTP_200_OK) - content = BytesIO(b"".join(response.streaming_content)) - with open(file_zip_name, "wb") as f: - f.write(content.getvalue()) + self._download_file(url, data, self.admin, file_zip_name) self._check_downloaded_file(file_zip_name) # remove annotations From 2380e54359eee1c5712f39ee01fe4ac9c94237ea Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 8 Jun 2021 18:18:15 +0300 Subject: [PATCH 37/43] Don't skip Widerface format --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index d24e088be70..5c355e6f2fb 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -1015,7 +1015,6 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): if dump_format_name in [ "MOT 1.1", # issue #2925 "Datumaro 1.0", # not uploaded - "WiderFace 1.0", # issue #2944 "CamVid 1.0", # issue #2840 and changed points values "MOTS PNG 1.0", # issue #2925 and changed points values "Segmentation mask 1.1", # changed points values From 72e2a4f1d8c7480caf8836e330f0f06da38448ef Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 10 Jun 2021 14:23:38 +0300 Subject: [PATCH 38/43] Refactoring. --- .../dataset_manager/tests/test_annotation.py | 35 +++- .../tests/test_rest_api_formats.py | 164 +++++++++--------- 2 files changed, 113 insertions(+), 86 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_annotation.py b/cvat/apps/dataset_manager/tests/test_annotation.py index 4f4dc84c123..34501fcf98e 100644 --- a/cvat/apps/dataset_manager/tests/test_annotation.py +++ b/cvat/apps/dataset_manager/tests/test_annotation.py @@ -165,4 +165,37 @@ def test_line_interpolation(self): ] } - self._check_interpolation(track) \ No newline at end of file + self._check_interpolation(track) + + def test_api_v1_unit_test_on_normalize_shape_function(self): + # 3 points + TrackManager.normalize_shape({ + "points": [1.5, 2.5], + }) + + # 4 points + TrackManager.normalize_shape({ + "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], + }) + # 1 point + TrackManager.normalize_shape({ + "points": [1.5, 2.5], + }) + # empty shape + with self.assertRaises(ValueError): + TrackManager.normalize_shape({ + "points": [], + }) + # invalid count of points + with self.assertRaises(ValueError): + TrackManager.normalize_shape({ + "points": [1.5, 2.5, 7.5], + }) + # negative points + TrackManager.normalize_shape({ + "points": [-1.5, 2.5, -9.8, -4.6], + }) + # integer + TrackManager.normalize_shape({ + "points": [1, 2, 9, 4], + }) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index fe53d56bf81..7eb67422bab 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -12,6 +12,7 @@ import xml.etree.ElementTree as ET import zipfile from io import BytesIO +import itertools from datumaro.components.dataset import Dataset from datumaro.util.test_utils import compare_datasets, TestDir @@ -957,55 +958,49 @@ def test_api_v1_unit_test_on_normalize_shape_function(self): def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): test_name = self._testMethodName upload_format_name = "CVAT 1.1" + include_images_params = (False, True) + dump_format_names = ("CVAT for images 1.1", "CVAT for video 1.1") - for include_images in (False, True): - for dump_format_name in ("CVAT for images 1.1", "CVAT for video 1.1"): - with self.subTest(): - # create task with annotations - images = self._generate_task_images(13) - task = self._create_task(tasks["many jobs"], images) - self._create_annotations(task, f'{dump_format_name} many jobs', "default") + for dump_format_name, include_images in itertools.product(dump_format_names, include_images_params): + with self.subTest(f"{dump_format_name}_include_images_{include_images}"): + # create task with annotations + images = self._generate_task_images(13) + task = self._create_task(tasks["many jobs"], images) + self._create_annotations(task, f'{dump_format_name} many jobs', "default") - task_id = task["id"] - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_before_upload = Dataset.from_extractors(extractor) + task_id = task["id"] + data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - data = { - "format": dump_format_name, - "action": "download", - } - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) + data = { + "format": dump_format_name, + "action": "download", + } + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) - # remove annotations - self._remove_annotations(url, self.admin) + # remove annotations + self._remove_annotations(url, self.admin) - # upload annotations - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - self._upload_file(url, binary_file, self.admin) + # upload annotations + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + self._upload_file(url, binary_file, self.admin) - # equals annotations - task_ann = TaskAnnotation(task_id) - task_ann.init_from_db() - task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task_id)) - extractor = CvatTaskDataExtractor(task_data, include_images=include_images) - data_from_task_after_upload = Dataset.from_extractors(extractor) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + # equals annotations + data_from_task_after_upload = self._get_data_from_task(task_id, include_images) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): test_name = self._testMethodName # get formats dump_formats = dm.views.get_export_formats() - for dump_format in dump_formats: + include_images_params = (False, True) + for dump_format, include_images in itertools.product(dump_formats, include_images_params): if dump_format.ENABLED: dump_format_name = dump_format.DISPLAY_NAME with self.subTest(): @@ -1019,59 +1014,58 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): ]: self.skipTest("Format is fail") - for include_images in (False, True): - # create task - images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) - else: - task = self._create_task(tasks["main"], images) + # create task + images = self._generate_task_images(3) + if dump_format_name == "Market-1501 1.0": + task = self._create_task(tasks["market1501"], images) + elif dump_format_name in ["ICDAR Localization 1.0", + "ICDAR Recognition 1.0"]: + task = self._create_task(tasks["icdar_localization_and_recognition"], images) + elif dump_format_name == "ICDAR Segmentation 1.0": + task = self._create_task(tasks["icdar_segmentation"], images) + else: + task = self._create_task(tasks["main"], images) - # create annotations - if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ - ]: - self._create_annotations(task, dump_format_name, "default") - else: - self._create_annotations(task, dump_format_name, "random") + # create annotations + if dump_format_name in [ + "MOT 1.1", "MOTS PNG 1.0", \ + "PASCAL VOC 1.1", "Segmentation mask 1.1", \ + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", \ + ]: + self._create_annotations(task, dump_format_name, "default") + else: + self._create_annotations(task, dump_format_name, "random") - task_id = task["id"] - data_from_task_before_upload = self._get_data_from_task(task_id, include_images) + task_id = task["id"] + data_from_task_before_upload = self._get_data_from_task(task_id, include_images) - # dump annotations - url = self._generate_url_dump_tasks_annotations(task_id) - with TestDir() as test_dir: - file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') - data = { - "format": dump_format_name, - "action": "download", - } - self._download_file(url, data, self.admin, file_zip_name) - self._check_downloaded_file(file_zip_name) - - # remove annotations - self._remove_annotations(url, self.admin) - - # upload annotations - if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: - upload_format_name = "CVAT 1.1" - else: - upload_format_name = dump_format_name - url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) - with open(file_zip_name, 'rb') as binary_file: - self._upload_file(url, binary_file, self.admin) + # dump annotations + url = self._generate_url_dump_tasks_annotations(task_id) + with TestDir() as test_dir: + file_zip_name = osp.join(test_dir, f'{test_name}_{dump_format_name}.zip') + data = { + "format": dump_format_name, + "action": "download", + } + self._download_file(url, data, self.admin, file_zip_name) + self._check_downloaded_file(file_zip_name) + + # remove annotations + self._remove_annotations(url, self.admin) + + # upload annotations + if dump_format_name in ["CVAT for images 1.1", "CVAT for video 1.1"]: + upload_format_name = "CVAT 1.1" + else: + upload_format_name = dump_format_name + url = self._generate_url_upload_tasks_annotations(task_id, upload_format_name) + with open(file_zip_name, 'rb') as binary_file: + self._upload_file(url, binary_file, self.admin) # equals annotations - data_from_task_after_upload = self._get_data_from_task(task_id, include_images) - compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) + data_from_task_after_upload = self._get_data_from_task(task_id, include_images) + compare_datasets(self, data_from_task_before_upload, data_from_task_after_upload) def test_api_v1_check_duplicated_polygon_points(self): test_name = self._testMethodName From 0592294640dc79cd0af39641612478b72bef7f77 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Thu, 17 Jun 2021 15:45:48 +0300 Subject: [PATCH 39/43] Add asserts test_api_v1_unit_test_on_normalize_shape_function --- .../dataset_manager/tests/test_annotation.py | 13 +++++--- .../tests/test_rest_api_formats.py | 33 ------------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_annotation.py b/cvat/apps/dataset_manager/tests/test_annotation.py index 34501fcf98e..93d9c594342 100644 --- a/cvat/apps/dataset_manager/tests/test_annotation.py +++ b/cvat/apps/dataset_manager/tests/test_annotation.py @@ -169,18 +169,23 @@ def test_line_interpolation(self): def test_api_v1_unit_test_on_normalize_shape_function(self): # 3 points - TrackManager.normalize_shape({ - "points": [1.5, 2.5], + norm_shape = TrackManager.normalize_shape({ + "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6], }) + self.assertEqual(len(norm_shape["points"]), 200) # 4 points - TrackManager.normalize_shape({ + norm_shape = TrackManager.normalize_shape({ "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], }) + self.assertEqual(len(norm_shape["points"]), 200) + # 1 point - TrackManager.normalize_shape({ + norm_shape = TrackManager.normalize_shape({ "points": [1.5, 2.5], }) + self.assertEqual(len(norm_shape["points"]), 200) + # empty shape with self.assertRaises(ValueError): TrackManager.normalize_shape({ diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 7eb67422bab..0a80ab67277 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -922,39 +922,6 @@ def test_api_v1_rewriting_annotations(self): task_ann_data = task_ann.data self.assertEqual(len(task_ann_data["shapes"]), len(task_ann_prev_data["shapes"])) - def test_api_v1_unit_test_on_normalize_shape_function(self): - # 3 points - TrackManager.normalize_shape({ - "points": [1.5, 2.5], - }) - - # 4 points - TrackManager.normalize_shape({ - "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], - }) - # 1 point - TrackManager.normalize_shape({ - "points": [1.5, 2.5], - }) - # empty shape - with self.assertRaises(ValueError): - TrackManager.normalize_shape({ - "points": [], - }) - # invalid count of points - with self.assertRaises(ValueError): - TrackManager.normalize_shape({ - "points": [1.5, 2.5, 7.5], - }) - # negative points - TrackManager.normalize_shape({ - "points": [-1.5, 2.5, -9.8, -4.6], - }) - # integer - TrackManager.normalize_shape({ - "points": [1, 2, 9, 4], - }) - def test_api_v1_tasks_annotations_dump_and_upload_many_jobs_with_datumaro(self): test_name = self._testMethodName upload_format_name = "CVAT 1.1" From 1ae6e9e91391677a6fa55e4528ee01c76e22e538 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Fri, 18 Jun 2021 13:09:00 +0300 Subject: [PATCH 40/43] Remove useless import. --- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 0a80ab67277..f3b03169bca 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -24,7 +24,6 @@ import cvat.apps.dataset_manager as dm from cvat.apps.dataset_manager.bindings import CvatTaskDataExtractor, TaskData from cvat.apps.dataset_manager.task import TaskAnnotation -from cvat.apps.dataset_manager.annotation import TrackManager from cvat.apps.engine.models import Task tasks_path = osp.join(osp.dirname(__file__), 'assets', 'tasks.json') From 3215d49e24b29a5b0caed04178e12a635ee34899 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Mon, 21 Jun 2021 16:53:39 +0300 Subject: [PATCH 41/43] Changed values for label attributes. --- cvat/apps/dataset_manager/tests/assets/tasks.json | 4 ++-- cvat/apps/dataset_manager/tests/test_rest_api_formats.py | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 40a53c526ca..09e2d866287 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -132,13 +132,13 @@ "name": "camera_id", "mutable": false, "input_type": "number", - "values": ["1", "2", "3", "4", "5", "6"] + "values": ["1", "5", "2"] }, { "name": "person_id", "mutable": false, "input_type": "number", - "values": ["1", "2", "3"] + "values": ["1", "6", "1"] } ] } diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index f3b03169bca..880585b25f2 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -225,7 +225,6 @@ def _create_annotations(self, task, name_ann, key_get_values): "spec_id": spec_id, "value": value, }) - response = self._put_api_v1_task_id_annotations(task["id"], tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -263,7 +262,6 @@ def _create_annotations_in_job(self, task, job_id, name_ann, key_get_values): "spec_id": spec_id, "value": value, }) - response = self._put_api_v1_job_id_annotations(job_id, tmp_annotations) self.assertEqual(response.status_code, status.HTTP_200_OK) @@ -969,12 +967,12 @@ def test_api_v1_tasks_annotations_dump_and_upload_with_datumaro(self): for dump_format, include_images in itertools.product(dump_formats, include_images_params): if dump_format.ENABLED: dump_format_name = dump_format.DISPLAY_NAME - with self.subTest(): + with self.subTest(dump_format_name): if dump_format_name in [ - "MOT 1.1", # issue #2925 + "MOT 1.1", "Datumaro 1.0", # not uploaded "CamVid 1.0", # issue #2840 and changed points values - "MOTS PNG 1.0", # issue #2925 and changed points values + "MOTS PNG 1.0", # changed points values "Segmentation mask 1.1", # changed points values "ICDAR Segmentation 1.0", # changed points values ]: From 7c95cd4b17fb03eb9674725a02d9851e0fde11b1 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 22 Jun 2021 14:43:30 +0300 Subject: [PATCH 42/43] Removed test for dead code. --- .../dataset_manager/tests/test_annotation.py | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/cvat/apps/dataset_manager/tests/test_annotation.py b/cvat/apps/dataset_manager/tests/test_annotation.py index 93d9c594342..f7263dc3cc4 100644 --- a/cvat/apps/dataset_manager/tests/test_annotation.py +++ b/cvat/apps/dataset_manager/tests/test_annotation.py @@ -167,40 +167,3 @@ def test_line_interpolation(self): self._check_interpolation(track) - def test_api_v1_unit_test_on_normalize_shape_function(self): - # 3 points - norm_shape = TrackManager.normalize_shape({ - "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6], - }) - self.assertEqual(len(norm_shape["points"]), 200) - - # 4 points - norm_shape = TrackManager.normalize_shape({ - "points": [1.5, 2.5, 0.5, 8.6, 9.6, 3.6, 2.8, 7.2], - }) - self.assertEqual(len(norm_shape["points"]), 200) - - # 1 point - norm_shape = TrackManager.normalize_shape({ - "points": [1.5, 2.5], - }) - self.assertEqual(len(norm_shape["points"]), 200) - - # empty shape - with self.assertRaises(ValueError): - TrackManager.normalize_shape({ - "points": [], - }) - # invalid count of points - with self.assertRaises(ValueError): - TrackManager.normalize_shape({ - "points": [1.5, 2.5, 7.5], - }) - # negative points - TrackManager.normalize_shape({ - "points": [-1.5, 2.5, -9.8, -4.6], - }) - # integer - TrackManager.normalize_shape({ - "points": [1, 2, 9, 4], - }) From bcf2d63f94c1adea6503bc47ec1d089c25003e31 Mon Sep 17 00:00:00 2001 From: Smirnova Maria Date: Tue, 22 Jun 2021 15:01:57 +0300 Subject: [PATCH 43/43] Removed dead code. --- cvat/apps/dataset_manager/annotation.py | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/cvat/apps/dataset_manager/annotation.py b/cvat/apps/dataset_manager/annotation.py index 95c127c6085..e34d47cd981 100644 --- a/cvat/apps/dataset_manager/annotation.py +++ b/cvat/apps/dataset_manager/annotation.py @@ -436,24 +436,6 @@ def _modify_unmached_object(obj, end_frame): obj["interpolated_shapes"].append(last_interpolated_shape) obj["interpolated_shapes"].append(shape) - @staticmethod - def normalize_shape(shape): - points = list(shape["points"]) - if len(points) == 2: - points.extend(points) # duplicate points for single point case - points = np.asarray(points).reshape(-1, 2) - broken_line = geometry.LineString(points) - points = [] - for off in range(0, 100, 1): - p = broken_line.interpolate(off / 100, True) - points.append(p.x) - points.append(p.y) - - shape = copy(shape) - shape["points"] = points - - return shape - @staticmethod def get_interpolated_shapes(track, start_frame, end_frame): def copy_shape(source, frame, points=None):