Skip to content

Commit 5c60514

Browse files
authored
Add Enterprise Catalog tests (#307)
### Summary Add Enterprise Catalog related tests and adjustments. ### Description - Added test profiles with Enterprise Catalog as storage option and respective tests → `TestProfileTemplate` and `TestProfileValidation` - Added test to confirm that twin strategy is **not** applied when Enterprise Catalog is used → `TestTwinStrategyNotAppliedDremio` - Updated expected failures ### Test Results All tests are passing/failing as expected ### Changelog - [x] Added a summary of what this PR accomplishes to CHANGELOG.md ### Related Issue #298
1 parent e20e92c commit 5c60514

File tree

8 files changed

+223
-18
lines changed

8 files changed

+223
-18
lines changed

.github/expected_failures.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
tests/component/test_profile_template.py::TestProfileTemplate::test_cloud_options
21
tests/functional/adapter/dremio_specific/test_drop_temp_table.py::TestDropTempTableDremio::test_drop_temp_table
32
tests/functional/adapter/dremio_specific/test_schema_parsing.py::TestSchemaParsingDremio::test_schema_with_dots
43
tests/functional/adapter/dremio_specific/test_verify_ssl.py::TestVerifyCertificateDremio::test_insecure_request_warning_not_exist
Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,14 @@
11
tests/functional/adapter/unit_testing/test_unit_testing.py::TestDremioUnitTestingTypes::test_unit_test_data_type
2-
tests/functional/adapter/dremio_specific/test_persist_docs.py::TestPersistDocs::test_view_model_delete_wikis_and_tags
3-
tests/functional/adapter/dremio_specific/test_persist_docs.py::TestPersistDocs::test_view_model_update_wikis_and_tags
4-
tests/functional/adapter/dremio_specific/test_persist_docs.py::TestPersistDocs::test_view_model_wikis_and_tags_remain_when_no_changes
52
tests/functional/adapter/grants/test_incremental_grants.py::TestIncrementalGrantsDremio::test_incremental_grants
63
tests/functional/adapter/grants/test_model_grants.py::TestTableGrantsDremio::test_view_table_grants
74
tests/functional/adapter/grants/test_model_grants.py::TestViewGrantsDremio::test_view_table_grants
85
tests/functional/adapter/grants/test_seed_grants.py::TestSeedGrantsDremio::test_seed_grants
96
tests/functional/adapter/materialization/test_base_mat.py::TestSimpleMaterializationsDremio::test_base
10-
tests/functional/adapter/utils/test_array_append.py::TestArrayAppend::test_expected_actual
11-
tests/functional/adapter/utils/test_array_concat.py::TestArrayConcat::test_expected_actual
127
tests/functional/adapter/utils/test_null_compare.py::TestMixedNullCompare::test_build_assert_equal
138
tests/functional/adapter/utils/test_null_compare.py::TestNullCompare::test_build_assert_equal
149
tests/simple_copy/test_simple_copy.py::TestSimpleCopyBaseDremio::test_simple_copy_with_materialized_views
1510
tests/functional/adapter/grants/test_snapshot_grants.py::TestSnapshotGrantsDremio::test_snapshot_grants
1611
tests/component/test_profile_template.py::TestProfileTemplate::test_software_pat_options
1712
tests/component/test_profile_template.py::TestProfileTemplate::test_software_username_password_options
18-
tests/functional/adapter/basic/test_docs_generate.py::TestBaseDocsGenerateDremio::test_run_and_generate
1913
tests/functional/adapter/dremio_specific/test_exact_search.py::TestExactSearchEnabled::test_exact_match_succeeds
2014
tests/functional/adapter/dremio_specific/test_exact_search.py::TestExactSearchEnabled::test_ilike_match_succeeds
21-
tests/hooks/test_model_hooks.py::TestPrePostModelHooksInConfigDremio::test_pre_and_post_model_hooks_model
22-
tests/hooks/test_model_hooks.py::TestPrePostModelHooksInConfigWithCountDremio::test_pre_and_post_model_hooks_model_and_project
23-
tests/hooks/test_model_hooks.py::TestPrePostModelHooksInConfigKwargsDremio::test_pre_and_post_model_hooks_model
24-
tests/hooks/test_model_hooks.py::TestPrePostModelHooksUnderscoresDremio::test_pre_and_post_run_hooks

.github/scripts/compare_test_failures.sh

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
#!/bin/bash
22
set -e
33

4-
echo "Comparing actual test failures with expected failures..."
4+
# Check if expected failures file is provided as argument
5+
if [ $# -eq 0 ]; then
6+
echo "Error: Expected failures file not provided."
7+
exit 1
8+
fi
9+
10+
expected_failures_file="$1"
11+
12+
# Check if the expected failures file exists
13+
if [ ! -f "$expected_failures_file" ]; then
14+
echo "Error: Expected failures file '$expected_failures_file' not found."
15+
exit 1
16+
fi
17+
18+
echo "Comparing actual test failures with expected failures from: $expected_failures_file"
519

620
# Enable globstar for recursive globbing
721
shopt -s globstar
@@ -10,7 +24,7 @@ shopt -s globstar
1024
actual_failures=$(grep -E "(FAILED tests|ERROR tests)" reports/**/*.txt | awk '{print $2}' | sort)
1125

1226
# Read expected failures
13-
expected_failures=$(sort .github/expected_failures.txt)
27+
expected_failures=$(sort "$expected_failures_file")
1428

1529
echo "Expected Failures:"
1630
echo "$expected_failures"

.github/scripts/profiles.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,29 @@ test_sw_up_options:
2828
use_ssl: false
2929
user: dremio
3030
target: dev
31+
test_sw_enterprise_catalog_pat_options:
32+
outputs:
33+
dev:
34+
enterprise_catalog_namespace: test_catalog
35+
enterprise_catalog_folder: no_schema
36+
pat: dremio123
37+
port: 9047
38+
software_host: localhost
39+
threads: 1
40+
type: dremio
41+
use_ssl: false
42+
user: dremio
43+
target: dev
44+
test_sw_enterprise_catalog_up_options:
45+
outputs:
46+
dev:
47+
enterprise_catalog_namespace: test_catalog
48+
enterprise_catalog_folder: no_schema
49+
password: dremio123
50+
port: 9047
51+
software_host: localhost
52+
threads: 1
53+
type: dremio
54+
use_ssl: false
55+
user: dremio
56+
target: dev

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,4 +136,4 @@ jobs:
136136
path: reports/
137137

138138
- name: Compare Actual Failures with Expected Failures
139-
run: bash .github/scripts/compare_test_failures.sh
139+
run: bash .github/scripts/compare_test_failures.sh .github/expected_failures.txt

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [#299](https://github.com/dremio/dbt-dremio/pull/299) Enhance persist_docs macro to wrap model and column metadata (including descriptions, tags and tests) into a Markdown wiki for Dremio.
66
- Refactored CI
77
- Fixed tests for hooks and grants
8+
- Added Dremio Enterprise Catalog tests
89

910
# dbt-dremio v1.9.0
1011

tests/component/test_profile_template.py

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
from dbt.adapters.dremio.credentials import DremioCredentials
2020
from tests.utils.util import SOURCE
2121

22+
DREMIO_EDITION = os.getenv("DREMIO_EDITION")
23+
2224
# Tests require manual setup before executing.
2325
#
24-
# Prior to running these tests, create three dbt projects:
26+
# Prior to running these tests, create six dbt projects:
2527
#
2628
# 1. `dbt init test_cloud_options`
2729
# - accept all default options
@@ -35,8 +37,27 @@
3537
# - accept all default options
3638
# - provide any value for mandatory options
3739
#
40+
# 4. `dbt init test_sw_enterprise_catalog_pat_options`
41+
# - select software_with_pat
42+
# - select enterprise catalog storage option
43+
# - select PAT authentication
44+
# - accept all default options
45+
# - provide any value for mandatory options
46+
#
47+
# 5. `dbt init test_sw_enterprise_catalog_up_options`
48+
# - select software_with_username_password
49+
# - select enterprise catalog storage option
50+
# - select username/password authentication
51+
# - accept all default options
52+
# - provide any value for mandatory options
53+
#
54+
# 6. `dbt init test_cloud_enterprise_catalog_options`
55+
# - select cloud
56+
# - select enterprise catalog storage option
57+
# - accept all default options
58+
# - provide any value for mandatory options
3859
# These tests assumes there exists a $HOME/.dbt/profiles.yml
39-
# file containing these three dbt projects.
60+
# file containing these six dbt projects.
4061

4162

4263
class TestProfileTemplate:
@@ -51,6 +72,9 @@ class TestProfileTemplate:
5172
"test_sw_up_options" # nosec hardcoded_password_string
5273
)
5374
_TEST_SOFTWARE_PAT_PROFILE_PROJECT = "test_sw_pat_options"
75+
_TEST_SW_ENTERPRISE_CATALOG_PAT_PROFILE_PROJECT = "test_sw_enterprise_catalog_pat_options"
76+
_TEST_SW_ENTERPRISE_CATALOG_USER_PASSWORD_PROFILE_PROJECT = "test_sw_enterprise_catalog_up_options"
77+
_TEST_CLOUD_ENTERPRISE_CATALOG_PROFILE_PROJECT = "test_cloud_enterprise_catalog_options"
5478

5579
_PASSWORD_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS = {"password": None}
5680
_PAT_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS = {"pat": None}
@@ -71,6 +95,18 @@ class TestProfileTemplate:
7195
"port": 9047,
7296
"use_ssl": False,
7397
}
98+
_DREMIO_SW_ENTERPRISE_CATALOG_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS = {
99+
"enterprise_catalog_namespace": None,
100+
"enterprise_catalog_folder": None,
101+
"software_host": None,
102+
"port": 9047,
103+
"use_ssl": False,
104+
}
105+
_DREMIO_CLOUD_ENTERPRISE_CATALOG_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS = {
106+
"enterprise_catalog_namespace": None,
107+
"enterprise_catalog_folder": None,
108+
"use_ssl": False,
109+
}
74110

75111
_DREMIO_CLOUD_PROFILE_OPTIONS_WITH_DEFAULTS = (
76112
_COMMON_PROFILE_OPTIONS_WITH_DEFAULTS
@@ -87,6 +123,21 @@ class TestProfileTemplate:
87123
| _DREMIO_SW_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS
88124
| _PAT_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS
89125
)
126+
_DREMIO_SW_ENTERPRISE_CATALOG_USERNAME_PASSWORD_PROFILE_OPTIONS = (
127+
_COMMON_PROFILE_OPTIONS_WITH_DEFAULTS
128+
| _DREMIO_SW_ENTERPRISE_CATALOG_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS
129+
| _PASSWORD_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS
130+
)
131+
_DREMIO_SW_ENTERPRISE_CATALOG_PAT_PROFILE_OPTIONS = (
132+
_COMMON_PROFILE_OPTIONS_WITH_DEFAULTS
133+
| _DREMIO_SW_ENTERPRISE_CATALOG_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS
134+
| _PAT_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS
135+
)
136+
_DREMIO_CLOUD_ENTERPRISE_CATALOG_PROFILE_OPTIONS_WITH_DEFAULTS = (
137+
_COMMON_PROFILE_OPTIONS_WITH_DEFAULTS
138+
| _DREMIO_CLOUD_ENTERPRISE_CATALOG_PROFILE_SPECIFIC_OPTIONS_WITH_DEFAULTS
139+
| _PAT_AUTH_PROFILE_OPTIONS_WITH_DEFAULTS
140+
)
90141

91142
_PROFILE_OPTIONS_ALIASES = {
92143
"username": "UID",
@@ -98,6 +149,10 @@ class TestProfileTemplate:
98149
"dremio_space_folder": "schema",
99150
}
100151

152+
@pytest.mark.skipif(
153+
DREMIO_EDITION != "cloud",
154+
reason="Cloud options are not available in Dremio community/enterprise edition.",
155+
)
101156
def test_cloud_options(self) -> None:
102157
self._test_project_profile_options(
103158
self._get_dbt_test_project_dict(self._TEST_CLOUD_PROFILE_PROJECT),
@@ -125,6 +180,37 @@ def test_aliases(self) -> None:
125180
assert credential_option_aliases[option] is not None
126181
assert alias == credential_option_aliases[option]
127182

183+
184+
@pytest.mark.skipif(
185+
DREMIO_EDITION != "enterprise",
186+
reason="Dremio Software enterprise catalog options are specific to Dremio Enterprise edition.",
187+
)
188+
def test_sw_enterprise_catalog_username_password_options(self) -> None:
189+
self._test_project_profile_options(
190+
self._get_dbt_test_project_dict(self._TEST_SW_ENTERPRISE_CATALOG_USER_PASSWORD_PROFILE_PROJECT),
191+
self._DREMIO_SW_ENTERPRISE_CATALOG_USERNAME_PASSWORD_PROFILE_OPTIONS,
192+
)
193+
194+
@pytest.mark.skipif(
195+
DREMIO_EDITION != "enterprise",
196+
reason="Dremio Software enterprise catalog options are specific to Dremio Enterprise edition.",
197+
)
198+
def test_sw_enterprise_catalog_pat_options(self) -> None:
199+
self._test_project_profile_options(
200+
self._get_dbt_test_project_dict(self._TEST_SW_ENTERPRISE_CATALOG_PAT_PROFILE_PROJECT),
201+
self._DREMIO_SW_ENTERPRISE_CATALOG_PAT_PROFILE_OPTIONS,
202+
)
203+
204+
@pytest.mark.skipif(
205+
DREMIO_EDITION != "cloud",
206+
reason="Dremio Software enterprise catalog options are specific to Dremio Enterprise edition.",
207+
)
208+
def test_cloud_enterprise_catalog_options(self) -> None:
209+
self._test_project_profile_options(
210+
self._get_dbt_test_project_dict(self._TEST_CLOUD_ENTERPRISE_CATALOG_PROFILE_PROJECT),
211+
self._DREMIO_CLOUD_ENTERPRISE_CATALOG_PROFILE_OPTIONS_WITH_DEFAULTS,
212+
)
213+
128214
@pytest.mark.skip
129215
def _get_dbt_test_project_dict(self, dbt_test_project_name: str) -> Dict[str, any]:
130216
# read_profile returns dictionary with the following layout:
@@ -142,3 +228,30 @@ def _test_project_profile_options(
142228
assert test_project[option] is not None
143229
if test_options[option] is not None:
144230
assert test_project[option] == test_options[option]
231+
232+
class TestProfileValidation:
233+
@pytest.mark.skipif(
234+
DREMIO_EDITION == "community",
235+
reason="Enterprise catalog options are not available in Dremio community edition.",
236+
)
237+
def test_invalid_enterprise_catalog_profile(self) -> None:
238+
"""Test that using both enterprise catalog and space & source configs raises validation error."""
239+
from dbt_common.exceptions import DbtValidationError
240+
241+
# Simulate profile data with both enterprise catalog and individual storage configurations
242+
conflicting_data = {
243+
"enterprise_catalog_namespace": "my_enterprise_catalog",
244+
"enterprise_catalog_folder": "analytics_folder",
245+
"datalake": "my_source",
246+
"root_path": "my_path",
247+
"database": "my_space",
248+
"schema": "my_schema",
249+
"user": "test_user",
250+
"pat": "test_token",
251+
"threads": 1,
252+
"type": "dremio"
253+
}
254+
255+
# Verify that validation raises an error for conflicting configurations
256+
with pytest.raises(DbtValidationError, match="Cannot use both enterprise catalog and individual storage configurations"):
257+
DremioCredentials._validate_and_restructure_data(conflicting_data)

tests/functional/adapter/dremio_specific/test_twin_strategy.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
import os
12
import pytest
23
from tests.fixtures.profiles import unique_schema, dbt_profile_data
34

4-
from dbt.tests.util import run_dbt, write_file
5+
from dbt.tests.util import run_dbt, write_file, run_dbt_and_capture
56
from tests.utils.util import (
67
check_relation_types,
78
relation_from_name,
8-
get_connection
9+
get_connection,
10+
BUCKET
911
)
1012

13+
DREMIO_EDITION = os.getenv("DREMIO_EDITION")
14+
DREMIO_ENTERPRISE_CATALOG = os.getenv("DREMIO_ENTERPRISE_CATALOG")
15+
1116
schema_prevent_yml = """
1217
version: 2
1318
models:
@@ -231,3 +236,60 @@ def test_overwrite_table(self, project):
231236
assert columns_view[0].name == "table_column"
232237
assert len(columns_table) == 1
233238
assert columns_table[0].name == "table_column"
239+
240+
class TestTwinStrategyNotAppliedDremio:
241+
# Override unique_schema to be the schema defined in Jenkins tests, i.e., tests_functional_adapter_dremio_specific
242+
@pytest.fixture(scope="class")
243+
def unique_schema(self, request, prefix) -> str:
244+
test_file_path = request.module.__file__
245+
relative_path = os.path.relpath(test_file_path, os.getcwd())
246+
# Get directory path and remove filename
247+
dir_path = os.path.dirname(relative_path)
248+
# Replace '/' with '_' to create schema name
249+
test_file = dir_path.replace('/', '_')
250+
unique_schema = test_file
251+
return unique_schema
252+
253+
@pytest.fixture(scope="class")
254+
def models(self):
255+
return {
256+
"schema.yml": schema_allow_yml,
257+
"view_model.sql": view_model_sql,
258+
"table_model.sql": table_model_sql,
259+
}
260+
261+
@pytest.fixture(scope="class")
262+
def dbt_profile_data(
263+
self, unique_schema, dbt_profile_target, profiles_config_update
264+
):
265+
profile = {
266+
"test": {
267+
"outputs": {
268+
"default": {},
269+
},
270+
"target": "default",
271+
},
272+
}
273+
target = dbt_profile_target
274+
# For enterprise catalog: object_storage_source == dremio_space AND object_storage_path == dremio_space_folder
275+
# This maps to: target.datalake == target.database AND target.root_path == target.schema
276+
enterprise_catalog_name = DREMIO_ENTERPRISE_CATALOG
277+
target["schema"] = unique_schema
278+
target["root_path"] = unique_schema # Make object_storage_path == dremio_space_folder
279+
target["datalake"] = enterprise_catalog_name # Set object_storage_source to enterprise catalog
280+
target["database"] = enterprise_catalog_name # Set dremio_space to same enterprise catalog
281+
282+
profile["test"]["outputs"]["default"] = target
283+
if profiles_config_update:
284+
profile.update(profiles_config_update)
285+
return profile
286+
287+
@pytest.mark.skipif(DREMIO_EDITION == "community" or not DREMIO_ENTERPRISE_CATALOG, reason="Enterprise catalog is only supported in Dremio EE/DC editions.")
288+
def test_twin_strategy_not_applied_with_enterprise_catalog(self, project):
289+
# Run with twin_strategy configured but enterprise catalog enabled
290+
# Should show warning and not apply twin strategy
291+
(results, log_output) = run_dbt_and_capture(["--debug","run"])
292+
assert len(results) == 2 # Both models should build successfully
293+
294+
# Check that the warning message appears in the logs
295+
assert "WARNING: Twin strategy not applied - using enterprise catalog" in log_output

0 commit comments

Comments
 (0)