Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(watcher): scanning a managed workspace only logs a warning msg #1668

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions antarest/core/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,3 @@ def __init__(self, *district_ids: str):
class BadEditInstructionException(HTTPException):
def __init__(self, message: str) -> None:
super().__init__(HTTPStatus.UNPROCESSABLE_ENTITY, message)


class CannotScanInternalWorkspace(HTTPException):
def __init__(self) -> None:
super().__init__(
HTTPStatus.BAD_REQUEST,
"You cannot scan the default internal workspace",
)
23 changes: 17 additions & 6 deletions antarest/study/storage/rawstudy/watcher.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging
import re
import tempfile
import threading
from html import escape
from http import HTTPStatus
from http.client import HTTPException
Expand All @@ -12,7 +11,6 @@
from filelock import FileLock

from antarest.core.config import Config
from antarest.core.exceptions import CannotScanInternalWorkspace
from antarest.core.interfaces.service import IService
from antarest.core.requests import RequestParameters
from antarest.core.tasks.model import TaskResult, TaskType
Expand All @@ -31,6 +29,11 @@ def __init__(self, message: str) -> None:
super().__init__(HTTPStatus.BAD_REQUEST, message)


class CannotScanInternalWorkspace(Exception):
def __init__(self, message: str) -> None:
super().__init__(message)


class Watcher(IService):
"""
Files Watcher to listen raw studies changes and trigger a database update.
Expand Down Expand Up @@ -128,7 +131,7 @@ def _rec_scan(
return [StudyFolder(path, workspace, groups)]

else:
folders: List[StudyFolder] = list()
folders: List[StudyFolder] = []
if path.is_dir():
for child in path.iterdir():
try:
Expand Down Expand Up @@ -179,7 +182,13 @@ def oneshot_scan(
"""

def scan_task(notifier: TaskUpdateNotifier) -> TaskResult:
self.scan(workspace, path)
try:
self.scan(workspace, path)
except CannotScanInternalWorkspace as e:
logger.warning(e)
MartinBelthle marked this conversation as resolved.
Show resolved Hide resolved
return TaskResult(
success=False, message=f"Scan failed: {str(e)}"
)
return TaskResult(success=True, message="Scan completed")

return self.task_service.add_task(
Expand All @@ -202,11 +211,13 @@ def scan(

"""
stopwatch = StopWatch()
studies: List[StudyFolder] = list()
studies: List[StudyFolder] = []
directory_path: Optional[Path] = None
if workspace_directory_path is not None and workspace_name:
if workspace_name == DEFAULT_WORKSPACE_NAME:
raise CannotScanInternalWorkspace
raise CannotScanInternalWorkspace(
"You cannot scan the default internal workspace"
)
try:
workspace = self.config.storage.workspaces[workspace_name]
except KeyError:
Expand Down
20 changes: 0 additions & 20 deletions tests/integration/test_integration_watcher.py

This file was deleted.

95 changes: 95 additions & 0 deletions tests/integration/test_watcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from fastapi import FastAPI
from starlette.testclient import TestClient

from antarest.core.tasks.model import TaskResult


def test_scan_dir__nominal_case(app: FastAPI, admin_access_token: str) -> None:
client = TestClient(app)
headers = {"Authorization": f"Bearer {admin_access_token}"}

task_id = client.post(
"/v1/watcher/_scan?path=ext",
headers=headers,
)

# asserts that the POST request succeeded
assert task_id.status_code == 200

# asserts that the task succeeded
res = client.get(
f"v1/tasks/{task_id.json()}?wait_for_completion=true", headers=headers
)
task_result = TaskResult.parse_obj(res.json()["result"])
assert task_result.success
assert task_result.message == "Scan completed"
assert task_result.return_value is None


def test_scan_dir__default_workspace(
app: FastAPI, admin_access_token: str
) -> None:
client = TestClient(app)
headers = {"Authorization": f"Bearer {admin_access_token}"}

task_id = client.post(
"/v1/watcher/_scan?path=/default",
headers=headers,
)
# asserts that the POST request did not raise an Exception
assert task_id.status_code == 200

# asserts that the task failed
res = client.get(
f"v1/tasks/{task_id.json()}?wait_for_completion=true", headers=headers
)
task_result = TaskResult.parse_obj(res.json()["result"])
assert not task_result.success
assert (
task_result.message
== "Scan failed: You cannot scan the default internal workspace"
)
assert task_result.return_value is None


def test_scan_dir__unknown_folder(
app: FastAPI, admin_access_token: str
) -> None:
client = TestClient(app)
headers = {"Authorization": f"Bearer {admin_access_token}"}

fake_workspace_name = "fake_workspace"
task_id = client.post(
f"/v1/watcher/_scan?path={fake_workspace_name}",
headers=headers,
)

# asserts that the POST request did not raise an Exception
assert task_id.status_code == 200

# asserts that the task failed
res = client.get(
f"v1/tasks/{task_id.json()}?wait_for_completion=true", headers=headers
)
task_result = TaskResult.parse_obj(res.json()["result"])
assert not task_result.success
assert (
task_result.message
== f"Task {task_id.json()} failed: Unhandled exception "
f"(<HTTPStatus.BAD_REQUEST: 400>, 'Workspace {fake_workspace_name} not found')"
f"\nSee the logs for detailed information and the error traceback."
)
assert task_result.return_value is None


def test_scan_dir__no_path(app: FastAPI, admin_access_token: str) -> None:
client = TestClient(app)
headers = {"Authorization": f"Bearer {admin_access_token}"}

res = client.post("/v1/watcher/_scan", headers=headers)
assert res.status_code == 422
assert res.json() == {
"description": "field required",
"exception": "RequestValidationError",
"body": None,
}
6 changes: 4 additions & 2 deletions tests/storage/business/test_watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
from sqlalchemy import create_engine

from antarest.core.config import Config, StorageConfig, WorkspaceConfig
from antarest.core.exceptions import CannotScanInternalWorkspace
from antarest.core.persistence import Base
from antarest.core.utils.fastapi_sqlalchemy import DBSessionMiddleware
from antarest.login.model import Group
from antarest.study.model import StudyFolder, DEFAULT_WORKSPACE_NAME
from antarest.study.storage.rawstudy.watcher import Watcher
from antarest.study.storage.rawstudy.watcher import (
Watcher,
CannotScanInternalWorkspace,
)
from tests.storage.conftest import SimpleSyncTaskService


Expand Down