diff --git a/swh/loader/core/tests/test_utils.py b/swh/loader/core/tests/test_utils.py --- a/swh/loader/core/tests/test_utils.py +++ b/swh/loader/core/tests/test_utils.py @@ -3,6 +3,7 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information +from datetime import datetime import os import signal from time import sleep @@ -15,6 +16,7 @@ CloneTimeout, clean_dangling_folders, clone_with_timeout, + parse_visit_date, ) @@ -145,3 +147,25 @@ clone_with_timeout(src, dest, ignores_sigterm, timeout) killed = True assert e.value.args == (src, timeout, killed) + + +VISIT_DATE_STR = "2021-02-17 15:50:04.518963" +VISIT_DATE = datetime(2021, 2, 17, 15, 50, 4, 518963) + + +@pytest.mark.parametrize( + "input_visit_date,expected_date", + [(None, None), (VISIT_DATE, VISIT_DATE), (VISIT_DATE_STR, VISIT_DATE),], +) +def test_utils_parse_visit_date(input_visit_date, expected_date): + assert parse_visit_date(input_visit_date) == expected_date + + +def test_utils_parse_visit_date_now(): + actual_date = parse_visit_date("now") + assert isinstance(actual_date, datetime) + + +def test_utils_parse_visit_date_fails(): + with pytest.raises(ValueError, match="invalid"): + parse_visit_date(10) # not a string nor a date diff --git a/swh/loader/core/utils.py b/swh/loader/core/utils.py --- a/swh/loader/core/utils.py +++ b/swh/loader/core/utils.py @@ -4,15 +4,17 @@ # See top-level LICENSE file for more information +from datetime import datetime, timezone import io import os import shutil import signal import time import traceback -from typing import Callable +from typing import Callable, Optional, Union from billiard import Process, Queue # type: ignore +from dateutil.parser import parse import psutil @@ -103,3 +105,23 @@ if not errors.empty(): raise CloneFailure(src, dest, errors.get()) + + +def parse_visit_date(visit_date: Optional[Union[datetime, str]]) -> Optional[datetime]: + """Convert visit date from either None, a string or a datetime to either None or + datetime. + + """ + if visit_date is None: + return None + + if isinstance(visit_date, datetime): + return visit_date + + if visit_date == "now": + return datetime.now(tz=timezone.utc) + + if isinstance(visit_date, str): + return parse(visit_date) + + raise ValueError(f"invalid visit date {visit_date!r}")