diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index a3c42f9f8e8..b06dd39981e 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -5,6 +5,7 @@ from dbt.contracts.graph.nodes import SourceDefinition # All manifest related fixtures. +from tests.unit.utils.adapter import * # noqa from tests.unit.utils.manifest import * # noqa from tests.unit.utils.project import * # noqa diff --git a/tests/unit/parser/test_manifest.py b/tests/unit/parser/test_manifest.py index 9a84414a99e..b7d470a3552 100644 --- a/tests/unit/parser/test_manifest.py +++ b/tests/unit/parser/test_manifest.py @@ -2,25 +2,14 @@ from unittest.mock import MagicMock, patch import pytest +from pytest_mock import MockerFixture from dbt.config import RuntimeConfig from dbt.contracts.graph.manifest import Manifest from dbt.flags import set_from_args from dbt.parser.manifest import ManifestLoader - - -@pytest.fixture -def mock_project(): - mock_project = MagicMock(RuntimeConfig) - mock_project.cli_vars = {} - mock_project.args = MagicMock() - mock_project.args.profile = "test" - mock_project.args.target = "test" - mock_project.project_env_vars = {} - mock_project.profile_env_vars = {} - mock_project.project_target_path = "mock_target_path" - mock_project.credentials = MagicMock() - return mock_project +from dbt.parser.read_files import FileDiff +from dbt.tracking import User class TestPartialParse: @@ -91,3 +80,84 @@ def test_partial_parse_safe_update_project_parser_files_partially( assert "full_reparse_reason" in exc_info assert "KeyError: 'Whoopsie!'" == exc_info["exception"] assert isinstance(exc_info["code"], str) or isinstance(exc_info["code"], type(None)) + + +class TestGetFullManifest: + @pytest.fixture + def set_required_mocks( + self, mocker: MockerFixture, manifest: Manifest, mock_adapter: MagicMock + ): + mocker.patch("dbt.parser.manifest.get_adapter").return_value = mock_adapter + mocker.patch("dbt.parser.manifest.ManifestLoader.load").return_value = manifest + mocker.patch("dbt.parser.manifest._check_manifest").return_value = None + mocker.patch( + "dbt.parser.manifest.ManifestLoader.save_macros_to_adapter" + ).return_value = None + mocker.patch("dbt.tracking.active_user").return_value = User(None) + + def test_write_perf_info( + self, + mock_project: MagicMock, + mocker: MockerFixture, + set_required_mocks, + ) -> None: + write_perf_info = mocker.patch("dbt.parser.manifest.ManifestLoader.write_perf_info") + + ManifestLoader.get_full_manifest( + config=mock_project, + # write_perf_info=False let it default instead + ) + assert not write_perf_info.called + + ManifestLoader.get_full_manifest(config=mock_project, write_perf_info=False) + assert not write_perf_info.called + + ManifestLoader.get_full_manifest(config=mock_project, write_perf_info=True) + assert write_perf_info.called + + def test_reset( + self, + mock_project: MagicMock, + mock_adapter: MagicMock, + set_required_mocks, + ) -> None: + + ManifestLoader.get_full_manifest( + config=mock_project, + # reset=False let it default instead + ) + assert not mock_project.clear_dependencies.called + assert not mock_adapter.clear_macro_resolver.called + + ManifestLoader.get_full_manifest(config=mock_project, reset=False) + assert not mock_project.clear_dependencies.called + assert not mock_adapter.clear_macro_resolver.called + + ManifestLoader.get_full_manifest(config=mock_project, reset=True) + assert mock_project.clear_dependencies.called + assert mock_adapter.clear_macro_resolver.called + + def test_partial_parse_file_diff_flag( + self, + mock_project: MagicMock, + mocker: MockerFixture, + set_required_mocks, + ) -> None: + + # FileDiff.from_dict is only called if PARTIAL_PARSE_FILE_DIFF == False + # So we can track this function call to check if setting PARTIAL_PARSE_FILE_DIFF + # works appropriately + mock_file_diff = mocker.patch("dbt.parser.read_files.FileDiff.from_dict") + mock_file_diff.return_value = FileDiff([], [], []) + + set_from_args(Namespace(), {}) + ManifestLoader.get_full_manifest(config=mock_project) + assert not mock_file_diff.called + + set_from_args(Namespace(PARTIAL_PARSE_FILE_DIFF=True), {}) + ManifestLoader.get_full_manifest(config=mock_project) + assert not mock_file_diff.called + + set_from_args(Namespace(PARTIAL_PARSE_FILE_DIFF=False), {}) + ManifestLoader.get_full_manifest(config=mock_project) + assert mock_file_diff.called diff --git a/tests/unit/utils/adapter.py b/tests/unit/utils/adapter.py new file mode 100644 index 00000000000..06555b0e400 --- /dev/null +++ b/tests/unit/utils/adapter.py @@ -0,0 +1,21 @@ +from unittest.mock import MagicMock + +import pytest + +from dbt.adapters.postgres import PostgresAdapter +from dbt.adapters.sql import SQLConnectionManager + + +@pytest.fixture +def mock_connection_manager() -> MagicMock: + mock_connection_manager = MagicMock(SQLConnectionManager) + mock_connection_manager.set_query_header = lambda query_header_context: None + return mock_connection_manager + + +@pytest.fixture +def mock_adapter(mock_connection_manager: MagicMock) -> MagicMock: + mock_adapter = MagicMock(PostgresAdapter) + mock_adapter.connections = mock_connection_manager + mock_adapter.clear_macro_resolver = MagicMock() + return mock_adapter diff --git a/tests/unit/utils/project.py b/tests/unit/utils/project.py index b34e03da494..c7215990e6d 100644 --- a/tests/unit/utils/project.py +++ b/tests/unit/utils/project.py @@ -1,6 +1,9 @@ +from unittest.mock import MagicMock + import pytest from dbt.adapters.contracts.connection import QueryComment +from dbt.config import RuntimeConfig from dbt.config.project import Project, RenderComponents, VarProvider from dbt.config.selectors import SelectorConfig from dbt.contracts.project import PackageConfig @@ -68,3 +71,18 @@ def project(selector_config: SelectorConfig) -> Project: restrict_access=False, dbt_cloud={}, ) + + +@pytest.fixture +def mock_project(): + mock_project = MagicMock(RuntimeConfig) + mock_project.cli_vars = {} + mock_project.args = MagicMock() + mock_project.args.profile = "test" + mock_project.args.target = "test" + mock_project.project_env_vars = {} + mock_project.profile_env_vars = {} + mock_project.project_target_path = "mock_target_path" + mock_project.credentials = MagicMock() + mock_project.clear_dependencies = MagicMock() + return mock_project