-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add generic test for exposure schema validation
- Loading branch information
erikzaadi
committed
Sep 11, 2023
1 parent
2ea1c6f
commit 40f34e0
Showing
3 changed files
with
137 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
from datetime import date, timedelta | ||
from typing import Any, Dict, List | ||
|
||
from data_generator import DATE_FORMAT, generate_dates | ||
from dbt_project import DbtProject | ||
|
||
DBT_TEST_NAME = "elementary.exposure_schema_validity" | ||
|
||
|
||
def test_expose_schema_validity_with_no_exposures(test_id: str, dbt_project: DbtProject): | ||
test_result = dbt_project.test(test_id, DBT_TEST_NAME, as_model=True) | ||
assert test_result["status"] == "pass" | ||
|
||
def test_expose_schema_validity_with_missing_columns(test_id: str, dbt_project: DbtProject): | ||
DBT_TEST_ARGS = { | ||
"exposures": { | ||
"ZOMG": { | ||
"meta": """{ | ||
"columns": [{ | ||
"name": "w00t", | ||
"data_type": "string" | ||
}] | ||
}""", | ||
"depends_on": { | ||
"nodes": [] | ||
} | ||
} | ||
} | ||
} | ||
test_result = dbt_project.test(test_id, DBT_TEST_NAME, DBT_TEST_ARGS, as_model=True) | ||
assert test_result["status"] == "fail" | ||
|
||
def test_expose_schema_validity_with_correct_columns_and_no_data_type(test_id: str, dbt_project: DbtProject): | ||
DBT_TEST_ARGS = { | ||
"exposures": { | ||
"ZOMG": { | ||
"meta": """{ | ||
"columns": [{ | ||
"name": "w00t", | ||
}] | ||
}""", | ||
"depends_on": { | ||
"nodes": [] | ||
} | ||
} | ||
} | ||
} | ||
test_result = dbt_project.test(test_id, DBT_TEST_NAME, DBT_TEST_ARGS, as_model=True) | ||
assert test_result["status"] == "fail" | ||
|
||
def test_expose_schema_validity_with_correct_columns_and_incompatible_data_type(test_id: str, dbt_project: DbtProject): | ||
DBT_TEST_ARGS = { | ||
"exposures": { | ||
"ZOMG": { | ||
"meta": """{ | ||
"columns": [{ | ||
"name": "w00t", | ||
}] | ||
}""", | ||
"depends_on": { | ||
"nodes": [] | ||
} | ||
} | ||
} | ||
} | ||
test_result = dbt_project.test(test_id, DBT_TEST_NAME, DBT_TEST_ARGS, as_model=True) | ||
assert test_result["status"] == "fail" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
{% test exposure_schema_validity(model, exposures=graph.exposures) %} | ||
{%- if not execute -%} | ||
{%- do return(none) -%} | ||
{%- endif -%} | ||
{%- set model_relation = elementary.get_model_relation_for_test(model, context["model"]) -%} | ||
{%- set full_table_name = elementary.relation_to_full_name(model_relation) -%} | ||
{{- elementary.test_log('start', full_table_name, 'exposure validation') -}} | ||
{%- set matching_exposures = [] -%} | ||
{%- for exposure in exposures.values() -%} | ||
{%- if context['model']['attached_node'] in exposure.depends_on.nodes and exposure['meta'] | default(none) is not none -%} | ||
{%- do matching_exposures.append(exposure) -%} | ||
{%- endif -%} | ||
{%- endfor -%} | ||
{%- set matching_exposures_len = matching_exposures | length -%} | ||
{%- if matching_exposures_len > 0 -%} | ||
{%- set columns_from_model = adapter.get_columns_in_relation(model) -%} | ||
{%- if not columns_from_model -%} | ||
{%- set table_name = elementary.relation_to_full_name(model) -%} | ||
{{- elementary.edr_log('Could not extract columns for table - ' ~ table_name ~ ' (might be a permissions issue)') -}} | ||
{{ return(none) }} | ||
{%- endif -%} | ||
{%- set columns_dict = {} -%} | ||
{%- if columns_from_model and columns_from_model is iterable -%} | ||
{%- for column in columns_from_model -%} | ||
{%- do columns_dict.update({ column['name']: elementary.normalize_data_type(column['dtype']) }) -%} | ||
{%- endfor -%} | ||
{%- endif -%} | ||
{%- set invalid_exposures = [] -%} | ||
{%- for exposure in matching_exposures -%} | ||
{# Depend on meta since column level info is not available on exposures #} | ||
{%- set meta = exposure['meta'] | default(none) -%} | ||
{%- if meta != none and meta['columns'] | default(none) is iterable -%} | ||
{%- for column in meta['columns'] -%} | ||
{%- if column['name'] | upper not in columns_dict.keys() -%} | ||
{%- do invalid_exposures.append({ | ||
'exposure': exposure.name, | ||
'url': exposure.url, | ||
'error': column['name'] ~ ' column missing in the model' | ||
}) | ||
-%} | ||
{%- elif column['data_type'] | default('') != '' and elementary.normalize_data_type(column['data_type']) != columns_dict[column['name'] | upper] -%} | ||
{%- do invalid_exposures.append({ | ||
'exposure': exposure.name, | ||
'url': exposure.url, | ||
'error': 'different data type for the column ' ~ column['name'] ~ ' ' ~ column['data_type'] ~ ' vs ' ~ columns_dict[column['name']] | ||
}) | ||
-%} | ||
{%- endif -%} | ||
{%- endfor -%} | ||
{%- endif -%} | ||
{%- endfor -%} | ||
{%- for invalid_exposure in invalid_exposures %} | ||
{{ 'UNION ALL ' if not loop.first }}SELECT '{{ invalid_exposure['exposure'] }}' as exposure, '{{ invalid_exposure['url'] }}' as url, '{{ invalid_exposure['error'] }}' as error | ||
{%- endfor -%} | ||
{{ elementary.test_log('end', full_table_name, 'exposure validation') }} | ||
{% if invalid_exposures | length == 0 %} | ||
{{ elementary.no_results_query() }} | ||
{% endif %} | ||
{%- else -%} | ||
{{ elementary.no_results_query() }} | ||
{%- endif -%} | ||
{% endtest %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters