Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
nevdelap committed Jun 4, 2024
2 parents 7566cb2 + a34267f commit 70da1b8
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 204 deletions.
3 changes: 3 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Documentation
url: https://github.com/dbt-labs/docs.getdbt.com/issues/new/choose
about: Problems and issues with dbt documentation
- name: Ask the community for help
url: https://github.com/dbt-labs/docs.getdbt.com/discussions
about: Need help troubleshooting? Check out our guide on how to ask
Expand Down
51 changes: 50 additions & 1 deletion tests/functional/basic/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import pytest
import yaml

from dbt.exceptions import ProjectContractError
from dbt.cli.main import dbtRunner
from dbt.exceptions import DbtProjectError, ProjectContractError
from dbt.tests.util import run_dbt, update_config_file, write_config_file

simple_model_sql = """
Expand Down Expand Up @@ -118,3 +119,51 @@ def test_dbt_cloud_invalid(self, project):
with pytest.raises(ProjectContractError) as excinfo:
run_dbt()
assert expected_err in str(excinfo.value)


class TestVersionSpecifierChecksComeBeforeYamlValidation:
def test_version_specifier_checks_before_yaml_validation(self, project) -> None:
runner = dbtRunner()

# if no version specifier error, we should get a yaml validation error
config_update = {"this-is-not-a-valid-key": "my-value-for-invalid-key"}
update_config_file(config_update, "dbt_project.yml")
result = runner.invoke(["parse"])
assert result.exception is not None
assert isinstance(result.exception, ProjectContractError)
assert "Additional properties are not allowed" in str(result.exception)

# add bad version specifier, and assert we get the error for that
update_config_file({"require-dbt-version": [">0.0.0", "<=0.0.1"]}, "dbt_project.yml")
result = runner.invoke(["parse"])
assert result.exception is not None
assert isinstance(result.exception, DbtProjectError)
assert "This version of dbt is not supported"


class TestArchiveNotAllowed:
"""At one point in time we supported an 'archive' key in projects, but no longer"""

def test_archive_not_allowed(self, project):
runner = dbtRunner()

config_update = {
"archive": {
"source_schema": "a",
"target_schema": "b",
"tables": [
{
"source_table": "seed",
"target_table": "archive_actual",
"updated_at": "updated_at",
"unique_key": """id || '-' || first_name""",
},
],
}
}
update_config_file(config_update, "dbt_project.yml")

result = runner.invoke(["parse"])
assert result.exception is not None
assert isinstance(result.exception, ProjectContractError)
assert "Additional properties are not allowed" in str(result.exception)
55 changes: 53 additions & 2 deletions tests/unit/config/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import unittest
from copy import deepcopy
from typing import Any, Dict
from unittest import mock

import pytest
Expand All @@ -10,7 +11,7 @@
import dbt.exceptions
from dbt.adapters.contracts.connection import DEFAULT_QUERY_COMMENT, QueryComment
from dbt.adapters.factory import load_plugin
from dbt.config.project import Project
from dbt.config.project import Project, _get_required_version
from dbt.constants import DEPENDENCIES_FILE_NAME
from dbt.contracts.project import GitPackage, LocalPackage, PackageConfig
from dbt.flags import set_from_args
Expand Down Expand Up @@ -42,7 +43,7 @@ def test_fixture_paths(self, project: Project):
def test__str__(self, project: Project):
assert (
str(project)
== "{'name': 'test_project', 'version': 1.0, 'project-root': 'doesnt/actually/exist', 'profile': 'test_profile', 'model-paths': ['models'], 'macro-paths': ['macros'], 'seed-paths': ['seeds'], 'test-paths': ['tests'], 'analysis-paths': ['analyses'], 'docs-paths': ['docs'], 'asset-paths': ['assets'], 'target-path': 'target', 'snapshot-paths': ['snapshots'], 'clean-targets': ['target'], 'log-path': 'path/to/project/logs', 'quoting': {'database': True, 'schema': True, 'identifier': True}, 'models': {}, 'on-run-start': [], 'on-run-end': [], 'dispatch': [{'macro_namespace': 'dbt_utils', 'search_order': ['test_project', 'dbt_utils']}], 'seeds': {}, 'snapshots': {}, 'sources': {}, 'data_tests': {}, 'unit_tests': {}, 'metrics': {}, 'semantic-models': {}, 'saved-queries': {}, 'exposures': {}, 'vars': {}, 'require-dbt-version': ['=0.0.0'], 'restrict-access': False, 'dbt-cloud': {}, 'query-comment': {'comment': \"\\n{%- set comment_dict = {} -%}\\n{%- do comment_dict.update(\\n app='dbt',\\n dbt_version=dbt_version,\\n profile_name=target.get('profile_name'),\\n target_name=target.get('target_name'),\\n) -%}\\n{%- if node is not none -%}\\n {%- do comment_dict.update(\\n node_id=node.unique_id,\\n ) -%}\\n{% else %}\\n {# in the node context, the connection name is the node_id #}\\n {%- do comment_dict.update(connection_name=connection_name) -%}\\n{%- endif -%}\\n{{ return(tojson(comment_dict)) }}\\n\", 'append': False, 'job-label': False}, 'packages': []}"
== "{'name': 'test_project', 'version': 1.0, 'project-root': 'doesnt/actually/exist', 'profile': 'test_profile', 'model-paths': ['models'], 'macro-paths': ['macros'], 'seed-paths': ['seeds'], 'test-paths': ['tests'], 'analysis-paths': ['analyses'], 'docs-paths': ['docs'], 'asset-paths': ['assets'], 'target-path': 'target', 'snapshot-paths': ['snapshots'], 'clean-targets': ['target'], 'log-path': 'path/to/project/logs', 'quoting': {}, 'models': {}, 'on-run-start': [], 'on-run-end': [], 'dispatch': [{'macro_namespace': 'dbt_utils', 'search_order': ['test_project', 'dbt_utils']}], 'seeds': {}, 'snapshots': {}, 'sources': {}, 'data_tests': {}, 'unit_tests': {}, 'metrics': {}, 'semantic-models': {}, 'saved-queries': {}, 'exposures': {}, 'vars': {}, 'require-dbt-version': ['=0.0.0'], 'restrict-access': False, 'dbt-cloud': {}, 'query-comment': {'comment': \"\\n{%- set comment_dict = {} -%}\\n{%- do comment_dict.update(\\n app='dbt',\\n dbt_version=dbt_version,\\n profile_name=target.get('profile_name'),\\n target_name=target.get('target_name'),\\n) -%}\\n{%- if node is not none -%}\\n {%- do comment_dict.update(\\n node_id=node.unique_id,\\n ) -%}\\n{% else %}\\n {# in the node context, the connection name is the node_id #}\\n {%- do comment_dict.update(connection_name=connection_name) -%}\\n{%- endif -%}\\n{{ return(tojson(comment_dict)) }}\\n\", 'append': False, 'job-label': False}, 'packages': []}"
)

def test_get_selector(self, project: Project):
Expand Down Expand Up @@ -534,3 +535,53 @@ def setUp(self):
def test_setting_multiple_flags(self):
with pytest.raises(dbt.exceptions.DbtProjectError):
set_from_args(self.args, None)


class TestGetRequiredVersion:
@pytest.fixture
def project_dict(self) -> Dict[str, Any]:
return {
"name": "test_project",
"require-dbt-version": ">0.0.0",
}

def test_supported_version(self, project_dict: Dict[str, Any]) -> None:
specifiers = _get_required_version(project_dict=project_dict, verify_version=True)
assert set(x.to_version_string() for x in specifiers) == {">0.0.0"}

def test_unsupported_version(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = ">99999.0.0"
with pytest.raises(
dbt.exceptions.DbtProjectError, match="This version of dbt is not supported"
):
_get_required_version(project_dict=project_dict, verify_version=True)

def test_unsupported_version_no_check(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = ">99999.0.0"
specifiers = _get_required_version(project_dict=project_dict, verify_version=False)
assert set(x.to_version_string() for x in specifiers) == {">99999.0.0"}

def test_supported_version_range(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = [">0.0.0", "<=99999.0.0"]
specifiers = _get_required_version(project_dict=project_dict, verify_version=True)
assert set(x.to_version_string() for x in specifiers) == {">0.0.0", "<=99999.0.0"}

def test_unsupported_version_range(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = [">0.0.0", "<=0.0.1"]
with pytest.raises(
dbt.exceptions.DbtProjectError, match="This version of dbt is not supported"
):
_get_required_version(project_dict=project_dict, verify_version=True)

def test_unsupported_version_range_no_check(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = [">0.0.0", "<=0.0.1"]
specifiers = _get_required_version(project_dict=project_dict, verify_version=False)
assert set(x.to_version_string() for x in specifiers) == {">0.0.0", "<=0.0.1"}

def test_impossible_version_range(self, project_dict: Dict[str, Any]) -> None:
project_dict["require-dbt-version"] = [">99999.0.0", "<=0.0.1"]
with pytest.raises(
dbt.exceptions.DbtProjectError,
match="The package version requirement can never be satisfied",
):
_get_required_version(project_dict=project_dict, verify_version=True)
Loading

0 comments on commit 70da1b8

Please sign in to comment.