recce-nightly 1.3.0.20250507__py3-none-any.whl → 1.4.0.20250514__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of recce-nightly might be problematic. Click here for more details.
- recce/VERSION +1 -1
- recce/__init__.py +22 -22
- recce/adapter/base.py +11 -14
- recce/adapter/dbt_adapter/__init__.py +355 -316
- recce/adapter/dbt_adapter/dbt_version.py +3 -0
- recce/adapter/sqlmesh_adapter.py +24 -35
- recce/apis/check_api.py +39 -28
- recce/apis/check_func.py +33 -27
- recce/apis/run_api.py +25 -19
- recce/apis/run_func.py +29 -23
- recce/artifact.py +44 -49
- recce/cli.py +484 -285
- recce/config.py +42 -33
- recce/core.py +52 -44
- recce/data/404.html +1 -1
- recce/data/_next/static/chunks/{368-7587b306577df275.js → 778-aef312bffb4c0312.js} +15 -15
- recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js +1 -0
- recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js +1 -0
- recce/data/_next/static/chunks/app/page-7086764277331fcb.js +1 -0
- recce/data/_next/static/chunks/{cd9f8d63-cf0d5a7b0f7a92e8.js → cd9f8d63-e020f408095ed77c.js} +3 -3
- recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js +1 -0
- recce/data/_next/static/css/88b8abc134cfd59a.css +3 -0
- recce/data/index.html +2 -2
- recce/data/index.txt +2 -2
- recce/diff.py +6 -12
- recce/event/__init__.py +74 -72
- recce/event/collector.py +27 -20
- recce/event/track.py +39 -27
- recce/exceptions.py +1 -1
- recce/git.py +7 -7
- recce/github.py +57 -53
- recce/models/__init__.py +1 -1
- recce/models/check.py +6 -7
- recce/models/run.py +1 -0
- recce/models/types.py +27 -27
- recce/pull_request.py +26 -24
- recce/run.py +148 -111
- recce/server.py +103 -89
- recce/state.py +209 -177
- recce/summary.py +168 -143
- recce/tasks/__init__.py +3 -3
- recce/tasks/core.py +11 -13
- recce/tasks/dataframe.py +19 -17
- recce/tasks/histogram.py +69 -34
- recce/tasks/lineage.py +2 -2
- recce/tasks/profile.py +147 -86
- recce/tasks/query.py +139 -87
- recce/tasks/rowcount.py +33 -30
- recce/tasks/schema.py +14 -14
- recce/tasks/top_k.py +35 -35
- recce/tasks/valuediff.py +216 -152
- recce/util/breaking.py +77 -84
- recce/util/cll.py +55 -51
- recce/util/io.py +19 -17
- recce/util/logger.py +1 -1
- recce/util/recce_cloud.py +70 -72
- recce/util/singleton.py +4 -4
- recce/yaml/__init__.py +7 -10
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/METADATA +5 -2
- recce_nightly-1.4.0.20250514.dist-info/RECORD +143 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/WHEEL +1 -1
- tests/adapter/dbt_adapter/conftest.py +1 -0
- tests/adapter/dbt_adapter/dbt_test_helper.py +28 -18
- tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -15
- tests/adapter/dbt_adapter/test_dbt_cll.py +39 -32
- tests/adapter/dbt_adapter/test_selector.py +22 -21
- tests/tasks/test_histogram.py +58 -66
- tests/tasks/test_lineage.py +36 -23
- tests/tasks/test_preset_checks.py +45 -31
- tests/tasks/test_profile.py +340 -15
- tests/tasks/test_query.py +40 -40
- tests/tasks/test_row_count.py +65 -46
- tests/tasks/test_schema.py +65 -42
- tests/tasks/test_top_k.py +22 -18
- tests/tasks/test_valuediff.py +43 -32
- tests/test_cli.py +71 -58
- tests/test_config.py +7 -9
- tests/test_core.py +5 -3
- tests/test_dbt.py +7 -7
- tests/test_pull_request.py +1 -1
- tests/test_server.py +19 -13
- tests/test_state.py +40 -27
- tests/test_summary.py +18 -14
- recce/data/_next/static/chunks/8d700b6a-f0b1f6b9e0d97ce2.js +0 -1
- recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
- recce/data/_next/static/chunks/app/page-92f13c8fad9fae3d.js +0 -1
- recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
- recce_nightly-1.3.0.20250507.dist-info/RECORD +0 -142
- /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → E_HPXsXdrqHg2YEHmU3mK}/_buildManifest.js +0 -0
- /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → E_HPXsXdrqHg2YEHmU3mK}/_ssgManifest.js +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/entry_points.txt +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/licenses/LICENSE +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/top_level.txt +0 -0
tests/test_config.py
CHANGED
|
@@ -10,7 +10,7 @@ test_root_path = os.path.dirname(os.path.abspath(__file__))
|
|
|
10
10
|
|
|
11
11
|
class RecceConfigTestCase(TestCase):
|
|
12
12
|
def setUp(self):
|
|
13
|
-
self.recce_config_path = os.path.join(test_root_path,
|
|
13
|
+
self.recce_config_path = os.path.join(test_root_path, "data", "config", "recce.yml")
|
|
14
14
|
pass
|
|
15
15
|
|
|
16
16
|
def tearDown(self):
|
|
@@ -21,25 +21,23 @@ class RecceConfigTestCase(TestCase):
|
|
|
21
21
|
config = RecceConfig(self.recce_config_path)
|
|
22
22
|
|
|
23
23
|
# Test data contains 2 checks
|
|
24
|
-
preset_checks = config.config.get(
|
|
24
|
+
preset_checks = config.config.get("checks")
|
|
25
25
|
self.assertIsNotNone(preset_checks)
|
|
26
26
|
self.assertIsInstance(preset_checks, list)
|
|
27
27
|
self.assertEqual(len(preset_checks), 2)
|
|
28
28
|
|
|
29
|
-
@patch(
|
|
29
|
+
@patch("recce.config.RecceConfig.save")
|
|
30
30
|
def test_recce_config_not_found(self, mock_save):
|
|
31
|
-
default_config = RecceConfig(
|
|
31
|
+
default_config = RecceConfig("NOT_EXISTING_FILE")
|
|
32
32
|
assert mock_save.called is True
|
|
33
33
|
# Default config should be generated
|
|
34
|
-
preset_checks = default_config.config.get(
|
|
34
|
+
preset_checks = default_config.config.get("checks")
|
|
35
35
|
self.assertIsNotNone(default_config.config)
|
|
36
36
|
self.assertIsInstance(preset_checks, list)
|
|
37
37
|
self.assertEqual(len(preset_checks), 2)
|
|
38
38
|
|
|
39
|
-
@patch(
|
|
39
|
+
@patch("recce.yaml.safe_load")
|
|
40
40
|
def test_recce_config_null_checks(self, mock_yaml_safe_load):
|
|
41
41
|
# mock to load a yaml file with null checks
|
|
42
|
-
mock_yaml_safe_load.return_value = {
|
|
43
|
-
'checks': None
|
|
44
|
-
}
|
|
42
|
+
mock_yaml_safe_load.return_value = {"checks": None}
|
|
45
43
|
RecceConfig(self.recce_config_path)
|
tests/test_core.py
CHANGED
|
@@ -21,7 +21,9 @@ def test_lineage_diff(dbt_test_helper):
|
|
|
21
21
|
dbt_test_helper.create_model("model1", sql_model1, sql_model1)
|
|
22
22
|
dbt_test_helper.create_model("model2", sql_model2, sql_model2_)
|
|
23
23
|
result = dbt_test_helper.context.get_lineage_diff()
|
|
24
|
-
nodediff = result.diff.get(
|
|
24
|
+
nodediff = result.diff.get("model1")
|
|
25
25
|
assert nodediff is None
|
|
26
|
-
nodediff2 = result.diff.get(
|
|
27
|
-
assert
|
|
26
|
+
nodediff2 = result.diff.get("model2")
|
|
27
|
+
assert (
|
|
28
|
+
nodediff2 is not None and nodediff2.change_status == "modified" and nodediff2.change.category == "non_breaking"
|
|
29
|
+
)
|
tests/test_dbt.py
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from unittest import TestCase
|
|
3
|
-
from unittest.mock import
|
|
3
|
+
from unittest.mock import MagicMock, patch
|
|
4
4
|
|
|
5
|
-
from recce.adapter.dbt_adapter import
|
|
5
|
+
from recce.adapter.dbt_adapter import DbtAdapter, load_catalog, load_manifest
|
|
6
6
|
|
|
7
7
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class TestAdapterLineage(TestCase):
|
|
11
11
|
def setUp(self) -> None:
|
|
12
|
-
self.manifest = load_manifest(path=os.path.join(current_dir,
|
|
12
|
+
self.manifest = load_manifest(path=os.path.join(current_dir, "manifest.json"))
|
|
13
13
|
assert self.manifest is not None
|
|
14
14
|
|
|
15
|
-
self.catalog = load_catalog(path=os.path.join(current_dir,
|
|
15
|
+
self.catalog = load_catalog(path=os.path.join(current_dir, "catalog.json"))
|
|
16
16
|
assert self.catalog is not None
|
|
17
17
|
|
|
18
18
|
def tearDown(self):
|
|
@@ -22,8 +22,8 @@ class TestAdapterLineage(TestCase):
|
|
|
22
22
|
dbt_adapter = DbtAdapter(curr_manifest=self.manifest)
|
|
23
23
|
lineage = dbt_adapter.get_lineage()
|
|
24
24
|
assert lineage is not None
|
|
25
|
-
assert lineage[
|
|
26
|
-
assert
|
|
25
|
+
assert lineage["nodes"]["model.jaffle_shop.orders"] is not None
|
|
26
|
+
assert "columns" not in lineage["nodes"]["model.jaffle_shop.orders"]
|
|
27
27
|
|
|
28
28
|
def test_load_lineage_with_catalog(self):
|
|
29
29
|
mock_adapter = MagicMock()
|
|
@@ -33,4 +33,4 @@ class TestAdapterLineage(TestCase):
|
|
|
33
33
|
dbt_adapter.adapter = mock_adapter
|
|
34
34
|
lineage = dbt_adapter.get_lineage()
|
|
35
35
|
assert lineage is not None
|
|
36
|
-
assert len(lineage[
|
|
36
|
+
assert len(lineage["nodes"]["model.jaffle_shop.orders"]["columns"]) == 9
|
tests/test_pull_request.py
CHANGED
tests/test_server.py
CHANGED
|
@@ -5,6 +5,7 @@ from fastapi.testclient import TestClient
|
|
|
5
5
|
|
|
6
6
|
from recce.core import default_context
|
|
7
7
|
from recce.server import app
|
|
8
|
+
|
|
8
9
|
# noinspection PyUnresolvedReferences
|
|
9
10
|
from tests.adapter.dbt_adapter.conftest import dbt_test_helper
|
|
10
11
|
|
|
@@ -12,10 +13,12 @@ from tests.adapter.dbt_adapter.conftest import dbt_test_helper
|
|
|
12
13
|
@pytest.fixture
|
|
13
14
|
def temp_folder():
|
|
14
15
|
import tempfile
|
|
16
|
+
|
|
15
17
|
temp_dir = tempfile.mkdtemp()
|
|
16
18
|
yield temp_dir
|
|
17
19
|
|
|
18
20
|
import shutil
|
|
21
|
+
|
|
19
22
|
shutil.rmtree(temp_dir)
|
|
20
23
|
|
|
21
24
|
|
|
@@ -29,36 +32,39 @@ def test_health():
|
|
|
29
32
|
def test_stateless(dbt_test_helper):
|
|
30
33
|
context = default_context()
|
|
31
34
|
from recce.state import RecceStateLoader
|
|
35
|
+
|
|
32
36
|
context.state_loader = RecceStateLoader()
|
|
33
37
|
client = TestClient(app)
|
|
34
38
|
response = client.get("/api/info")
|
|
35
39
|
assert response.status_code == 200
|
|
36
40
|
info = response.json()
|
|
37
|
-
assert info[
|
|
38
|
-
assert info[
|
|
41
|
+
assert info["file_mode"] is False
|
|
42
|
+
assert info["cloud_mode"] is False
|
|
39
43
|
|
|
40
44
|
|
|
41
45
|
def test_file_mode(dbt_test_helper):
|
|
42
46
|
context = default_context()
|
|
43
47
|
from recce.state import RecceStateLoader
|
|
44
|
-
|
|
48
|
+
|
|
49
|
+
context.state_loader = RecceStateLoader(state_file="/tmp/recce_state.json")
|
|
45
50
|
client = TestClient(app)
|
|
46
51
|
response = client.get("/api/info")
|
|
47
52
|
assert response.status_code == 200
|
|
48
53
|
info = response.json()
|
|
49
|
-
assert info[
|
|
50
|
-
assert info[
|
|
51
|
-
assert info[
|
|
54
|
+
assert info["file_mode"] is True
|
|
55
|
+
assert info["filename"] == "recce_state.json"
|
|
56
|
+
assert info["cloud_mode"] is False
|
|
52
57
|
|
|
53
58
|
|
|
54
59
|
def test_saveas_and_rename(dbt_test_helper, temp_folder):
|
|
55
60
|
context = default_context()
|
|
56
|
-
state_file = os.path.join(temp_folder,
|
|
57
|
-
state_file2 = os.path.join(temp_folder,
|
|
58
|
-
state_file3 = os.path.join(temp_folder,
|
|
59
|
-
os.makedirs(os.path.join(temp_folder,
|
|
61
|
+
state_file = os.path.join(temp_folder, "recce_state.json")
|
|
62
|
+
state_file2 = os.path.join(temp_folder, "recce_state2.json")
|
|
63
|
+
state_file3 = os.path.join(temp_folder, "recce_state3.json")
|
|
64
|
+
os.makedirs(os.path.join(temp_folder, "dir.json"))
|
|
60
65
|
|
|
61
66
|
from recce.state import RecceStateLoader
|
|
67
|
+
|
|
62
68
|
context.state_loader = RecceStateLoader(state_file=state_file)
|
|
63
69
|
client = TestClient(app)
|
|
64
70
|
|
|
@@ -69,7 +75,7 @@ def test_saveas_and_rename(dbt_test_helper, temp_folder):
|
|
|
69
75
|
response = client.post("/api/save-as", json={"filename": "recce_state2.json"})
|
|
70
76
|
assert response.status_code == 200
|
|
71
77
|
assert os.path.exists(state_file2)
|
|
72
|
-
assert context.state_loader.state_file == os.path.join(temp_folder,
|
|
78
|
+
assert context.state_loader.state_file == os.path.join(temp_folder, "recce_state2.json")
|
|
73
79
|
|
|
74
80
|
# Same file
|
|
75
81
|
response = client.post("/api/save-as", json={"filename": "recce_state2.json"})
|
|
@@ -84,7 +90,7 @@ def test_saveas_and_rename(dbt_test_helper, temp_folder):
|
|
|
84
90
|
assert response.status_code == 200
|
|
85
91
|
assert not os.path.exists(state_file2)
|
|
86
92
|
assert os.path.exists(state_file3)
|
|
87
|
-
assert context.state_loader.state_file == os.path.join(temp_folder,
|
|
93
|
+
assert context.state_loader.state_file == os.path.join(temp_folder, "recce_state3.json")
|
|
88
94
|
|
|
89
95
|
# Conflict
|
|
90
96
|
response = client.post("/api/save-as", json={"filename": "recce_state.json"})
|
|
@@ -95,4 +101,4 @@ def test_saveas_and_rename(dbt_test_helper, temp_folder):
|
|
|
95
101
|
# Overwrite
|
|
96
102
|
response = client.post("/api/save-as", json={"filename": "recce_state.json", "overwrite": True})
|
|
97
103
|
assert response.status_code == 200
|
|
98
|
-
assert context.state_loader.state_file == os.path.join(temp_folder,
|
|
104
|
+
assert context.state_loader.state_file == os.path.join(temp_folder, "recce_state.json")
|
tests/test_state.py
CHANGED
|
@@ -5,20 +5,19 @@ from datetime import datetime
|
|
|
5
5
|
|
|
6
6
|
from recce.core import RecceContext
|
|
7
7
|
from recce.models import Check, Run
|
|
8
|
-
from recce.state import
|
|
8
|
+
from recce.state import ArtifactsRoot, RecceState, RecceStateLoader
|
|
9
9
|
|
|
10
10
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class TestRecceState(unittest.TestCase):
|
|
14
14
|
def test_merge_checks(self):
|
|
15
|
-
check1 = Check(name=
|
|
16
|
-
check2 = Check(name=
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
check3 = Check(name='test3', description='', type='query')
|
|
15
|
+
check1 = Check(name="test1", description="", type="query")
|
|
16
|
+
check2 = Check(name="test2", description="", type="query", updated_at=datetime(2000, 1, 1))
|
|
17
|
+
check2_2 = Check(
|
|
18
|
+
name="test2_2", description="", type="query", updated_at=datetime(2020, 1, 1), check_id=check2.check_id
|
|
19
|
+
)
|
|
20
|
+
check3 = Check(name="test3", description="", type="query")
|
|
22
21
|
|
|
23
22
|
context = RecceContext()
|
|
24
23
|
state = RecceState(checks=[check1], runs=[])
|
|
@@ -33,10 +32,22 @@ class TestRecceState(unittest.TestCase):
|
|
|
33
32
|
self.assertEqual(check2_2.name, context.checks[1].name)
|
|
34
33
|
|
|
35
34
|
def test_merge_preset_checks(self):
|
|
36
|
-
check1 = Check(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
check1 = Check(
|
|
36
|
+
name="test1",
|
|
37
|
+
description="test1",
|
|
38
|
+
type="query",
|
|
39
|
+
params=dict(foo="bar"),
|
|
40
|
+
updated_at=datetime(2000, 1, 1),
|
|
41
|
+
is_preset=True,
|
|
42
|
+
)
|
|
43
|
+
check2 = Check(
|
|
44
|
+
name="test2",
|
|
45
|
+
description="test2",
|
|
46
|
+
type="query",
|
|
47
|
+
params=dict(foo="bar"),
|
|
48
|
+
updated_at=datetime(2001, 1, 1),
|
|
49
|
+
is_preset=True,
|
|
50
|
+
)
|
|
40
51
|
|
|
41
52
|
context = RecceContext(checks=[check1])
|
|
42
53
|
state = RecceState(checks=[check2], runs=[])
|
|
@@ -51,10 +62,10 @@ class TestRecceState(unittest.TestCase):
|
|
|
51
62
|
self.assertEqual(check2.name, context.checks[0].name)
|
|
52
63
|
|
|
53
64
|
def test_revert_checks(self):
|
|
54
|
-
check1 = Check(name=
|
|
55
|
-
check2 = Check(name=
|
|
56
|
-
check2_2 = Check(name=
|
|
57
|
-
check3 = Check(name=
|
|
65
|
+
check1 = Check(name="test1", description="", type="query")
|
|
66
|
+
check2 = Check(name="test2", description="", type="query")
|
|
67
|
+
check2_2 = Check(name="test2_2", description="", type="query", check_id=check2.check_id)
|
|
68
|
+
check3 = Check(name="test3", description="", type="query")
|
|
58
69
|
|
|
59
70
|
context = RecceContext(checks=[check1, check2])
|
|
60
71
|
state = RecceState(checks=[check2_2, check3], runs=[])
|
|
@@ -63,9 +74,9 @@ class TestRecceState(unittest.TestCase):
|
|
|
63
74
|
self.assertEqual(check2_2.name, context.checks[0].name)
|
|
64
75
|
|
|
65
76
|
def test_merge_runs(self):
|
|
66
|
-
run1 = Run(type=
|
|
67
|
-
run2 = Run(type=
|
|
68
|
-
run3 = Run(type=
|
|
77
|
+
run1 = Run(type="query")
|
|
78
|
+
run2 = Run(type="query")
|
|
79
|
+
run3 = Run(type="query")
|
|
69
80
|
|
|
70
81
|
context = RecceContext(runs=[])
|
|
71
82
|
state = RecceState(runs=[run1])
|
|
@@ -80,9 +91,10 @@ class TestRecceState(unittest.TestCase):
|
|
|
80
91
|
def test_merge_dbt_artifacts(self):
|
|
81
92
|
import json
|
|
82
93
|
import os
|
|
83
|
-
|
|
94
|
+
|
|
95
|
+
with open(os.path.join(current_dir, "manifest.json"), "r") as f:
|
|
84
96
|
manifest = json.load(f)
|
|
85
|
-
manifest[
|
|
97
|
+
manifest["metadata"]["generated_at"] = "2000-01-01T00:00:00Z"
|
|
86
98
|
artifacts = ArtifactsRoot(
|
|
87
99
|
base=dict(
|
|
88
100
|
manifest=manifest,
|
|
@@ -93,13 +105,14 @@ class TestRecceState(unittest.TestCase):
|
|
|
93
105
|
)
|
|
94
106
|
|
|
95
107
|
from tests.adapter.dbt_adapter.dbt_test_helper import DbtTestHelper
|
|
108
|
+
|
|
96
109
|
adapter = DbtTestHelper().adapter
|
|
97
110
|
adapter.import_artifacts(artifacts)
|
|
98
|
-
self.assertNotEqual(adapter.base_manifest.metadata.invocation_id, manifest.get(
|
|
111
|
+
self.assertNotEqual(adapter.base_manifest.metadata.invocation_id, manifest.get("metadata").get("invocation_id"))
|
|
99
112
|
|
|
100
|
-
manifest[
|
|
113
|
+
manifest["metadata"]["generated_at"] = "2099-01-01T00:00:00Z"
|
|
101
114
|
adapter.import_artifacts(artifacts)
|
|
102
|
-
self.assertEqual(adapter.base_manifest.metadata.invocation_id, manifest.get(
|
|
115
|
+
self.assertEqual(adapter.base_manifest.metadata.invocation_id, manifest.get("metadata").get("invocation_id"))
|
|
103
116
|
|
|
104
117
|
def test_state_loader(self):
|
|
105
118
|
context = RecceContext()
|
|
@@ -107,14 +120,14 @@ class TestRecceState(unittest.TestCase):
|
|
|
107
120
|
# copy ./recce_state.json to temp and open
|
|
108
121
|
|
|
109
122
|
# use library to create a temp file in the context
|
|
110
|
-
import tempfile
|
|
111
|
-
import shutil
|
|
112
123
|
import os
|
|
124
|
+
import shutil
|
|
125
|
+
import tempfile
|
|
113
126
|
|
|
114
127
|
with tempfile.NamedTemporaryFile() as f:
|
|
115
128
|
# copy ./recce_state.json to temp file
|
|
116
129
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
117
|
-
state_file = os.path.join(current_dir,
|
|
130
|
+
state_file = os.path.join(current_dir, "recce_state.json")
|
|
118
131
|
shutil.copy(state_file, f.name)
|
|
119
132
|
|
|
120
133
|
# load the state file
|
tests/test_summary.py
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import unittest
|
|
3
3
|
|
|
4
|
-
from recce.adapter.dbt_adapter import
|
|
4
|
+
from recce.adapter.dbt_adapter import DbtAdapter, DbtVersion, load_manifest
|
|
5
5
|
from recce.core import RecceContext, set_default_context
|
|
6
|
-
from recce.summary import
|
|
6
|
+
from recce.summary import (
|
|
7
|
+
_build_lineage_graph,
|
|
8
|
+
generate_mermaid_lineage_graph,
|
|
9
|
+
generate_summary_metadata,
|
|
10
|
+
)
|
|
7
11
|
|
|
8
12
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
9
|
-
base_manifest_dir = os.path.join(current_dir,
|
|
10
|
-
pr2_manifest_dir = os.path.join(current_dir,
|
|
13
|
+
base_manifest_dir = os.path.join(current_dir, "data", "manifest", "base")
|
|
14
|
+
pr2_manifest_dir = os.path.join(current_dir, "data", "manifest", "pr2") # Pull Request 2l
|
|
11
15
|
|
|
12
16
|
dbt_version = DbtVersion()
|
|
13
17
|
|
|
14
18
|
|
|
15
|
-
@unittest.skipIf(dbt_version <
|
|
19
|
+
@unittest.skipIf(dbt_version < "1.8.1", "Dbt version is less than 1.8.1")
|
|
16
20
|
def test_generate_summary_metadata():
|
|
17
|
-
manifest = load_manifest(path=os.path.join(current_dir,
|
|
21
|
+
manifest = load_manifest(path=os.path.join(current_dir, "manifest.json"))
|
|
18
22
|
assert manifest is not None
|
|
19
23
|
dbt_adapter = DbtAdapter(curr_manifest=manifest)
|
|
20
24
|
curr_lineage = dbt_adapter.get_lineage()
|
|
@@ -23,18 +27,18 @@ def test_generate_summary_metadata():
|
|
|
23
27
|
# Summary with no changes
|
|
24
28
|
generate_summary_metadata(curr_lineage, base_lineage)
|
|
25
29
|
|
|
26
|
-
base_manifest = load_manifest(path=os.path.join(base_manifest_dir,
|
|
27
|
-
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir,
|
|
30
|
+
base_manifest = load_manifest(path=os.path.join(base_manifest_dir, "manifest.json"))
|
|
31
|
+
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir, "manifest.json"))
|
|
28
32
|
dbt_adapter = DbtAdapter(curr_manifest=curr_manifest, base_manifest=base_manifest)
|
|
29
33
|
curr_lineage = dbt_adapter.get_lineage()
|
|
30
34
|
base_lineage = dbt_adapter.get_lineage(base=True)
|
|
31
35
|
generate_summary_metadata(curr_lineage, base_lineage)
|
|
32
36
|
|
|
33
37
|
|
|
34
|
-
@unittest.skipIf(dbt_version <
|
|
38
|
+
@unittest.skipIf(dbt_version < "v1.8.1", "Dbt version is less than 1.8.1")
|
|
35
39
|
def test_build_lineage_graph():
|
|
36
|
-
base_manifest = load_manifest(path=os.path.join(base_manifest_dir,
|
|
37
|
-
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir,
|
|
40
|
+
base_manifest = load_manifest(path=os.path.join(base_manifest_dir, "manifest.json"))
|
|
41
|
+
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir, "manifest.json"))
|
|
38
42
|
dbt_adapter = DbtAdapter(curr_manifest=curr_manifest, base_manifest=base_manifest)
|
|
39
43
|
curr_lineage = dbt_adapter.get_lineage()
|
|
40
44
|
base_lineage = dbt_adapter.get_lineage(base=True)
|
|
@@ -47,11 +51,11 @@ def test_build_lineage_graph():
|
|
|
47
51
|
assert len(lineage_graph.modified_set) == 3
|
|
48
52
|
|
|
49
53
|
|
|
50
|
-
@unittest.skipIf(dbt_version <
|
|
54
|
+
@unittest.skipIf(dbt_version < "v1.8.1", "Dbt version is less than 1.8.1")
|
|
51
55
|
def test_generate_mermaid_lineage_graph():
|
|
52
56
|
set_default_context(RecceContext())
|
|
53
|
-
base_manifest = load_manifest(path=os.path.join(base_manifest_dir,
|
|
54
|
-
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir,
|
|
57
|
+
base_manifest = load_manifest(path=os.path.join(base_manifest_dir, "manifest.json"))
|
|
58
|
+
curr_manifest = load_manifest(path=os.path.join(pr2_manifest_dir, "manifest.json"))
|
|
55
59
|
dbt_adapter = DbtAdapter(curr_manifest=curr_manifest, base_manifest=base_manifest)
|
|
56
60
|
curr_lineage = dbt_adapter.get_lineage()
|
|
57
61
|
base_lineage = dbt_adapter.get_lineage(base=True)
|