Skip to content

Commit

Permalink
Adding unit tests for files API (#403)
Browse files Browse the repository at this point in the history
  • Loading branch information
quaark committed Aug 11, 2020
1 parent 1d9c3a4 commit f3556e5
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 33 deletions.
32 changes: 32 additions & 0 deletions tests/api/api/test_files.py
@@ -0,0 +1,32 @@
from http import HTTPStatus

import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

# fixtures for test, aren't used directly so we need to ignore the lint here
from tests.common_fixtures import ( # noqa: F401
patch_file_forbidden,
patch_file_not_found,
)


@pytest.mark.usefixtures("patch_file_forbidden")
def test_files_forbidden(db: Session, client: TestClient) -> None:
validate_files_status_code(client, HTTPStatus.FORBIDDEN.value)


@pytest.mark.usefixtures("patch_file_not_found")
def test_files_not_found(db: Session, client: TestClient) -> None:
validate_files_status_code(client, HTTPStatus.NOT_FOUND.value)


def validate_files_status_code(client: TestClient, status_code: int):
resp = client.get('/api/files?schema=v3io&path=mybucket/files.txt')
assert resp.status_code == status_code

resp = client.get('/api/files?schema=v3io&path=mybucket/')
assert resp.status_code == status_code

resp = client.get('/api/filestat?schema=v3io&path=mybucket/files.txt')
assert resp.status_code == status_code
51 changes: 51 additions & 0 deletions tests/common_fixtures.py
@@ -0,0 +1,51 @@
from http import HTTPStatus
from unittest.mock import Mock

import pytest
import requests

import v3io.dataplane


@pytest.fixture
def patch_file_forbidden(monkeypatch):
class MockV3ioClient:
def __init__(self, *args, **kwargs):
pass

def get_container_contents(self, *args, **kwargs):
raise RuntimeError('Permission denied')

mock_get = mock_failed_get_func(HTTPStatus.FORBIDDEN.value)

monkeypatch.setattr(requests, "get", mock_get)
monkeypatch.setattr(requests, "head", mock_get)
monkeypatch.setattr(v3io.dataplane, "Client", MockV3ioClient)


@pytest.fixture
def patch_file_not_found(monkeypatch):
class MockV3ioClient:
def __init__(self, *args, **kwargs):
pass

def get_container_contents(self, *args, **kwargs):
raise FileNotFoundError

mock_get = mock_failed_get_func(HTTPStatus.NOT_FOUND.value)

monkeypatch.setattr(requests, "get", mock_get)
monkeypatch.setattr(requests, "head", mock_get)
monkeypatch.setattr(v3io.dataplane, "Client", MockV3ioClient)


def mock_failed_get_func(status_code: int):
def mock_get(*args, **kwargs):
mock_response = Mock()
mock_response.status_code = status_code
mock_response.raise_for_status = Mock(
side_effect=requests.HTTPError('Error', response=mock_response)
)
return mock_response

return mock_get
41 changes: 8 additions & 33 deletions tests/test_datastores.py
Expand Up @@ -11,20 +11,19 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from http import HTTPStatus
from os import listdir
from tempfile import TemporaryDirectory
from unittest.mock import Mock

import pandas as pd
import pytest
import requests
import v3io.dataplane

import mlrun
import mlrun.errors
from tests.conftest import rundb_path

# fixtures for test, aren't used directly so we need to ignore the lint here
from tests.common_fixtures import patch_file_forbidden # noqa: F401

mlrun.mlconf.dbpath = rundb_path

raw_data = {
Expand Down Expand Up @@ -103,44 +102,20 @@ def test_parse_url_preserve_case():
assert expected_endpoint, endpoint


def test_forbidden_file_access(monkeypatch):
class MockV3ioClient:
def __init__(self, *args, **kwargs):
pass

def get_container_contents(self, *args, **kwargs):
raise RuntimeError('Permission denied')

def mock_get(*args, **kwargs):
mock_forbidden_response = Mock()
mock_forbidden_response.status_code = HTTPStatus.FORBIDDEN.value
mock_forbidden_response.raise_for_status = Mock(
side_effect=requests.HTTPError('Error', response=mock_forbidden_response)
)
return mock_forbidden_response

monkeypatch.setattr(requests, "get", mock_get)
monkeypatch.setattr(requests, "head", mock_get)
monkeypatch.setattr(v3io.dataplane, "Client", MockV3ioClient)

@pytest.mark.usefixtures("patch_file_forbidden")
def test_forbidden_file_access():
store = mlrun.datastore.datastore.StoreManager(
secrets={'V3IO_ACCESS_KEY': 'some-access-key'}
)

with pytest.raises(mlrun.errors.AccessDeniedError) as access_denied_exc:
with pytest.raises(mlrun.errors.AccessDeniedError):
obj = store.object('v3io://some-system/some-dir/')
obj.listdir()

assert access_denied_exc.value.response.status_code == HTTPStatus.FORBIDDEN.value

with pytest.raises(mlrun.errors.AccessDeniedError) as access_denied_exc:
with pytest.raises(mlrun.errors.AccessDeniedError):
obj = store.object('v3io://some-system/some-dir/some-file')
obj.get()

assert access_denied_exc.value.response.status_code == HTTPStatus.FORBIDDEN.value

with pytest.raises(mlrun.errors.AccessDeniedError) as access_denied_exc:
with pytest.raises(mlrun.errors.AccessDeniedError):
obj = store.object('v3io://some-system/some-dir/some-file')
obj.stat()

assert access_denied_exc.value.response.status_code == HTTPStatus.FORBIDDEN.value

0 comments on commit f3556e5

Please sign in to comment.