|
16 | 16 | )
|
17 | 17 | from titan.client import reset_cache
|
18 | 18 | from titan.enums import BlueprintScope, ResourceType
|
| 19 | +from titan.exceptions import NotADAGException |
19 | 20 | from titan.gitops import collect_blueprint_config
|
20 | 21 | from titan.resources.database import public_schema_urn
|
21 | 22 |
|
@@ -607,3 +608,90 @@ def test_blueprint_share_custom_owner(cursor, suffix):
|
607 | 608 | blueprint.apply(session, plan)
|
608 | 609 | finally:
|
609 | 610 | cursor.execute(f"DROP SHARE IF EXISTS {share_name}")
|
| 611 | + |
| 612 | + |
| 613 | +def test_stage_read_write_privilege_execution_order(cursor, suffix, marked_for_cleanup): |
| 614 | + session = cursor.connection |
| 615 | + |
| 616 | + role_name = f"STAGE_ACCESS_ROLE_{suffix}" |
| 617 | + |
| 618 | + blueprint = Blueprint() |
| 619 | + |
| 620 | + role = res.Role(name=role_name) |
| 621 | + read_grant = res.Grant(priv="READ", on_stage="STATIC_DATABASE.PUBLIC.STATIC_STAGE", to=role) |
| 622 | + write_grant = res.Grant(priv="WRITE", on_stage="STATIC_DATABASE.PUBLIC.STATIC_STAGE", to=role) |
| 623 | + |
| 624 | + # Incorrect order of execution |
| 625 | + read_grant.requires(write_grant) |
| 626 | + |
| 627 | + blueprint.add(role, read_grant, write_grant) |
| 628 | + |
| 629 | + marked_for_cleanup.append(role) |
| 630 | + |
| 631 | + with pytest.raises(NotADAGException): |
| 632 | + blueprint.plan(session) |
| 633 | + |
| 634 | + blueprint = Blueprint() |
| 635 | + |
| 636 | + role = res.Role(name=role_name) |
| 637 | + read_grant = res.Grant(priv="READ", on_stage="STATIC_DATABASE.PUBLIC.STATIC_STAGE", to=role) |
| 638 | + write_grant = res.Grant(priv="WRITE", on_stage="STATIC_DATABASE.PUBLIC.STATIC_STAGE", to=role) |
| 639 | + |
| 640 | + # Implicitly ordered incorrectly |
| 641 | + blueprint.add(role, write_grant, read_grant) |
| 642 | + |
| 643 | + plan = blueprint.plan(session) |
| 644 | + assert len(plan) == 3 |
| 645 | + blueprint.apply(session, plan) |
| 646 | + |
| 647 | + blueprint = Blueprint() |
| 648 | + |
| 649 | + read_on_all = res.GrantOnAll( |
| 650 | + priv="READ", on_type="STAGE", in_type="SCHEMA", in_name="STATIC_DATABASE.PUBLIC", to=role_name |
| 651 | + ) |
| 652 | + future_read = res.FutureGrant( |
| 653 | + priv="READ", on_type="STAGE", in_type="SCHEMA", in_name="STATIC_DATABASE.PUBLIC", to=role_name |
| 654 | + ) |
| 655 | + write_on_all = res.GrantOnAll( |
| 656 | + priv="WRITE", on_type="STAGE", in_type="SCHEMA", in_name="STATIC_DATABASE.PUBLIC", to=role_name |
| 657 | + ) |
| 658 | + future_write = res.FutureGrant( |
| 659 | + priv="WRITE", on_type="STAGE", in_type="SCHEMA", in_name="STATIC_DATABASE.PUBLIC", to=role_name |
| 660 | + ) |
| 661 | + |
| 662 | + # Implicitly ordered incorrectly |
| 663 | + blueprint.add(future_write, future_read, write_on_all, read_on_all) |
| 664 | + |
| 665 | + plan = blueprint.plan(session) |
| 666 | + assert len(plan) == 4 |
| 667 | + blueprint.apply(session, plan) |
| 668 | + |
| 669 | + |
| 670 | +def test_grant_database_role_to_database_role(cursor, suffix, marked_for_cleanup): |
| 671 | + session = cursor.connection |
| 672 | + bp = Blueprint() |
| 673 | + |
| 674 | + parent = res.DatabaseRole(name=f"DBR2DBR_PARENT_{suffix}", database="STATIC_DATABASE") |
| 675 | + child1 = res.DatabaseRole(name=f"DBR2DBR_CHILD_1_{suffix}", database="STATIC_DATABASE") |
| 676 | + child2 = res.DatabaseRole(name=f"DBR2DBR_CHILD_2_{suffix}", database="STATIC_DATABASE") |
| 677 | + drg1 = res.DatabaseRoleGrant(database_role=child1, to_database_role=parent) |
| 678 | + drg2 = res.DatabaseRoleGrant(database_role=child2, to_database_role=parent) |
| 679 | + |
| 680 | + marked_for_cleanup.append(parent) |
| 681 | + marked_for_cleanup.append(child1) |
| 682 | + marked_for_cleanup.append(child2) |
| 683 | + |
| 684 | + bp.add(parent, child1, child2, drg1, drg2) |
| 685 | + plan = bp.plan(session) |
| 686 | + assert len(plan) == 5 |
| 687 | + bp.apply(session, plan) |
| 688 | + |
| 689 | + grant1 = safe_fetch(cursor, res.DatabaseRoleGrant(database_role=child1, to_database_role=parent).urn) |
| 690 | + assert grant1 is not None |
| 691 | + assert grant1["database_role"] == str(child1.fqn) |
| 692 | + assert grant1["to_database_role"] == str(parent.fqn) |
| 693 | + |
| 694 | + grant2 = safe_fetch(cursor, res.DatabaseRoleGrant(database_role=child2, to_database_role=parent).urn) |
| 695 | + assert grant2 is not None |
| 696 | + assert grant2["database_role"] == str(child2.fqn) |
| 697 | + assert grant2["to_database_role"] == str(parent.fqn) |
0 commit comments