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