Skip to content

Commit ccb3fe8

Browse files
committed
test: add unit tests for APIDbtRunner manifest caching
Cover three scenarios: - manifest is cached after the first successful invocation - manifest is not cached when invocation fails - cached manifest is reused on subsequent calls
1 parent d6d6d06 commit ccb3fe8

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from contextlib import contextmanager
2+
from unittest import mock
3+
4+
from dbt.cli.main import dbtRunnerResult
5+
6+
from elementary.clients.dbt.api_dbt_runner import APIDbtRunner
7+
8+
9+
def _make_result(success=True, exception=None):
10+
return dbtRunnerResult(
11+
success=success,
12+
result=None,
13+
exception=exception,
14+
)
15+
16+
17+
def _make_runner():
18+
runner = APIDbtRunner.__new__(APIDbtRunner)
19+
runner._manifest = None
20+
runner.project_dir = "/tmp/fake"
21+
runner.env_vars = None
22+
runner.raise_on_failure = False
23+
return runner
24+
25+
26+
@contextmanager
27+
def _noop_context(*args, **kwargs):
28+
yield
29+
30+
31+
_PATCH_CHDIR = mock.patch("elementary.clients.dbt.api_dbt_runner.with_chdir", _noop_context)
32+
_PATCH_ENV = mock.patch("elementary.clients.dbt.api_dbt_runner.env_vars_context", _noop_context)
33+
34+
35+
@_PATCH_ENV
36+
@_PATCH_CHDIR
37+
@mock.patch("elementary.clients.dbt.api_dbt_runner.dbtRunner")
38+
def test_manifest_cached_after_first_success(mock_dbt_runner_cls):
39+
fake_manifest = object()
40+
mock_instance = mock.MagicMock()
41+
mock_instance.invoke.return_value = _make_result(success=True)
42+
mock_instance.manifest = fake_manifest
43+
mock_dbt_runner_cls.return_value = mock_instance
44+
45+
runner = _make_runner()
46+
runner._inner_run_command(["run-operation", "foo"], quiet=True, log_output=False, log_format="json")
47+
48+
assert runner._manifest is fake_manifest
49+
mock_dbt_runner_cls.assert_called_once_with(manifest=None, callbacks=mock.ANY)
50+
51+
52+
@_PATCH_ENV
53+
@_PATCH_CHDIR
54+
@mock.patch("elementary.clients.dbt.api_dbt_runner.dbtRunner")
55+
def test_manifest_not_cached_on_failure(mock_dbt_runner_cls):
56+
mock_instance = mock.MagicMock()
57+
mock_instance.invoke.return_value = _make_result(success=False)
58+
mock_instance.manifest = object()
59+
mock_dbt_runner_cls.return_value = mock_instance
60+
61+
runner = _make_runner()
62+
runner._inner_run_command(["run-operation", "foo"], quiet=True, log_output=False, log_format="json")
63+
64+
assert runner._manifest is None
65+
66+
67+
@_PATCH_ENV
68+
@_PATCH_CHDIR
69+
@mock.patch("elementary.clients.dbt.api_dbt_runner.dbtRunner")
70+
def test_cached_manifest_reused_on_subsequent_calls(mock_dbt_runner_cls):
71+
fake_manifest = object()
72+
mock_instance = mock.MagicMock()
73+
mock_instance.invoke.return_value = _make_result(success=True)
74+
mock_instance.manifest = fake_manifest
75+
mock_dbt_runner_cls.return_value = mock_instance
76+
77+
runner = _make_runner()
78+
79+
runner._inner_run_command(["run-operation", "foo"], quiet=True, log_output=False, log_format="json")
80+
assert runner._manifest is fake_manifest
81+
82+
new_manifest = object()
83+
mock_instance.manifest = new_manifest
84+
mock_dbt_runner_cls.reset_mock()
85+
86+
runner._inner_run_command(["run-operation", "bar"], quiet=True, log_output=False, log_format="json")
87+
88+
mock_dbt_runner_cls.assert_called_once_with(manifest=fake_manifest, callbacks=mock.ANY)
89+
assert runner._manifest is fake_manifest

0 commit comments

Comments
 (0)