diff --git a/dbt_subprojects/tokens/dbt_project.yml b/dbt_subprojects/tokens/dbt_project.yml index 9ec35c4c768..c36b4e7950f 100644 --- a/dbt_subprojects/tokens/dbt_project.yml +++ b/dbt_subprojects/tokens/dbt_project.yml @@ -23,7 +23,7 @@ vars: # These configurations specify where dbt should look for different types of files. # You don't need to change these! model-paths: ["models", "../../sources"] -# test-paths: ["tests"] +test-paths: ["tests"] # seed-paths: ["seeds"] macro-paths: ["macros", "../../dbt_macros"] diff --git a/dbt_subprojects/tokens/models/prices/_schema.yml b/dbt_subprojects/tokens/models/prices/_schema.yml index 3e50acf4bd5..1826a016c25 100644 --- a/dbt_subprojects/tokens/models/prices/_schema.yml +++ b/dbt_subprojects/tokens/models/prices/_schema.yml @@ -34,6 +34,12 @@ models: contributors: couralex, jeff-dude, 0xRob config: tags: [ 'prices', 'daily'] + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - blockchain + - contract_address + - timestamp - name: prices_hour meta: @@ -68,6 +74,12 @@ models: contributors: couralex, jeff-dude, 0xRob config: tags: [ 'prices', 'hourly'] + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - blockchain + - contract_address + - timestamp - name: prices_minute meta: @@ -102,6 +114,12 @@ models: contributors: couralex, jeff-dude, 0xRob config: tags: [ 'prices', 'minute'] + data_tests: + - dbt_utils.unique_combination_of_columns: + combination_of_columns: + - blockchain + - contract_address + - timestamp - name: prices_solana_hour meta: diff --git a/dbt_subprojects/tokens/tests/assert_no_missing_prices_day.sql b/dbt_subprojects/tokens/tests/assert_no_missing_prices_day.sql new file mode 100644 index 00000000000..12aec18a991 --- /dev/null +++ b/dbt_subprojects/tokens/tests/assert_no_missing_prices_day.sql @@ -0,0 +1,28 @@ +WITH token_time_range AS ( + SELECT + blockchain, + contract_address, + symbol, + DATE(MIN(timestamp)) AS min_date, + DATE(MAX(timestamp)) AS max_date + FROM {{ ref('prices_day') }} + GROUP BY blockchain, contract_address, symbol +), +all_days AS ( + SELECT DISTINCT DATE(timestamp) AS date + FROM {{ ref('prices_day') }} +) +SELECT + ad.date AS missing_date, + ttr.blockchain, + ttr.contract_address, + ttr.symbol +FROM token_time_range ttr +CROSS JOIN all_days ad +LEFT JOIN {{ ref('prices_day') }} p ON ad.date = DATE(p.timestamp) + AND ttr.blockchain = p.blockchain + AND ttr.contract_address = p.contract_address + AND ttr.symbol = p.symbol +WHERE p.timestamp IS NULL + AND ad.date BETWEEN ttr.min_date AND ttr.max_date + diff --git a/dbt_subprojects/tokens/tests/assert_no_missing_prices_hour.sql b/dbt_subprojects/tokens/tests/assert_no_missing_prices_hour.sql new file mode 100644 index 00000000000..05a7dd84f1d --- /dev/null +++ b/dbt_subprojects/tokens/tests/assert_no_missing_prices_hour.sql @@ -0,0 +1,28 @@ +WITH token_time_range AS ( + SELECT + blockchain, + contract_address, + symbol, + MIN(timestamp) AS min_timestamp, + MAX(timestamp) AS max_timestamp + FROM {{ ref('prices_hour') }} + GROUP BY blockchain, contract_address, symbol +), +all_hours AS ( + SELECT DISTINCT timestamp + FROM {{ ref('prices_hour') }} +) +SELECT + ah.timestamp AS missing_hour, + ttr.blockchain, + ttr.contract_address, + ttr.symbol +FROM token_time_range ttr +CROSS JOIN all_hours ah +LEFT JOIN {{ ref('prices_hour') }} p ON ah.timestamp = p.timestamp + AND ttr.blockchain = p.blockchain + AND ttr.contract_address = p.contract_address + AND ttr.symbol = p.symbol +WHERE p.timestamp IS NULL + AND ah.timestamp BETWEEN ttr.min_timestamp AND ttr.max_timestamp + diff --git a/dbt_subprojects/tokens/tests/assert_no_missing_prices_minute.sql b/dbt_subprojects/tokens/tests/assert_no_missing_prices_minute.sql new file mode 100644 index 00000000000..1743df8e41e --- /dev/null +++ b/dbt_subprojects/tokens/tests/assert_no_missing_prices_minute.sql @@ -0,0 +1,28 @@ +WITH token_time_range AS ( + SELECT + blockchain, + contract_address, + symbol, + MIN(timestamp) AS min_timestamp, + MAX(timestamp) AS max_timestamp + FROM {{ ref('prices_minute') }} + GROUP BY blockchain, contract_address, symbol +), +all_minutes AS ( + SELECT DISTINCT timestamp + FROM {{ ref('prices_minute') }} +) +SELECT + am.timestamp AS missing_minute, + ttr.blockchain, + ttr.contract_address, + ttr.symbol +FROM token_time_range ttr +CROSS JOIN all_minutes am +LEFT JOIN {{ ref('prices_minute') }} p ON am.timestamp = p.timestamp + AND ttr.blockchain = p.blockchain + AND ttr.contract_address = p.contract_address + AND ttr.symbol = p.symbol +WHERE p.timestamp IS NULL + AND am.timestamp BETWEEN ttr.min_timestamp AND ttr.max_timestamp + diff --git a/dbt_subprojects/tokens/tests/schema.yml b/dbt_subprojects/tokens/tests/schema.yml new file mode 100644 index 00000000000..66882a1e5ab --- /dev/null +++ b/dbt_subprojects/tokens/tests/schema.yml @@ -0,0 +1,20 @@ +version: 2 + +data_tests: + - name: assert_no_missing_price_day + description: > + Ensure that there are no missing prices for each token on each day + severity: error + tags: [ 'data_test', 'daily'] + + - name: assert_no_missing_price_hour + description: > + Ensure that there are no missing prices for each token on each hour + severity: error + tags: [ 'data_test', 'hourly'] + + - name: assert_no_missing_price_minute + description: > + Ensure that there are no missing prices for each token on each minute + severity: error + tags: [ 'data_test', 'minute']