Add REST API GET, POST, PATCH tests for cloud storage (#4353)
Co-authored-by: kirill.sizov <kirill.sizov@intel.com>main
parent
96af4f18c8
commit
2a05316496
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.12 on 2022-03-14 10:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('engine', '0051_auto_20220220_1824'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='cloudstorage',
|
||||||
|
name='specific_attributes',
|
||||||
|
field=models.CharField(blank=True, max_length=1024),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"count": 2,
|
||||||
|
"next": null,
|
||||||
|
"previous": null,
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"created_date": "2022-03-17T07:23:59.305000Z",
|
||||||
|
"credentials_type": "KEY_SECRET_KEY_PAIR",
|
||||||
|
"description": "",
|
||||||
|
"display_name": "Bucket 2",
|
||||||
|
"id": 2,
|
||||||
|
"manifests": [
|
||||||
|
"manifest.jsonl"
|
||||||
|
],
|
||||||
|
"organization": 2,
|
||||||
|
"owner": {
|
||||||
|
"first_name": "Business",
|
||||||
|
"id": 11,
|
||||||
|
"last_name": "Second",
|
||||||
|
"url": "http://localhost:8080/api/users/11",
|
||||||
|
"username": "business2"
|
||||||
|
},
|
||||||
|
"provider_type": "AWS_S3_BUCKET",
|
||||||
|
"resource": "private",
|
||||||
|
"specific_attributes": "endpoint_url=http%3A%2F%2Fminio%3A9000",
|
||||||
|
"updated_date": "2022-03-17T07:23:59.309000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"created_date": "2022-03-17T07:22:49.519000Z",
|
||||||
|
"credentials_type": "ANONYMOUS_ACCESS",
|
||||||
|
"description": "",
|
||||||
|
"display_name": "Bucket 1",
|
||||||
|
"id": 1,
|
||||||
|
"manifests": [
|
||||||
|
"manifest.jsonl"
|
||||||
|
],
|
||||||
|
"organization": null,
|
||||||
|
"owner": {
|
||||||
|
"first_name": "User",
|
||||||
|
"id": 2,
|
||||||
|
"last_name": "First",
|
||||||
|
"url": "http://localhost:8080/api/users/2",
|
||||||
|
"username": "user1"
|
||||||
|
},
|
||||||
|
"provider_type": "AWS_S3_BUCKET",
|
||||||
|
"resource": "public",
|
||||||
|
"specific_attributes": "endpoint_url=http%3A%2F%2Fminio%3A9000",
|
||||||
|
"updated_date": "2022-03-17T07:22:49.529000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
@ -0,0 +1,58 @@
|
|||||||
|
version: '3.3'
|
||||||
|
|
||||||
|
services:
|
||||||
|
minio:
|
||||||
|
image: quay.io/minio/minio
|
||||||
|
hostname: minio
|
||||||
|
restart: always
|
||||||
|
command: server /data --console-address ":9001"
|
||||||
|
expose:
|
||||||
|
- "9000"
|
||||||
|
- "9001"
|
||||||
|
ports:
|
||||||
|
- 9000:9000
|
||||||
|
- 9001:9001
|
||||||
|
environment:
|
||||||
|
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY}
|
||||||
|
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 20s
|
||||||
|
retries: 3
|
||||||
|
networks:
|
||||||
|
cvat:
|
||||||
|
aliases:
|
||||||
|
- minio
|
||||||
|
mc:
|
||||||
|
image: minio/mc
|
||||||
|
depends_on:
|
||||||
|
- minio
|
||||||
|
environment:
|
||||||
|
MC_PATH: "/usr/bin/mc"
|
||||||
|
MINIO_HOST: "http://minio:9000"
|
||||||
|
MINIO_ACCESS_KEY:
|
||||||
|
MINIO_SECRET_KEY:
|
||||||
|
MINIO_ALIAS: "local_minio"
|
||||||
|
PRIVATE_BUCKET: "private"
|
||||||
|
PUBLIC_BUCKET: "public"
|
||||||
|
TEST_BUCKET: "test"
|
||||||
|
volumes:
|
||||||
|
- ./tests/cypress/integration/actions_tasks/assets/case_65_manifest/:/storage
|
||||||
|
networks:
|
||||||
|
- cvat
|
||||||
|
entrypoint: >
|
||||||
|
/bin/sh -c "
|
||||||
|
$${MC_PATH} config host add --quiet --api s3v4 $${MINIO_ALIAS} $${MINIO_HOST} $${MINIO_ACCESS_KEY} $${MINIO_SECRET_KEY};
|
||||||
|
$${MC_PATH} mb $${MINIO_ALIAS}/$${PRIVATE_BUCKET} $${MINIO_ALIAS}/$${PUBLIC_BUCKET} $${MINIO_ALIAS}/$${TEST_BUCKET};
|
||||||
|
for BUCKET in $${MINIO_ALIAS}/$${PRIVATE_BUCKET} $${MINIO_ALIAS}/$${PUBLIC_BUCKET} $${MINIO_ALIAS}/$${TEST_BUCKET};
|
||||||
|
do
|
||||||
|
$${MC_PATH} cp --recursive /storage/ $${BUCKET};
|
||||||
|
for i in 1 2;
|
||||||
|
do
|
||||||
|
$${MC_PATH} cp /storage/manifest.jsonl $${BUCKET}/manifest_$${i}.jsonl;
|
||||||
|
done;
|
||||||
|
done;
|
||||||
|
$${MC_PATH} policy set public $${MINIO_ALIAS}/$${PUBLIC_BUCKET};
|
||||||
|
exit 0;
|
||||||
|
"
|
||||||
@ -0,0 +1,188 @@
|
|||||||
|
# Copyright (C) 2022 Intel Corporation
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from http import HTTPStatus
|
||||||
|
from deepdiff import DeepDiff
|
||||||
|
|
||||||
|
from .utils.config import get_method, patch_method, post_method
|
||||||
|
|
||||||
|
class TestGetCloudStorage:
|
||||||
|
|
||||||
|
def _test_can_see(self, user, storage_id, data, **kwargs):
|
||||||
|
response = get_method(user, f'cloudstorages/{storage_id}', **kwargs)
|
||||||
|
response_data = response.json()
|
||||||
|
response_data = response_data.get('results', response_data)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.OK
|
||||||
|
assert DeepDiff(data, response_data, ignore_order=True) == {}
|
||||||
|
|
||||||
|
def _test_cannot_see(self, user, storage_id, **kwargs):
|
||||||
|
response = get_method(user, f'cloudstorages/{storage_id}', **kwargs)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.FORBIDDEN
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('storage_id', [1])
|
||||||
|
@pytest.mark.parametrize('group, is_owner, is_allow', [
|
||||||
|
('admin', False, True),
|
||||||
|
('business', False, False),
|
||||||
|
('user', True, True),
|
||||||
|
])
|
||||||
|
def test_sandbox_user_get_coud_storage(self, storage_id, group, is_owner, is_allow, users, cloud_storages):
|
||||||
|
org = ''
|
||||||
|
cloud_storage = cloud_storages[storage_id]
|
||||||
|
username = cloud_storage['owner']['username'] if is_owner else \
|
||||||
|
next((u for u in users if group in u['groups'] and u['id'] != cloud_storage['owner']['id']))['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_see(username, storage_id, cloud_storage, org=org)
|
||||||
|
else:
|
||||||
|
self._test_cannot_see(username, storage_id, org=org)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('org_id', [2])
|
||||||
|
@pytest.mark.parametrize('storage_id', [2])
|
||||||
|
@pytest.mark.parametrize('role, is_owner, is_allow', [
|
||||||
|
('worker', True, True),
|
||||||
|
('supervisor', False, True),
|
||||||
|
('worker', False, False),
|
||||||
|
])
|
||||||
|
def test_org_user_get_coud_storage(self, org_id, storage_id, role, is_owner, is_allow, find_users, cloud_storages):
|
||||||
|
cloud_storage = cloud_storages[storage_id]
|
||||||
|
username = cloud_storage['owner']['username'] if is_owner else \
|
||||||
|
next((u for u in find_users(role=role, org=org_id) if u['id'] != cloud_storage['owner']['id']))['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_see(username, storage_id, cloud_storage, org_id=org_id)
|
||||||
|
else:
|
||||||
|
self._test_cannot_see(username, storage_id, org_id=org_id)
|
||||||
|
|
||||||
|
|
||||||
|
class TestPostCloudStorage:
|
||||||
|
_SPEC = {
|
||||||
|
'provider_type': 'AWS_S3_BUCKET',
|
||||||
|
'resource': 'test',
|
||||||
|
'display_name': 'Bucket',
|
||||||
|
'credentials_type': 'KEY_SECRET_KEY_PAIR',
|
||||||
|
'key': 'minio_access_key', 'secret_key': 'minio_secret_key',
|
||||||
|
'specific_attributes': 'endpoint_url=http://minio:9000',
|
||||||
|
'description': 'Some description',
|
||||||
|
'manifests': [
|
||||||
|
'manifest.jsonl'
|
||||||
|
],
|
||||||
|
}
|
||||||
|
_EXCLUDE_PATHS = [
|
||||||
|
f"root['{extra_field}']" for extra_field in {
|
||||||
|
# unchanged fields
|
||||||
|
'created_date', 'id', 'organization', 'owner', 'updated_date',
|
||||||
|
# credentials that server doesn't return
|
||||||
|
'key', 'secret_key',
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _test_can_create(self, user, spec, **kwargs):
|
||||||
|
response = post_method(user, 'cloudstorages', spec, **kwargs)
|
||||||
|
response_data = response.json()
|
||||||
|
response_data = response_data.get('results', response_data)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.CREATED
|
||||||
|
assert DeepDiff(self._SPEC, response_data, ignore_order=True,
|
||||||
|
exclude_paths=self._EXCLUDE_PATHS) == {}
|
||||||
|
|
||||||
|
def _test_cannot_create(self, user, spec, **kwargs):
|
||||||
|
response = post_method(user, 'cloudstorages', spec, **kwargs)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.FORBIDDEN
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('group, is_allow', [
|
||||||
|
('user', True), ('worker', False)
|
||||||
|
])
|
||||||
|
def test_sandbox_user_create_cloud_storage(self, group, is_allow, users):
|
||||||
|
org = ''
|
||||||
|
username = [u for u in users if group in u['groups']][0]['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_create(username, self._SPEC, org=org)
|
||||||
|
else:
|
||||||
|
self._test_cannot_create(username, self._SPEC, org=org)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('org_id', [2])
|
||||||
|
@pytest.mark.parametrize('role, is_allow', [
|
||||||
|
('owner', True), ('maintainer', True),
|
||||||
|
('worker', False), ('supervisor', False),
|
||||||
|
])
|
||||||
|
def test_org_user_create_coud_storage(self, org_id, role, is_allow, find_users):
|
||||||
|
username = find_users(role=role, org=org_id)[0]['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_create(username, self._SPEC, org_id=org_id)
|
||||||
|
else:
|
||||||
|
self._test_cannot_create(username, self._SPEC, org_id=org_id)
|
||||||
|
|
||||||
|
class TestPatchCloudStorage:
|
||||||
|
_SPEC = {
|
||||||
|
'display_name': 'New display name',
|
||||||
|
'description': 'New description',
|
||||||
|
'manifests': [
|
||||||
|
'manifest_1.jsonl',
|
||||||
|
'manifest_2.jsonl',
|
||||||
|
],
|
||||||
|
}
|
||||||
|
_EXCLUDE_PATHS = [
|
||||||
|
f"root['{extra_field}']" for extra_field in {
|
||||||
|
# unchanged fields
|
||||||
|
'created_date', 'credentials_type', 'id', 'organization', 'owner',
|
||||||
|
'provider_type', 'resource', 'specific_attributes', 'updated_date',
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _test_can_update(self, user, storage_id, spec, **kwargs):
|
||||||
|
response = patch_method(user, f'cloudstorages/{storage_id}', spec, **kwargs)
|
||||||
|
response_data = response.json()
|
||||||
|
response_data = response_data.get('results', response_data)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.OK
|
||||||
|
assert DeepDiff(self._SPEC, response_data, ignore_order=True,
|
||||||
|
exclude_paths=self._EXCLUDE_PATHS) == {}
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.OK
|
||||||
|
|
||||||
|
def _test_cannot_update(self, user, storage_id, spec, **kwargs):
|
||||||
|
response = patch_method(user, f'cloudstorages/{storage_id}', spec, **kwargs)
|
||||||
|
|
||||||
|
assert response.status_code == HTTPStatus.FORBIDDEN
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('storage_id', [1])
|
||||||
|
@pytest.mark.parametrize('group, is_owner, is_allow', [
|
||||||
|
('admin', False, True),
|
||||||
|
('business', False, False),
|
||||||
|
('worker', True, True),
|
||||||
|
])
|
||||||
|
def test_sandbox_user_update_cloud_storage(self, storage_id, group, is_owner, is_allow, users, cloud_storages):
|
||||||
|
org = ''
|
||||||
|
cloud_storage = cloud_storages[storage_id]
|
||||||
|
username = cloud_storage['owner']['username'] if is_owner else \
|
||||||
|
next((u for u in users if group in u['groups'] and u['id'] != cloud_storage['owner']['id']))['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_update(username, storage_id, self._SPEC, org=org)
|
||||||
|
else:
|
||||||
|
self._test_cannot_update(username, storage_id, self._SPEC, org=org)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('org_id', [2])
|
||||||
|
@pytest.mark.parametrize('storage_id', [2])
|
||||||
|
@pytest.mark.parametrize('role, is_owner, is_allow', [
|
||||||
|
('worker', True, True),
|
||||||
|
('maintainer', False, True),
|
||||||
|
('supervisor', False, False),
|
||||||
|
])
|
||||||
|
def test_org_user_update_coud_storage(self, org_id, storage_id, role, is_owner, is_allow, find_users, cloud_storages):
|
||||||
|
cloud_storage = cloud_storages[storage_id]
|
||||||
|
username = cloud_storage['owner']['username'] if is_owner else \
|
||||||
|
next((u for u in find_users(role=role, org=org_id) if u['id'] != cloud_storage['owner']['id']))['username']
|
||||||
|
|
||||||
|
if is_allow:
|
||||||
|
self._test_can_update(username, storage_id, self._SPEC, org_id=org_id)
|
||||||
|
else:
|
||||||
|
self._test_cannot_update(username, storage_id, self._SPEC, org_id=org_id)
|
||||||
Loading…
Reference in New Issue