Skip to content
Merged
29 changes: 19 additions & 10 deletions packages/models-library/src/models_library/projects_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from enum import Enum, unique
from typing import Any, ClassVar

from pydantic import BaseModel, Extra, Field, validator
from pydantic import BaseModel, Extra, Field, root_validator, validator

from .projects_access import Owner

Expand Down Expand Up @@ -57,10 +57,10 @@ class ProjectStatus(str, Enum):

class ProjectLocked(BaseModel):
value: bool = Field(..., description="True if the project is locked")
status: ProjectStatus = Field(..., description="The status of the project")
owner: Owner | None = Field(
default=None, description="If locked, the user that owns the lock"
)
status: ProjectStatus = Field(..., description="The status of the project")

class Config:
extra = Extra.forbid
Expand All @@ -80,14 +80,6 @@ class Config:
]
}

@validator("owner", pre=True, always=True)
@classmethod
def check_not_null(cls, v, values):
if values["value"] is True and v is None:
msg = "value cannot be None when project is locked"
raise ValueError(msg)
return v

@validator("status", always=True)
@classmethod
def check_status_compatible(cls, v, values):
Expand All @@ -99,6 +91,23 @@ def check_status_compatible(cls, v, values):
raise ValueError(msg)
return v

@root_validator(pre=True)
@classmethod
def check_owner_compatible(cls, values):
if (
values["value"] is True
and values.get("owner") is None
and values["status"]
in [
status.value
for status in ProjectStatus
if status != ProjectStatus.MAINTAINING
]
):
msg = "Owner must be specified when the project is not in the 'MAINTAINING' status."
raise ValueError(msg)
return values


class ProjectRunningState(BaseModel):
value: RunningState = Field(
Expand Down
4 changes: 4 additions & 0 deletions packages/models-library/tests/test_projects_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ def test_project_locked_with_missing_owner_raises():
ProjectLocked.parse_obj({"value": False, "status": ProjectStatus.OPENED})


def test_project_locked_with_missing_owner_ok_during_maintaining():
ProjectLocked.parse_obj({"value": True, "status": ProjectStatus.MAINTAINING})


@pytest.mark.parametrize(
"lock, status",
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ async def removal_policy_task(app: FastAPI) -> None:
efs_project_ids: list[
ProjectID
] = await efs_manager.list_projects_across_whole_efs()
_logger.info(
"Number of projects that are currently in the EFS file system: %s",
len(efs_project_ids),
)

projects_repo = ProjectsRepo(app.state.engine)
for project_id in efs_project_ids:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@

_logger = logging.getLogger(__name__)

_SEC = 1000 # in ms
_MIN = 60 * _SEC # in ms
_HOUR = 60 * _MIN # in ms
_SEC = 1 # in s
_MIN = 60 * _SEC # in s
_HOUR = 60 * _MIN # in s


class EfsGuardianBackgroundTask(TypedDict):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async def _subscribe_to_rabbitmq(app) -> str:
def _on_app_startup(app: FastAPI) -> Callable[[], Awaitable[None]]:
async def _startup() -> None:
with log_context(
_logger, logging.INFO, msg="setup resource tracker"
_logger, logging.INFO, msg="setup efs guardian process messages"
), log_catch(_logger, reraise=False):
app_settings: ApplicationSettings = app.state.settings
app.state.efs_guardian_rabbitmq_consumer = None
Expand Down
Loading