|
| 1 | +import logging |
| 2 | +from datetime import timedelta |
| 3 | + |
| 4 | +from databricks.sdk.errors import NotFound |
| 5 | +from databricks.sdk.retries import retried |
| 6 | +from databricks.sdk.service.catalog import Privilege, PrivilegeAssignment, SecurableType |
| 7 | + |
| 8 | +from databricks.labs.ucx.hive_metastore.table_migrate import TableMove |
| 9 | + |
| 10 | +logger = logging.getLogger(__name__) |
| 11 | + |
| 12 | + |
| 13 | +@retried(on=[NotFound], timeout=timedelta(minutes=2)) |
| 14 | +def test_move_tables_no_from_schema(ws, sql_backend, make_random, make_catalog, caplog): |
| 15 | + from_catalog = make_catalog() |
| 16 | + from_schema = make_random(4) |
| 17 | + to_catalog = make_catalog() |
| 18 | + tm = TableMove(ws, sql_backend) |
| 19 | + tm.move_tables(from_catalog.name, from_schema, "*", to_catalog.name, from_schema, False) |
| 20 | + rec_results = [ |
| 21 | + rec.message |
| 22 | + for rec in caplog.records |
| 23 | + if f"schema {from_schema} not found in catalog {from_catalog.name}" in rec.message |
| 24 | + ] |
| 25 | + assert len(rec_results) == 1 |
| 26 | + |
| 27 | + |
| 28 | +@retried(on=[NotFound], timeout=timedelta(minutes=2)) |
| 29 | +def test_move_tables(ws, sql_backend, make_catalog, make_schema, make_table, make_acc_group): |
| 30 | + tm = TableMove(ws, sql_backend) |
| 31 | + group_a = make_acc_group() |
| 32 | + group_b = make_acc_group() |
| 33 | + from_catalog = make_catalog() |
| 34 | + from_schema = make_schema(catalog_name=from_catalog.name) |
| 35 | + from_table_1 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 36 | + from_table_2 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 37 | + from_table_3 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 38 | + from_view_1 = make_table( |
| 39 | + catalog_name=from_catalog.name, |
| 40 | + schema_name=from_schema.name, |
| 41 | + view=True, |
| 42 | + ctas=f"select * from {from_table_2.full_name}", |
| 43 | + ) |
| 44 | + to_catalog = make_catalog() |
| 45 | + to_schema = make_schema(catalog_name=to_catalog.name) |
| 46 | + # creating a table in target schema to test skipping |
| 47 | + to_table_3 = make_table(catalog_name=to_catalog.name, schema_name=to_schema.name, name=from_table_3.name) |
| 48 | + sql_backend.execute(f"GRANT SELECT ON TABLE {from_table_1.full_name} TO `{group_a.display_name}`") |
| 49 | + sql_backend.execute(f"GRANT SELECT,MODIFY ON TABLE {from_table_2.full_name} TO `{group_b.display_name}`") |
| 50 | + sql_backend.execute(f"GRANT SELECT ON VIEW {from_view_1.full_name} TO `{group_b.display_name}`") |
| 51 | + sql_backend.execute(f"GRANT SELECT ON TABLE {to_table_3.full_name} TO `{group_a.display_name}`") |
| 52 | + tm.move_tables(from_catalog.name, from_schema.name, "*", to_catalog.name, to_schema.name, False) |
| 53 | + tables = ws.tables.list(catalog_name=to_catalog.name, schema_name=to_schema.name) |
| 54 | + table_1_grant = ws.grants.get( |
| 55 | + securable_type=SecurableType.TABLE, full_name=f"{to_catalog.name}.{to_schema.name}.{from_table_1.name}" |
| 56 | + ) |
| 57 | + table_2_grant = ws.grants.get( |
| 58 | + securable_type=SecurableType.TABLE, full_name=f"{to_catalog.name}.{to_schema.name}.{from_table_2.name}" |
| 59 | + ) |
| 60 | + table_3_grant = ws.grants.get( |
| 61 | + securable_type=SecurableType.TABLE, full_name=f"{to_catalog.name}.{to_schema.name}.{from_table_3.name}" |
| 62 | + ) |
| 63 | + view_1_grant = ws.grants.get( |
| 64 | + securable_type=SecurableType.TABLE, full_name=f"{to_catalog.name}.{to_schema.name}.{from_view_1.name}" |
| 65 | + ) |
| 66 | + for t in tables: |
| 67 | + assert t.name in [from_table_1.name, from_table_2.name, from_table_3.name, from_view_1.name] |
| 68 | + expected_table_1_grant = [PrivilegeAssignment(group_a.display_name, [Privilege.SELECT])] |
| 69 | + expected_table_2_grant = [ |
| 70 | + PrivilegeAssignment(group_b.display_name, [Privilege.MODIFY, Privilege.SELECT]), |
| 71 | + ] |
| 72 | + expected_table_3_grant = [PrivilegeAssignment(group_a.display_name, [Privilege.SELECT])] |
| 73 | + expected_view_1_grant = [PrivilegeAssignment(group_b.display_name, [Privilege.SELECT])] |
| 74 | + assert table_1_grant.privilege_assignments == expected_table_1_grant |
| 75 | + assert table_2_grant.privilege_assignments == expected_table_2_grant |
| 76 | + assert table_3_grant.privilege_assignments == expected_table_3_grant |
| 77 | + assert view_1_grant.privilege_assignments == expected_view_1_grant |
| 78 | + |
| 79 | + |
| 80 | +@retried(on=[NotFound], timeout=timedelta(minutes=2)) |
| 81 | +def test_move_tables_no_to_schema(ws, sql_backend, make_catalog, make_schema, make_table, make_random): |
| 82 | + tm = TableMove(ws, sql_backend) |
| 83 | + from_catalog = make_catalog() |
| 84 | + from_schema = make_schema(catalog_name=from_catalog.name) |
| 85 | + from_table_1 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 86 | + from_table_2 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 87 | + from_table_3 = make_table(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 88 | + to_catalog = make_catalog() |
| 89 | + to_schema = make_random(4) |
| 90 | + tm.move_tables(from_catalog.name, from_schema.name, from_table_1.name, to_catalog.name, to_schema, True) |
| 91 | + tables = ws.tables.list(catalog_name=to_catalog.name, schema_name=to_schema) |
| 92 | + dropped_tables = ws.tables.list(catalog_name=from_catalog.name, schema_name=from_schema.name) |
| 93 | + for t in tables: |
| 94 | + assert t.name in [from_table_1.name, from_table_2.name, from_table_3.name] |
| 95 | + for t in dropped_tables: |
| 96 | + assert t.name in [from_table_1.name, from_table_2.name, from_table_3.name] |
0 commit comments