|
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 |
@@ -11715,90 +11715,235 @@ def test_use_original_sql(): |
11715 | 11715 | assert model.post_statements_[0].sql == "CREATE TABLE post (b INT)" |
11716 | 11716 |
|
11717 | 11717 |
|
11718 | | -def test_grants_validation_symbolic_model_error(): |
11719 | | - with pytest.raises(ValidationError, match=r".*grants cannot be set for EXTERNAL.*"): |
11720 | | - create_sql_model( |
11721 | | - "db.table", |
11722 | | - parse_one("SELECT 1 AS id"), |
11723 | | - kind="EXTERNAL", |
11724 | | - grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
11725 | | - ) |
| 11718 | +@pytest.mark.parametrize( |
| 11719 | + "kind", |
| 11720 | + [ |
| 11721 | + "FULL", |
| 11722 | + "VIEW", |
| 11723 | + SeedKind(path="test.csv"), |
| 11724 | + IncrementalByTimeRangeKind(time_column="ds"), |
| 11725 | + IncrementalByUniqueKeyKind(unique_key="id"), |
| 11726 | + ], |
| 11727 | +) |
| 11728 | +def test_grants_valid_model_kinds(kind: t.Union[str, _ModelKind]): |
| 11729 | + model = create_sql_model( |
| 11730 | + "db.table", |
| 11731 | + parse_one("SELECT 1 AS id"), |
| 11732 | + kind=kind, |
| 11733 | + grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
| 11734 | + ) |
| 11735 | + assert model.grants == {"select": ["user1", "user2"], "insert": ["admin_user"]} |
11726 | 11736 |
|
11727 | 11737 |
|
11728 | | -def test_grants_validation_embedded_model_error(): |
11729 | | - with pytest.raises(ValidationError, match=r".*grants cannot be set for EMBEDDED.*"): |
| 11738 | +@pytest.mark.parametrize( |
| 11739 | + "kind", |
| 11740 | + [ |
| 11741 | + "EXTERNAL", |
| 11742 | + "EMBEDDED", |
| 11743 | + ], |
| 11744 | +) |
| 11745 | +def test_grants_invalid_model_kind_errors(kind: str): |
| 11746 | + with pytest.raises(ValidationError, match=rf".*grants cannot be set for {kind}.*"): |
11730 | 11747 | create_sql_model( |
11731 | 11748 | "db.table", |
11732 | 11749 | parse_one("SELECT 1 AS id"), |
11733 | | - kind="EMBEDDED", |
| 11750 | + kind=kind, |
11734 | 11751 | grants={"select": ["user1"], "insert": ["admin_user"]}, |
11735 | 11752 | ) |
11736 | 11753 |
|
11737 | 11754 |
|
11738 | | -def test_grants_validation_valid_seed_model(): |
| 11755 | +def test_grants_validation_no_grants(): |
| 11756 | + model = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
| 11757 | + assert model.grants is None |
| 11758 | + |
| 11759 | + |
| 11760 | +def test_grants_validation_empty_grantees(): |
11739 | 11761 | model = create_sql_model( |
11740 | | - "db.table", |
11741 | | - parse_one("SELECT 1 AS id"), |
11742 | | - kind=SeedKind(path="test.csv"), |
11743 | | - grants={"select": ["user1"], "insert": ["admin_user"]}, |
| 11762 | + "db.table", parse_one("SELECT 1 AS id"), kind="FULL", grants={"select": []} |
11744 | 11763 | ) |
11745 | | - assert model.grants == {"select": ["user1"], "insert": ["admin_user"]} |
| 11764 | + assert model.grants == {"select": []} |
11746 | 11765 |
|
11747 | 11766 |
|
11748 | | -def test_grants_validation_valid_materialized_model(): |
| 11767 | +def test_grants_single_value_conversions(): |
| 11768 | + expressions = d.parse(f""" |
| 11769 | + MODEL ( |
| 11770 | + name test.nested_arrays, |
| 11771 | + kind FULL, |
| 11772 | + grants ( |
| 11773 | + 'select' = "user1", update = user2 |
| 11774 | + ) |
| 11775 | + ); |
| 11776 | + SELECT 1 as id |
| 11777 | + """) |
| 11778 | + model = load_sql_based_model(expressions) |
| 11779 | + assert model.grants == {"select": ["user1"], "update": ["user2"]} |
| 11780 | + |
11749 | 11781 | model = create_sql_model( |
11750 | 11782 | "db.table", |
11751 | 11783 | parse_one("SELECT 1 AS id"), |
11752 | 11784 | kind="FULL", |
11753 | | - grants={"select": ["user1", "user2"], "insert": ["admin_user"]}, |
| 11785 | + grants={"select": "user1", "insert": 123}, |
11754 | 11786 | ) |
11755 | | - assert model.grants == {"select": ["user1", "user2"], "insert": ["admin_user"]} |
| 11787 | + assert model.grants == {"select": ["user1"], "insert": ["123"]} |
11756 | 11788 |
|
11757 | 11789 |
|
11758 | | -def test_grants_validation_valid_view_model(): |
11759 | | - model = create_sql_model( |
11760 | | - "db.table", parse_one("SELECT 1 AS id"), kind="VIEW", grants={"select": ["user1", "user2"]} |
| 11790 | +@pytest.mark.parametrize( |
| 11791 | + "grantees", |
| 11792 | + [ |
| 11793 | + "('user1', ('user2', 'user3'), 'user4')", |
| 11794 | + "('user1', ['user2', 'user3'], user4)", |
| 11795 | + "['user1', ['user2', user3], 'user4']", |
| 11796 | + "[user1, ('user2', \"user3\"), 'user4']", |
| 11797 | + ], |
| 11798 | +) |
| 11799 | +def test_grants_array_flattening(grantees: str): |
| 11800 | + expressions = d.parse(f""" |
| 11801 | + MODEL ( |
| 11802 | + name test.nested_arrays, |
| 11803 | + kind FULL, |
| 11804 | + grants ( |
| 11805 | + 'select' = {grantees} |
| 11806 | + ) |
| 11807 | + ); |
| 11808 | + SELECT 1 as id |
| 11809 | + """) |
| 11810 | + model = load_sql_based_model(expressions) |
| 11811 | + assert model.grants == {"select": ["user1", "user2", "user3", "user4"]} |
| 11812 | + |
| 11813 | + |
| 11814 | +def test_grants_macro_var_resolved(): |
| 11815 | + expressions = d.parse(""" |
| 11816 | + MODEL ( |
| 11817 | + name test.macro_grants, |
| 11818 | + kind FULL, |
| 11819 | + grants ( |
| 11820 | + 'select' = @VAR('readers'), |
| 11821 | + 'insert' = @VAR('writers') |
| 11822 | + ) |
| 11823 | + ); |
| 11824 | + SELECT 1 as id |
| 11825 | + """) |
| 11826 | + model = load_sql_based_model( |
| 11827 | + expressions, variables={"readers": ["user1", "user2"], "writers": "admin"} |
11761 | 11828 | ) |
11762 | | - assert model.grants == {"select": ["user1", "user2"]} |
| 11829 | + assert model.grants == { |
| 11830 | + "select": ["user1", "user2"], |
| 11831 | + "insert": ["admin"], |
| 11832 | + } |
11763 | 11833 |
|
11764 | 11834 |
|
11765 | | -def test_grants_validation_valid_incremental_model(): |
11766 | | - model = create_sql_model( |
11767 | | - "db.table", |
11768 | | - parse_one("SELECT 1 AS id, CURRENT_TIMESTAMP AS ts"), |
11769 | | - kind=IncrementalByTimeRangeKind(time_column="ts"), |
11770 | | - grants={"select": ["user1"], "update": ["admin_user"]}, |
| 11835 | +def test_grants_macro_var_in_array_flattening(): |
| 11836 | + expressions = d.parse(""" |
| 11837 | + MODEL ( |
| 11838 | + name test.macro_in_array, |
| 11839 | + kind FULL, |
| 11840 | + grants ( |
| 11841 | + 'select' = ['user1', @VAR('admins'), 'user3'] |
| 11842 | + ) |
| 11843 | + ); |
| 11844 | + SELECT 1 as id |
| 11845 | + """) |
| 11846 | + |
| 11847 | + model = load_sql_based_model(expressions, variables={"admins": ["admin1", "admin2"]}) |
| 11848 | + assert model.grants == {"select": ["user1", "admin1", "admin2", "user3"]} |
| 11849 | + |
| 11850 | + model2 = load_sql_based_model(expressions, variables={"admins": "super_admin"}) |
| 11851 | + assert model2.grants == {"select": ["user1", "super_admin", "user3"]} |
| 11852 | + |
| 11853 | + |
| 11854 | +def test_grants_dynamic_permission_names(): |
| 11855 | + expressions = d.parse(""" |
| 11856 | + MODEL ( |
| 11857 | + name test.dynamic_keys, |
| 11858 | + kind FULL, |
| 11859 | + grants ( |
| 11860 | + @VAR('read_perm') = ['user1', 'user2'], |
| 11861 | + @VAR('write_perm') = ['admin'] |
| 11862 | + ) |
| 11863 | + ); |
| 11864 | + SELECT 1 as id |
| 11865 | + """) |
| 11866 | + model = load_sql_based_model( |
| 11867 | + expressions, variables={"read_perm": "select", "write_perm": "insert"} |
11771 | 11868 | ) |
11772 | | - assert model.grants == {"select": ["user1"], "update": ["admin_user"]} |
| 11869 | + assert model.grants == {"select": ["user1", "user2"], "insert": ["admin"]} |
11773 | 11870 |
|
11774 | 11871 |
|
11775 | | -def test_grants_validation_no_grants(): |
11776 | | - model = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
11777 | | - assert model.grants is None |
| 11872 | +def test_grants_unresolved_macro_errors(): |
| 11873 | + expressions1 = d.parse(""" |
| 11874 | + MODEL (name test.bad1, kind FULL, grants ('select' = @VAR('undefined'))); |
| 11875 | + SELECT 1 as id |
| 11876 | + """) |
| 11877 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration for 'select': NULL value"): |
| 11878 | + load_sql_based_model(expressions1) |
11778 | 11879 |
|
| 11880 | + expressions2 = d.parse(""" |
| 11881 | + MODEL (name test.bad2, kind FULL, grants (@VAR('undefined') = ['user'])); |
| 11882 | + SELECT 1 as id |
| 11883 | + """) |
| 11884 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration.*NULL value"): |
| 11885 | + load_sql_based_model(expressions2) |
11779 | 11886 |
|
11780 | | -def test_grants_validation_empty_grantees(): |
11781 | | - model = create_sql_model( |
| 11887 | + expressions3 = d.parse(""" |
| 11888 | + MODEL (name test.bad3, kind FULL, grants ('select' = ['user', @VAR('undefined')])); |
| 11889 | + SELECT 1 as id |
| 11890 | + """) |
| 11891 | + with pytest.raises(ConfigError, match=r"Invalid grants configuration for 'select': NULL value"): |
| 11892 | + load_sql_based_model(expressions3) |
| 11893 | + |
| 11894 | + |
| 11895 | +def test_grants_mixed_types_conversion(): |
| 11896 | + expressions = d.parse(""" |
| 11897 | + MODEL ( |
| 11898 | + name test.mixed_types, |
| 11899 | + kind FULL, |
| 11900 | + grants ( |
| 11901 | + 'select' = ['user1', 123, admin_role, 'user2'] |
| 11902 | + ) |
| 11903 | + ); |
| 11904 | + SELECT 1 as id |
| 11905 | + """) |
| 11906 | + model = load_sql_based_model(expressions) |
| 11907 | + assert model.grants == {"select": ["user1", "123", "admin_role", "user2"]} |
| 11908 | + |
| 11909 | + |
| 11910 | +def test_grants_empty_values(): |
| 11911 | + model1 = create_sql_model( |
11782 | 11912 | "db.table", parse_one("SELECT 1 AS id"), kind="FULL", grants={"select": []} |
11783 | 11913 | ) |
11784 | | - assert model.grants == {"select": []} |
| 11914 | + assert model1.grants == {"select": []} |
11785 | 11915 |
|
| 11916 | + model2 = create_sql_model("db.table", parse_one("SELECT 1 AS id"), kind="FULL") |
| 11917 | + assert model2.grants is None |
11786 | 11918 |
|
11787 | | -def test_grants_table_type_view(): |
11788 | | - model = create_sql_model("test_view", parse_one("SELECT 1 as id"), kind="VIEW") |
11789 | | - assert model.grants_table_type == DataObjectType.VIEW |
11790 | 11919 |
|
| 11920 | +def test_grants_backward_compatibility(): |
11791 | 11921 | model = create_sql_model( |
11792 | | - "test_mv", parse_one("SELECT 1 as id"), kind=ViewKind(materialized=True) |
| 11922 | + "db.table", |
| 11923 | + parse_one("SELECT 1 AS id"), |
| 11924 | + kind="FULL", |
| 11925 | + grants={ |
| 11926 | + "select": ["user1", "user2"], |
| 11927 | + "insert": ["admin"], |
| 11928 | + "roles/bigquery.dataViewer": ["user:data_eng@company.com"], |
| 11929 | + }, |
11793 | 11930 | ) |
11794 | | - assert model.grants_table_type == DataObjectType.MATERIALIZED_VIEW |
11795 | | - |
11796 | | - |
11797 | | -def test_grants_table_type_table(): |
11798 | | - model = create_sql_model("test_table", parse_one("SELECT 1 as id"), kind="FULL") |
11799 | | - assert model.grants_table_type == DataObjectType.TABLE |
| 11931 | + assert model.grants == { |
| 11932 | + "select": ["user1", "user2"], |
| 11933 | + "insert": ["admin"], |
| 11934 | + "roles/bigquery.dataViewer": ["user:data_eng@company.com"], |
| 11935 | + } |
11800 | 11936 |
|
11801 | 11937 |
|
11802 | | -def test_grants_table_type_managed(): |
11803 | | - model = create_sql_model("test_managed", parse_one("SELECT 1 as id"), kind="MANAGED") |
11804 | | - assert model.grants_table_type == DataObjectType.MANAGED_TABLE |
| 11938 | +@pytest.mark.parametrize( |
| 11939 | + "kind, expected", |
| 11940 | + [ |
| 11941 | + ("VIEW", DataObjectType.VIEW), |
| 11942 | + ("FULL", DataObjectType.TABLE), |
| 11943 | + ("MANAGED", DataObjectType.MANAGED_TABLE), |
| 11944 | + (ViewKind(materialized=True), DataObjectType.MATERIALIZED_VIEW), |
| 11945 | + ], |
| 11946 | +) |
| 11947 | +def test_grants_table_type(kind: t.Union[str, _ModelKind], expected: DataObjectType): |
| 11948 | + model = create_sql_model("test_table", parse_one("SELECT 1 as id"), kind=kind) |
| 11949 | + assert model.grants_table_type == expected |
0 commit comments