Skip to content

Commit 815c7e8

Browse files
authored
Update purge suffix so that resources are preserved for at least as long as the configured timeout. (#2265)
## Changes This PR updates the purge suffix used by integration tests so that resources are marked for preservation _at least_ as long as the configured timeout. The situation is that: - Many resources can be marked with a tag (or a special suffix in the name) to ensure they are preserved until a specific time. - The timestamp refers to a UTC-based hour, such as: `2024072915`. This means that resources can be deleted at any moment after 3 p.m. (UTC). - Prior to this change, resources created as late as 2:44:59 p.m. would be tagged for deletion with `2024072915` meaning deletion as of 3 p.m. This is 0:15 later instead of the intended 1:15. The default timeout for tests was 1:15 in an attempt to deal with resources being deleted when the test started near the hour boundary. This PR also updates the default timeout to 1:00 because the extra 0:15 isn't needed to ensure this.
1 parent 1678159 commit 815c7e8

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/databricks/labs/ucx/installer/workflows.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import webbrowser
88
from collections.abc import Iterator
99
from dataclasses import replace
10-
from datetime import datetime, timedelta
10+
from datetime import datetime, timedelta, timezone
1111
from io import StringIO
1212
from pathlib import Path
1313
from typing import Any
@@ -53,8 +53,8 @@
5353

5454
logger = logging.getLogger(__name__)
5555

56-
TEST_JOBS_PURGE_TIMEOUT = timedelta(hours=1, minutes=15)
57-
TEST_NIGHTLY_CI_JOBS_PURGE_TIMEOUT = timedelta(hours=3) # Buffer for debugging nightly integration test runs
56+
TEST_RESOURCE_PURGE_TIMEOUT = timedelta(hours=1)
57+
TEST_NIGHTLY_CI_RESOURCES_PURGE_TIMEOUT = timedelta(hours=3) # Buffer for debugging nightly integration test runs
5858
EXTRA_TASK_PARAMS = {
5959
"job_id": "{{job_id}}",
6060
"run_id": "{{run_id}}",
@@ -462,9 +462,15 @@ def _is_nightly():
462462
ci_env = os.getenv("TEST_NIGHTLY")
463463
return ci_env is not None and ci_env.lower() == "true"
464464

465-
def _get_test_purge_time(self) -> str:
466-
timeout = TEST_NIGHTLY_CI_JOBS_PURGE_TIMEOUT if self._is_nightly() else TEST_JOBS_PURGE_TIMEOUT
467-
return (datetime.utcnow() + timeout).strftime("%Y%m%d%H")
465+
@classmethod
466+
def _get_test_purge_time(cls) -> str:
467+
# Duplicate of mixins.fixtures.get_test_purge_time(); we don't want to import pytest as a transitive dependency.
468+
timeout = TEST_NIGHTLY_CI_RESOURCES_PURGE_TIMEOUT if cls._is_nightly() else TEST_RESOURCE_PURGE_TIMEOUT
469+
now = datetime.now(timezone.utc)
470+
purge_deadline = now + timeout
471+
# Round UP to the next hour boundary: that is when resources will be deleted.
472+
purge_hour = purge_deadline + (datetime.min.replace(tzinfo=timezone.utc) - purge_deadline) % timedelta(hours=1)
473+
return purge_hour.strftime("%Y%m%d%H")
468474

469475
def _create_readme(self) -> None:
470476
debug_notebook_link = self._installation.workspace_markdown_link('debug notebook', 'DEBUG.py')

src/databricks/labs/ucx/mixins/fixtures.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import subprocess
99
import sys
1010
from collections.abc import Callable, Generator, MutableMapping
11-
from datetime import timedelta, datetime
11+
from datetime import datetime, timedelta, timezone
1212
from pathlib import Path
1313
from typing import BinaryIO
1414

@@ -58,7 +58,9 @@
5858
# pylint: disable=redefined-outer-name,too-many-try-statements,import-outside-toplevel,unnecessary-lambda,too-complex,invalid-name
5959

6060
logger = logging.getLogger(__name__)
61-
TEST_JOBS_PURGE_TIMEOUT = timedelta(hours=1, minutes=15) # 15 minutes grace for jobs starting at the end of the hour
61+
62+
"""Preserve resources created during tests for at least this long."""
63+
TEST_RESOURCE_PURGE_TIMEOUT = timedelta(hours=1)
6264

6365

6466
def factory(name, create, remove):
@@ -1461,8 +1463,15 @@ def delete(dashboard: SDKDashboard) -> None:
14611463
yield from factory("dashboard", create, delete)
14621464

14631465

1464-
def get_test_purge_time() -> str:
1465-
return (datetime.utcnow() + TEST_JOBS_PURGE_TIMEOUT).strftime("%Y%m%d%H")
1466+
def get_test_purge_time(timeout: timedelta = TEST_RESOURCE_PURGE_TIMEOUT) -> str:
1467+
"""Purge time for test objects, representing the (UTC-based) hour from which objects may be purged."""
1468+
# Note: this code is duplicated in the workflow installer (WorkflowsDeployment) so that it can avoid the
1469+
# transitive pytest deployment from this module.
1470+
now = datetime.now(timezone.utc)
1471+
purge_deadline = now + timeout
1472+
# Round UP to the next hour boundary: that is when resources will be deleted.
1473+
purge_hour = purge_deadline + (datetime.min.replace(tzinfo=timezone.utc) - purge_deadline) % timedelta(hours=1)
1474+
return purge_hour.strftime("%Y%m%d%H")
14661475

14671476

14681477
def get_purge_suffix() -> str:

0 commit comments

Comments
 (0)