3333 TableType ,
3434)
3535from databricks .sdk .service .dashboards import Dashboard as SDKDashboard
36+ from databricks .sdk .service .ml import ModelTag
3637from databricks .sdk .service .serving import (
3738 EndpointCoreConfigInput ,
3839 ServedModelInput ,
3940 ServedModelInputWorkloadSize ,
4041 ServingEndpointDetailed ,
42+ EndpointTag ,
4143)
4244from databricks .sdk .service .sql import (
4345 CreateWarehouseRequestWarehouseType ,
@@ -120,7 +122,7 @@ def fresh_wheel_file(tmp_path) -> Path:
120122@pytest .fixture
121123def wsfs_wheel (ws , fresh_wheel_file , make_random ):
122124 my_user = ws .current_user .me ().user_name
123- workspace_location = f"/Users/{ my_user } /wheels/{ make_random (10 )} "
125+ workspace_location = f"/Users/{ my_user } /wheels/{ make_random (10 )} - { get_purge_suffix () } "
124126 ws .workspace .mkdirs (workspace_location )
125127
126128 wsfs_wheel = f"{ workspace_location } /{ fresh_wheel_file .name } "
@@ -582,7 +584,7 @@ def create(
582584 overwrite : bool = False ,
583585 ) -> str :
584586 if path is None :
585- path = f"/Users/{ ws .current_user .me ().user_name } /sdk-{ make_random (4 )} "
587+ path = f"/Users/{ ws .current_user .me ().user_name } /sdk-{ make_random (4 )} - { get_purge_suffix () } "
586588 elif isinstance (path , pathlib .Path ):
587589 path = str (path )
588590 if content is None :
@@ -609,7 +611,7 @@ def create(*, path: str | None = None):
609611def make_repo (ws , make_random ):
610612 def create (* , url = None , provider = None , path = None , ** kwargs ):
611613 if path is None :
612- path = f"/Repos/{ ws .current_user .me ().user_name } /sdk-{ make_random (4 )} "
614+ path = f"/Repos/{ ws .current_user .me ().user_name } /sdk-{ make_random (4 )} - { get_purge_suffix () } "
613615 if url is None :
614616 url = "https://github.com/shreyas-goenka/empty-repo.git"
615617 if provider is None :
@@ -760,9 +762,10 @@ def create(
760762 ** kwargs ,
761763 ):
762764 if path is None :
763- path = f"/Users/{ ws .current_user .me ().user_name } /{ make_random (4 )} "
765+ path = f"/Users/{ ws .current_user .me ().user_name } /{ make_random (4 )} - { get_purge_suffix () } "
764766 if experiment_name is None :
765- experiment_name = f"sdk-{ make_random (4 )} "
767+ # The purge suffix is needed here as well, just in case the path was supplied.
768+ experiment_name = f"sdk-{ make_random (4 )} -{ get_purge_suffix ()} "
766769
767770 try :
768771 ws .workspace .mkdirs (path )
@@ -842,6 +845,11 @@ def create(
842845 ):
843846 if model_name is None :
844847 model_name = f"sdk-{ make_random (4 )} "
848+ remove_after_tag = ModelTag (key = "RemoveAfter" , value = get_test_purge_time ())
849+ if 'tags' not in kwargs :
850+ kwargs ["tags" ] = [remove_after_tag ]
851+ else :
852+ kwargs ["tags" ].append (remove_after_tag )
845853
846854 created_model = ws .model_registry .create_model (model_name , ** kwargs )
847855 model = ws .model_registry .get_model (created_model .registered_model .name )
@@ -854,7 +862,7 @@ def create(
854862def make_pipeline (ws , make_random , make_notebook ):
855863 def create (** kwargs ) -> pipelines .CreatePipelineResponse :
856864 if "name" not in kwargs :
857- kwargs ["name" ] = f"sdk-{ make_random (4 )} "
865+ kwargs ["name" ] = f"sdk-{ make_random (4 )} - { get_purge_suffix () } "
858866 if "libraries" not in kwargs :
859867 kwargs ["libraries" ] = [pipelines .PipelineLibrary (notebook = pipelines .NotebookLibrary (path = make_notebook ()))]
860868 if "clusters" not in kwargs :
@@ -863,9 +871,7 @@ def create(**kwargs) -> pipelines.CreatePipelineResponse:
863871 node_type_id = ws .clusters .select_node_type (local_disk = True , min_memory_gb = 16 ),
864872 label = "default" ,
865873 num_workers = 1 ,
866- custom_tags = {
867- "cluster_type" : "default" ,
868- },
874+ custom_tags = {"cluster_type" : "default" , "RemoveAfter" : get_test_purge_time ()},
869875 )
870876 ]
871877 return ws .pipelines .create (continuous = False , ** kwargs )
@@ -965,6 +971,8 @@ def inventory_schema(make_schema):
965971@pytest .fixture
966972def make_catalog (ws , sql_backend , make_random ) -> Generator [Callable [..., CatalogInfo ], None , None ]:
967973 def create () -> CatalogInfo :
974+ # Warning: As of 2024-09-04 there is no way to mark this catalog for protection against the watchdog.
975+ # Ref: https://github.com/databrickslabs/watchdog/blob/cdc97afdac1567e89d3b39d938f066fd6267b3ba/scan/objects/uc.go#L68
968976 name = f"ucx_C{ make_random (4 )} " .lower ()
969977 sql_backend .execute (f"CREATE CATALOG { name } " )
970978 catalog_info = ws .catalogs .get (name )
@@ -1042,6 +1050,7 @@ def create( # pylint: disable=too-many-locals,too-many-arguments,too-many-state
10421050 elif non_delta :
10431051 table_type = TableType .EXTERNAL # pylint: disable=redefined-variable-type
10441052 data_source_format = DataSourceFormat .JSON
1053+ # DBFS locations are not purged; no suffix necessary.
10451054 storage_location = f"dbfs:/tmp/ucx_test_{ make_random (4 )} "
10461055 # Modified, otherwise it will identify the table as a DB Dataset
10471056 ddl = (
@@ -1151,7 +1160,10 @@ def create(
11511160 schema_name = schema .name
11521161
11531162 if name is None :
1154- name = f"ucx_T{ make_random (4 )} " .lower ()
1163+ name = f"ucx_t{ make_random (4 ).lower ()} "
1164+
1165+ # Note: the Watchdog does not explicitly scan for functions; they are purged along with their parent schema.
1166+ # As such the function can't be marked (and doesn't need to be if the schema as marked) for purge protection.
11551167
11561168 full_name = f"{ catalog_name } .{ schema_name } .{ name } " .lower ()
11571169 if hive_udf :
@@ -1173,7 +1185,7 @@ def create(
11731185 full_name = full_name ,
11741186 )
11751187
1176- logger .info (f"Function { udf_info .full_name } crated " )
1188+ logger .info (f"Function { udf_info .full_name } created " )
11771189 return udf_info
11781190
11791191 def remove (udf_info : FunctionInfo ):
@@ -1192,7 +1204,7 @@ def remove(udf_info: FunctionInfo):
11921204def make_query (ws , make_table , make_random ) -> Generator [LegacyQuery , None , None ]:
11931205 def create () -> LegacyQuery :
11941206 table = make_table ()
1195- query_name = f"ucx_query_Q{ make_random (4 )} "
1207+ query_name = f"ucx_query_Q{ make_random (4 )} _ { get_purge_suffix () } "
11961208 query = ws .queries_legacy .create (
11971209 name = query_name ,
11981210 description = "TEST QUERY FOR UCX" ,
@@ -1256,6 +1268,7 @@ def create() -> Wait[ServingEndpointDetailed]:
12561268 )
12571269 ]
12581270 ),
1271+ tags = [EndpointTag (key = "RemoveAfter" , value = get_test_purge_time ())],
12591272 )
12601273 return endpoint
12611274
@@ -1328,7 +1341,8 @@ def make_mounted_location(make_random, make_dbfs_data_copy, env_or_skip):
13281341 location; the mounted location is made with fixture setup already.
13291342 """
13301343 existing_mounted_location = f'dbfs:/mnt/{ env_or_skip ("TEST_MOUNT_NAME" )} /a/b/c'
1331- new_mounted_location = f'dbfs:/mnt/{ env_or_skip ("TEST_MOUNT_NAME" )} /a/b/{ make_random (4 )} '
1344+ # DBFS locations are not purged; no suffix necessary.
1345+ new_mounted_location = f'dbfs:/mnt/{ env_or_skip ("TEST_MOUNT_NAME" )} /a/b/{ make_random (4 )} -{ get_purge_suffix ()} '
13321346 make_dbfs_data_copy (src_path = existing_mounted_location , dst_path = new_mounted_location )
13331347 return new_mounted_location
13341348
@@ -1377,7 +1391,7 @@ def create() -> Dashboard:
13771391 },
13781392 )
13791393
1380- dashboard_name = f"ucx_D{ make_random (4 )} "
1394+ dashboard_name = f"ucx_D{ make_random (4 )} _ { get_purge_suffix () } "
13811395 dashboard = ws .dashboards .create (name = dashboard_name , tags = ["original_dashboard_tag" ])
13821396 assert dashboard .id is not None
13831397 ws .dashboard_widgets .create (
@@ -1445,10 +1459,10 @@ def make_lakeview_dashboard(ws, make_random, env_or_skip):
14451459 }
14461460
14471461 def create (display_name : str = "" ) -> SDKDashboard :
1448- if len (display_name ) == 0 :
1449- display_name = f"created_by_ucx_{ make_random ()} "
1450- else :
1462+ if display_name :
14511463 display_name = f"{ display_name } ({ make_random ()} )"
1464+ else :
1465+ display_name = f"created_by_ucx_{ make_random ()} _{ get_purge_suffix ()} "
14521466 dashboard = ws .lakeview .create (
14531467 display_name ,
14541468 serialized_dashboard = json .dumps (serialized_dashboard ),
0 commit comments