|
| 1 | +from pathlib import Path |
| 2 | +from unittest.mock import create_autospec |
| 3 | + |
| 4 | +import pytest |
| 5 | + |
| 6 | +from databricks.labs.ucx.source_code.base import CurrentSessionState |
| 7 | +from databricks.labs.ucx.source_code.files import FileLoader |
| 8 | +from databricks.labs.ucx.source_code.folders import FolderLoader, Folder |
| 9 | +from databricks.labs.ucx.source_code.graph import Dependency, DependencyGraph |
| 10 | +from databricks.labs.ucx.source_code.notebooks.loaders import NotebookLoader |
| 11 | +from databricks.labs.ucx.source_code.path_lookup import PathLookup |
| 12 | + |
| 13 | + |
| 14 | +def test_folder_has_repr() -> None: |
| 15 | + notebook_loader = NotebookLoader() |
| 16 | + file_loader = FileLoader() |
| 17 | + folder = Folder(Path("test"), notebook_loader, file_loader, FolderLoader(notebook_loader, file_loader)) |
| 18 | + assert len(repr(folder)) > 0 |
| 19 | + |
| 20 | + |
| 21 | +@pytest.fixture |
| 22 | +def graph_parent_child_context(mock_path_lookup, simple_dependency_resolver) -> DependencyGraph: |
| 23 | + """Dependency graph for the parent-child-context sample directory. |
| 24 | +
|
| 25 | + The directory contains three files `grand_parent.py`, `parent.py` and `child.py`. That import each other as such: |
| 26 | + grand parent imports parent import child. |
| 27 | + """ |
| 28 | + path = mock_path_lookup.resolve(Path("parent-child-context/")) |
| 29 | + dependency = Dependency(FolderLoader(NotebookLoader(), FileLoader()), path, False) |
| 30 | + graph = DependencyGraph(dependency, None, simple_dependency_resolver, mock_path_lookup, CurrentSessionState()) |
| 31 | + return graph |
| 32 | + |
| 33 | + |
| 34 | +def test_folder_build_dependency_graph_without_problems(mock_path_lookup, graph_parent_child_context) -> None: |
| 35 | + """No problems should arise form building the dependency graph for the sample folder""" |
| 36 | + folder = graph_parent_child_context.dependency.load(mock_path_lookup) |
| 37 | + assert folder is not None |
| 38 | + problems = folder.build_dependency_graph(graph_parent_child_context) |
| 39 | + assert not problems |
| 40 | + |
| 41 | + |
| 42 | +def test_folder_loads_content(mock_path_lookup, graph_parent_child_context) -> None: |
| 43 | + """The files in the folder should be added to the dependency graph after building.""" |
| 44 | + expected_dependencies = {graph_parent_child_context.dependency} |
| 45 | + for relative_path in "grand_parent.py", "parent.py", "child.py": |
| 46 | + path = mock_path_lookup.resolve(Path("parent-child-context") / relative_path) |
| 47 | + dependency = Dependency(FileLoader(), path) |
| 48 | + expected_dependencies.add(dependency) |
| 49 | + |
| 50 | + folder = graph_parent_child_context.dependency.load(mock_path_lookup) |
| 51 | + assert folder is not None |
| 52 | + folder.build_dependency_graph(graph_parent_child_context) |
| 53 | + |
| 54 | + assert graph_parent_child_context.all_dependencies == expected_dependencies |
| 55 | + |
| 56 | + |
| 57 | +def test_folder_cannot_load_unresolved_path(graph_parent_child_context) -> None: |
| 58 | + """An unresolved path cannot be loaded.""" |
| 59 | + path_lookup = create_autospec(PathLookup) |
| 60 | + path_lookup.resolve.return_value = None |
| 61 | + folder = graph_parent_child_context.dependency.load(path_lookup) |
| 62 | + assert folder is None |
| 63 | + path_lookup.resolve.assert_called_once_with(graph_parent_child_context.dependency.path) |
| 64 | + |
| 65 | + |
| 66 | +@pytest.mark.parametrize("subdirectory", [".venv"]) |
| 67 | +def test_folder_build_dependency_graph_ignore_subdirectories( |
| 68 | + tmp_path, mock_path_lookup, simple_dependency_resolver, subdirectory: str |
| 69 | +) -> None: |
| 70 | + """The folder loader should only include directories with source code""" |
| 71 | + path = tmp_path / subdirectory / "file.py" |
| 72 | + path.parent.mkdir(parents=True, exist_ok=True) |
| 73 | + path.touch() |
| 74 | + dependency = Dependency(FolderLoader(NotebookLoader(), FileLoader()), tmp_path, inherits_context=False) |
| 75 | + graph = DependencyGraph(dependency, None, simple_dependency_resolver, mock_path_lookup, CurrentSessionState()) |
| 76 | + folder = graph.dependency.load(mock_path_lookup) |
| 77 | + assert folder is not None |
| 78 | + problems = folder.build_dependency_graph(graph) |
| 79 | + assert not problems |
| 80 | + assert path not in mock_path_lookup.successfully_resolved_paths, "Subdirectory should be ignored" |
0 commit comments