|
61 | 61 | model, |
62 | 62 | ) |
63 | 63 | from sqlmesh.core.model.common import parse_expression |
64 | | -from sqlmesh.core.model.kind import ModelKindName, _model_kind_validator |
| 64 | +from sqlmesh.core.model.kind import _ModelKind, ModelKindName, _model_kind_validator |
65 | 65 | from sqlmesh.core.model.seed import CsvSettings |
66 | 66 | from sqlmesh.core.node import IntervalUnit, _Node |
67 | 67 | from sqlmesh.core.signal import signal |
@@ -11628,90 +11628,235 @@ def test_use_original_sql(): |
11628 | 11628 | assert model.post_statements_[0].sql == "CREATE TABLE post (b INT)" |
11629 | 11629 |
|
11630 | 11630 |
|
11631 | | -def test_grants_validation_symbolic_model_error(): |
11632 | | - with pytest.raises(ValidationError, match=r".*grants cannot be set for EXTERNAL.*"): |
11633 | | - create_sql_model( |
11634 | | - "db.table", |
11635 | | - parse_one("SELECT 1 AS id"), |
11636 | | - kind="EXTERNAL", |
11637 | | - grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
11638 | | - ) |
| 11631 | +@pytest.mark.parametrize( |
| 11632 | + "kind", |
| 11633 | + [ |
| 11634 | + "FULL", |
| 11635 | + "VIEW", |
| 11636 | + SeedKind(path="test.csv"), |
| 11637 | + IncrementalByTimeRangeKind(time_column="ds"), |
| 11638 | + IncrementalByUniqueKeyKind(unique_key="id"), |
| 11639 | + ], |
| 11640 | +) |
| 11641 | +def test_grants_valid_model_kinds(kind: t.Union[str, _ModelKind]): |
| 11642 | + model = create_sql_model( |
| 11643 | + "db.table", |
| 11644 | + parse_one("SELECT 1 AS id"), |
| 11645 | + kind=kind, |
| 11646 | + grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
| 11647 | + ) |
| 11648 | + assert model.grants == {"select": ["user1", "user2"], "insert": ["admin_user"]} |
11639 | 11649 |
|
11640 | 11650 |
|
11641 | | -def test_grants_validation_embedded_model_error(): |
11642 | | - with pytest.raises(ValidationError, match=r".*grants cannot be set for EMBEDDED.*"): |
| 11651 | +@pytest.mark.parametrize( |
| 11652 | + "kind", |
| 11653 | + [ |
| 11654 | + "EXTERNAL", |
| 11655 | + "EMBEDDED", |
| 11656 | + ], |
| 11657 | +) |
| 11658 | +def test_grants_invalid_model_kind_errors(kind: str): |
| 11659 | + with pytest.raises(ValidationError, match=rf".*grants cannot be set for {kind}.*"): |
11643 | 11660 | create_sql_model( |
11644 | 11661 | "db.table", |
11645 | 11662 | parse_one("SELECT 1 AS id"), |
11646 | | - kind="EMBEDDED", |
| 11663 | + kind=kind, |
11647 | 11664 | grants={"select": ["user1"], "insert": ["admin_user"]}, |
11648 | 11665 | ) |
11649 | 11666 |
|
11650 | 11667 |
|
11651 | | -def test_grants_validation_valid_seed_model(): |
| 11668 | +def test_grants_validation_no_grants(): |
| 11669 | + model = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
| 11670 | + assert model.grants is None |
| 11671 | + |
| 11672 | + |
| 11673 | +def test_grants_validation_empty_grantees(): |
11652 | 11674 | model = create_sql_model( |
11653 | | - "db.table", |
11654 | | - parse_one("SELECT 1 AS id"), |
11655 | | - kind=SeedKind(path="test.csv"), |
11656 | | - grants={"select": ["user1"], "insert": ["admin_user"]}, |
| 11675 | + "db.table", parse_one("SELECT 1 AS id"), kind="FULL", grants={"select": []} |
11657 | 11676 | ) |
11658 | | - assert model.grants == {"select": ["user1"], "insert": ["admin_user"]} |
| 11677 | + assert model.grants == {"select": []} |
11659 | 11678 |
|
11660 | 11679 |
|
11661 | | -def test_grants_validation_valid_materialized_model(): |
| 11680 | +def test_grants_single_value_conversions(): |
| 11681 | + expressions = d.parse(f""" |
| 11682 | + MODEL ( |
| 11683 | + name test.nested_arrays, |
| 11684 | + kind FULL, |
| 11685 | + grants ( |
| 11686 | + 'select' = "user1", update = user2 |
| 11687 | + ) |
| 11688 | + ); |
| 11689 | + SELECT 1 as id |
| 11690 | + """) |
| 11691 | + model = load_sql_based_model(expressions) |
| 11692 | + assert model.grants == {"select": ["user1"], "update": ["user2"]} |
| 11693 | + |
11662 | 11694 | model = create_sql_model( |
11663 | 11695 | "db.table", |
11664 | 11696 | parse_one("SELECT 1 AS id"), |
11665 | 11697 | kind="FULL", |
11666 | | - grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
| 11698 | + grants={"select": "user1", "insert": 123}, |
11667 | 11699 | ) |
11668 | | - assert model.grants == {"select": ["user1", "user2"], "insert": ["admin_user"]} |
| 11700 | + assert model.grants == {"select": ["user1"], "insert": ["123"]} |
11669 | 11701 |
|
11670 | 11702 |
|
11671 | | -def test_grants_validation_valid_view_model(): |
11672 | | - model = create_sql_model( |
11673 | | - "db.table", parse_one("SELECT 1 AS id"), kind="VIEW", grants={"select": ["user1", "user2"]} |
| 11703 | +@pytest.mark.parametrize( |
| 11704 | + "grantees", |
| 11705 | + [ |
| 11706 | + "('user1', ('user2', 'user3'), 'user4')", |
| 11707 | + "('user1', ['user2', 'user3'], user4)", |
| 11708 | + "['user1', ['user2', user3], 'user4']", |
| 11709 | + "[user1, ('user2', \"user3\"), 'user4']", |
| 11710 | + ], |
| 11711 | +) |
| 11712 | +def test_grants_array_flattening(grantees: str): |
| 11713 | + expressions = d.parse(f""" |
| 11714 | + MODEL ( |
| 11715 | + name test.nested_arrays, |
| 11716 | + kind FULL, |
| 11717 | + grants ( |
| 11718 | + 'select' = {grantees} |
| 11719 | + ) |
| 11720 | + ); |
| 11721 | + SELECT 1 as id |
| 11722 | + """) |
| 11723 | + model = load_sql_based_model(expressions) |
| 11724 | + assert model.grants == {"select": ["user1", "user2", "user3", "user4"]} |
| 11725 | + |
| 11726 | + |
| 11727 | +def test_grants_macro_var_resolved(): |
| 11728 | + expressions = d.parse(""" |
| 11729 | + MODEL ( |
| 11730 | + name test.macro_grants, |
| 11731 | + kind FULL, |
| 11732 | + grants ( |
| 11733 | + 'select' = @VAR('readers'), |
| 11734 | + 'insert' = @VAR('writers') |
| 11735 | + ) |
| 11736 | + ); |
| 11737 | + SELECT 1 as id |
| 11738 | + """) |
| 11739 | + model = load_sql_based_model( |
| 11740 | + expressions, variables={"readers": ["user1", "user2"], "writers": "admin"} |
11674 | 11741 | ) |
11675 | | - assert model.grants == {"select": ["user1", "user2"]} |
| 11742 | + assert model.grants == { |
| 11743 | + "select": ["user1", "user2"], |
| 11744 | + "insert": ["admin"], |
| 11745 | + } |
11676 | 11746 |
|
11677 | 11747 |
|
11678 | | -def test_grants_validation_valid_incremental_model(): |
11679 | | - model = create_sql_model( |
11680 | | - "db.table", |
11681 | | - parse_one("SELECT 1 AS id, CURRENT_TIMESTAMP AS ts"), |
11682 | | - kind=IncrementalByTimeRangeKind(time_column="ts"), |
11683 | | - grants={"select": ["user1"], "update": ["admin_user"]}, |
| 11748 | +def test_grants_macro_var_in_array_flattening(): |
| 11749 | + expressions = d.parse(""" |
| 11750 | + MODEL ( |
| 11751 | + name test.macro_in_array, |
| 11752 | + kind FULL, |
| 11753 | + grants ( |
| 11754 | + 'select' = ['user1', @VAR('admins'), 'user3'] |
| 11755 | + ) |
| 11756 | + ); |
| 11757 | + SELECT 1 as id |
| 11758 | + """) |
| 11759 | + |
| 11760 | + model = load_sql_based_model(expressions, variables={"admins": ["admin1", "admin2"]}) |
| 11761 | + assert model.grants == {"select": ["user1", "admin1", "admin2", "user3"]} |
| 11762 | + |
| 11763 | + model2 = load_sql_based_model(expressions, variables={"admins": "super_admin"}) |
| 11764 | + assert model2.grants == {"select": ["user1", "super_admin", "user3"]} |
| 11765 | + |
| 11766 | + |
| 11767 | +def test_grants_dynamic_permission_names(): |
| 11768 | + expressions = d.parse(""" |
| 11769 | + MODEL ( |
| 11770 | + name test.dynamic_keys, |
| 11771 | + kind FULL, |
| 11772 | + grants ( |
| 11773 | + @VAR('read_perm') = ['user1', 'user2'], |
| 11774 | + @VAR('write_perm') = ['admin'] |
| 11775 | + ) |
| 11776 | + ); |
| 11777 | + SELECT 1 as id |
| 11778 | + """) |
| 11779 | + model = load_sql_based_model( |
| 11780 | + expressions, variables={"read_perm": "select", "write_perm": "insert"} |
11684 | 11781 | ) |
11685 | | - assert model.grants == {"select": ["user1"], "update": ["admin_user"]} |
| 11782 | + assert model.grants == {"select": ["user1", "user2"], "insert": ["admin"]} |
11686 | 11783 |
|
11687 | 11784 |
|
11688 | | -def test_grants_validation_no_grants(): |
11689 | | - model = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
11690 | | - assert model.grants is None |
| 11785 | +def test_grants_unresolved_macro_errors(): |
| 11786 | + expressions1 = d.parse(""" |
| 11787 | + MODEL (name test.bad1, kind FULL, grants ('select' = @VAR('undefined'))); |
| 11788 | + SELECT 1 as id |
| 11789 | + """) |
| 11790 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration for 'select': NULL value"): |
| 11791 | + load_sql_based_model(expressions1) |
11691 | 11792 |
|
| 11793 | + expressions2 = d.parse(""" |
| 11794 | + MODEL (name test.bad2, kind FULL, grants (@VAR('undefined') = ['user'])); |
| 11795 | + SELECT 1 as id |
| 11796 | + """) |
| 11797 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration.*NULL value"): |
| 11798 | + load_sql_based_model(expressions2) |
11692 | 11799 |
|
11693 | | -def test_grants_validation_empty_grantees(): |
11694 | | - model = create_sql_model( |
| 11800 | + expressions3 = d.parse(""" |
| 11801 | + MODEL (name test.bad3, kind FULL, grants ('select' = ['user', @VAR('undefined')])); |
| 11802 | + SELECT 1 as id |
| 11803 | + """) |
| 11804 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration for 'select': NULL value"): |
| 11805 | + load_sql_based_model(expressions3) |
| 11806 | + |
| 11807 | + |
| 11808 | +def test_grants_mixed_types_conversion(): |
| 11809 | + expressions = d.parse(""" |
| 11810 | + MODEL ( |
| 11811 | + name test.mixed_types, |
| 11812 | + kind FULL, |
| 11813 | + grants ( |
| 11814 | + 'select' = ['user1', 123, admin_role, 'user2'] |
| 11815 | + ) |
| 11816 | + ); |
| 11817 | + SELECT 1 as id |
| 11818 | + """) |
| 11819 | + model = load_sql_based_model(expressions) |
| 11820 | + assert model.grants == {"select": ["user1", "123", "admin_role", "user2"]} |
| 11821 | + |
| 11822 | + |
| 11823 | +def test_grants_empty_values(): |
| 11824 | + model1 = create_sql_model( |
11695 | 11825 | "db.table", parse_one("SELECT 1 AS id"), kind="FULL", grants={"select": []} |
11696 | 11826 | ) |
11697 | | - assert model.grants == {"select": []} |
| 11827 | + assert model1.grants == {"select": []} |
11698 | 11828 |
|
| 11829 | + model2 = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
| 11830 | + assert model2.grants is None |
11699 | 11831 |
|
11700 | | -def test_grants_table_type_view(): |
11701 | | - model = create_sql_model("test_view", parse_one("SELECT 1 as id"), kind="VIEW") |
11702 | | - assert model.grants_table_type == DataObjectType.VIEW |
11703 | 11832 |
|
| 11833 | +def test_grants_backward_compatibility(): |
11704 | 11834 | model = create_sql_model( |
11705 | | - "test_mv", parse_one("SELECT 1 as id"), kind=ViewKind(materialized=True) |
| 11835 | + "db.table", |
| 11836 | + parse_one("SELECT 1 AS id"), |
| 11837 | + kind="FULL", |
| 11838 | + grants={ |
| 11839 | + "select": ["user1", "user2"], |
| 11840 | + "insert": ["admin"], |
| 11841 | + "roles/bigquery.dataViewer": ["user:data_eng@company.com"], |
| 11842 | + }, |
11706 | 11843 | ) |
11707 | | - assert model.grants_table_type == DataObjectType.MATERIALIZED_VIEW |
11708 | | - |
11709 | | - |
11710 | | -def test_grants_table_type_table(): |
11711 | | - model = create_sql_model("test_table", parse_one("SELECT 1 as id"), kind="FULL") |
11712 | | - assert model.grants_table_type == DataObjectType.TABLE |
| 11844 | + assert model.grants == { |
| 11845 | + "select": ["user1", "user2"], |
| 11846 | + "insert": ["admin"], |
| 11847 | + "roles/bigquery.dataViewer": ["user:data_eng@company.com"], |
| 11848 | + } |
11713 | 11849 |
|
11714 | 11850 |
|
11715 | | -def test_grants_table_type_managed(): |
11716 | | - model = create_sql_model("test_managed", parse_one("SELECT 1 as id"), kind="MANAGED") |
11717 | | - assert model.grants_table_type == DataObjectType.MANAGED_TABLE |
| 11851 | +@pytest.mark.parametrize( |
| 11852 | + "kind, expected", |
| 11853 | + [ |
| 11854 | + ("VIEW", DataObjectType.VIEW), |
| 11855 | + ("FULL", DataObjectType.TABLE), |
| 11856 | + ("MANAGED", DataObjectType.MANAGED_TABLE), |
| 11857 | + (ViewKind(materialized=True), DataObjectType.MATERIALIZED_VIEW), |
| 11858 | + ], |
| 11859 | +) |
| 11860 | +def test_grants_table_type(kind: t.Union[str, _ModelKind], expected: DataObjectType): |
| 11861 | + model = create_sql_model("test_table", parse_one("SELECT 1 as id"), kind=kind) |
| 11862 | + assert model.grants_table_type == expected |
0 commit comments