Skip to content

Commit 8db9f3c

Browse files
committed
feat: Add tests
1 parent bb7a6f7 commit 8db9f3c

File tree

3 files changed

+152
-6
lines changed

3 files changed

+152
-6
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ your_profile_name:
120120
| query_settings | A map/dictionary of ClickHouse user level settings to be used with `INSERT` or `DELETE` statements in conjunction with this model | |
121121
| ttl | A TTL expression to be used with the table. The TTL expression is a string that can be used to specify the TTL for the table. | |
122122
| indexes | A list of indexes to create, available only for `table` materialization. For examples look at ([#397](https://github.com/ClickHouse/dbt-clickhouse/pull/397)) | |
123-
| sql_security | Allow you to specify which ClickHouse user to use when executing the view's underlying query. `SQL SECURITY` has three legal values: `DEFINER``INVOKER`, or `NONE`. | |
124-
| definer | If `sql_security` was set to `DEFINER`, you have to specify any existing user or `CURRENT_USER` in the `DEFINER` clause. | |
123+
| sql_security | Allow you to specify which ClickHouse user to use when executing the view's underlying query. [`SQL SECURITY`](https://clickhouse.com/docs/sql-reference/statements/create/view#sql_security) has two legal values: `definer``invoker`. | |
124+
| definer | If `sql_security` was set to `definer`, you have to specify any existing user or `CURRENT_USER` in the `definer` clause. | |
125125
| | | |
126126

127127

dbt/include/clickhouse/macros/materializations/view.sql

+2-4
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,9 @@
4747
{%- endif %}
4848
DEFINER = {{ definer }} SQL SECURITY DEFINER
4949
{%- elif sql_security == 'invoker' %}
50-
SQL SECURITY INVOKER
51-
{%- elif sql_security == 'none' %}
52-
SQL SECURITY NONE
50+
SQL SECURITY INVOKER
5351
{%- else %}
54-
{{ exceptions.raise_compiler_error("Invalid config parameter `sql_security`. Got: `" + sql_security + "`, but only definer | invoker | none allowed.") }}
52+
{{ exceptions.raise_compiler_error("Invalid config parameter `sql_security`. Got: `" + sql_security + "`, but only definer | invoker allowed.") }}
5553
{%- endif %}
5654
{%- endif %}
5755
{%- endmacro -%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"""
2+
Test ClickHouse view with sql security settings in dbt-clickhouse
3+
"""
4+
5+
import pytest
6+
from dbt.tests.util import run_dbt, run_dbt_and_capture
7+
8+
PEOPLE_SEED_CSV = """
9+
id,name,age,department
10+
1231,Dade,33,engineering
11+
6666,Ksenia,48,engineering
12+
8888,Kate,50,engineering
13+
""".lstrip()
14+
15+
SEED_SCHEMA_YML = """
16+
version: 2
17+
18+
sources:
19+
- name: raw
20+
schema: "{{ target.schema }}"
21+
tables:
22+
- name: people
23+
"""
24+
25+
PEOPLE_VIEW_CONFIG = """
26+
{{ config(
27+
materialized='view',
28+
sql_security='invoker'
29+
) }}
30+
"""
31+
32+
PEOPLE_VIEW_CONFIG_2 = """
33+
{{ config(
34+
materialized='view',
35+
sql_security='definer',
36+
definer='admin'
37+
) }}
38+
"""
39+
40+
PEOPLE_VIEW_CONFIG_3 = """
41+
{{ config(
42+
materialized='view',
43+
sql_security='definer'
44+
) }}
45+
"""
46+
47+
PEOPLE_VIEW_CONFIG_4 = """
48+
{{ config(
49+
materialized='view',
50+
sql_security='definer',
51+
definer=''
52+
) }}
53+
"""
54+
55+
PEOPLE_VIEW_CONFIG_5 = """
56+
{{ config(
57+
materialized='view',
58+
sql_security='wrong'
59+
) }}
60+
"""
61+
62+
PEOPLE_VIEW_MODEL = """
63+
select
64+
id,
65+
name,
66+
age,
67+
department
68+
from {{ source('raw', 'people') }}
69+
"""
70+
71+
72+
73+
class TestClickHouseViewSqlSecurity:
74+
@pytest.fixture(scope="class")
75+
def seeds(self):
76+
return {
77+
"people.csv": PEOPLE_SEED_CSV,
78+
"schema.yml": SEED_SCHEMA_YML,
79+
}
80+
81+
@pytest.fixture(scope="class")
82+
def models(self):
83+
return {
84+
"view_invoker.sql": PEOPLE_VIEW_CONFIG + PEOPLE_VIEW_MODEL,
85+
"view_definer.sql": PEOPLE_VIEW_CONFIG_2 + PEOPLE_VIEW_MODEL,
86+
"view_definer_empty.sql": PEOPLE_VIEW_CONFIG_3 + PEOPLE_VIEW_MODEL,
87+
"view_definer_wrong.sql": PEOPLE_VIEW_CONFIG_4 + PEOPLE_VIEW_MODEL,
88+
"view_sql_security.sql": PEOPLE_VIEW_CONFIG_5 + PEOPLE_VIEW_MODEL,
89+
}
90+
91+
def test_create_view_invoker(self, project):
92+
# Load seed data
93+
run_dbt(["seed"])
94+
95+
# Run dbt to create the view
96+
run_dbt(["run", "--select", "view_invoker"])
97+
98+
# Query system table to be sure that view query contains desired statement
99+
result = project.run_sql(
100+
"""select 1 from system.tables
101+
where table = 'view_invoker'
102+
and position(create_table_query, 'SQL SECURITY INVOKER') > 0""", fetch="one")
103+
assert result[0] == 1 # 1 records in the seed data
104+
105+
def test_create_view_definer(self, project):
106+
# Load seed data
107+
run_dbt(["seed"])
108+
109+
# Run dbt to create the view
110+
run_dbt(["run", "--select", "view_definer"])
111+
112+
# Query system table to be sure that view query contains desired statement
113+
result = project.run_sql(
114+
"""select 1 from system.tables
115+
where table = 'view_definer'
116+
and position(create_table_query, 'DEFINER = admin SQL SECURITY DEFINER') > 0""", fetch="one")
117+
assert result[0] == 1 # 3 records in the seed data
118+
119+
def test_fail_view_definer_emty(self, project):
120+
# Load seed data
121+
run_dbt(["seed"])
122+
123+
# Run dbt to create the view
124+
_, stdout = run_dbt_and_capture(["run", "--select", "view_definer_empty"], expect_pass=False)
125+
126+
# Confirm that stdout/console output has error description
127+
assert "Model 'model.test.view_definer_empty' does not define a required config parameter 'definer'." in stdout
128+
129+
def test_fail_view_definer_wrong(self, project):
130+
# Load seed data
131+
run_dbt(["seed"])
132+
133+
# Run dbt to create the view
134+
_, stdout = run_dbt_and_capture(["run", "--select", "view_definer_wrong"], expect_pass=False)
135+
136+
# Confirm that stdout/console output has error description
137+
assert "Invalid config parameter `definer`. No value was provided." in stdout
138+
139+
def test_fail_view_sql_security(self, project):
140+
# Load seed data
141+
run_dbt(["seed"])
142+
143+
# Run dbt to create the view
144+
_, stdout = run_dbt_and_capture(["run", "--select", "view_sql_security"], expect_pass=False)
145+
146+
# Confirm that stdout/console output has error description
147+
assert "Invalid config parameter `sql_security`. Got: `wrong`, but only definer | invoker allowed." in stdout
148+

0 commit comments

Comments
 (0)