@@ -181,3 +181,96 @@ def test_init_passes_valid_aws_kwargs(self):
181181 assert hook ._verify is False
182182 assert hook ._region_name == "us-west-2"
183183 assert hook ._config is not None
184+
185+
186+ class TestAthenaSQLHookOpenLineage :
187+ """Static tests for the OpenLineage methods on AthenaSQLHook."""
188+
189+ EXPECTED_INFORMATION_SCHEMA_COLUMNS = [
190+ "table_schema" ,
191+ "table_name" ,
192+ "column_name" ,
193+ "ordinal_position" ,
194+ "data_type" ,
195+ "table_catalog" ,
196+ ]
197+
198+ @staticmethod
199+ def _make_hook (connection : Connection , hook_region : str | None = None ) -> AthenaSQLHook :
200+ hook = AthenaSQLHook (region_name = hook_region ) if hook_region else AthenaSQLHook ()
201+ hook .get_connection = mock .Mock (return_value = connection ) # type: ignore[method-assign]
202+ return hook
203+
204+ @pytest .mark .parametrize (
205+ ("extras" , "hook_region" , "expected_authority" ),
206+ [
207+ # region from connection extras when hook-constructor region not set
208+ ({"region_name" : "us-east-1" }, None , "athena.us-east-1.amazonaws.com" ),
209+ # hook-constructor region (explicit user override) wins over extras region
210+ ({"region_name" : "eu-west-1" }, "us-east-2" , "athena.us-east-2.amazonaws.com" ),
211+ # hook-constructor region used when extras have none
212+ ({}, "ap-south-1" , "athena.ap-south-1.amazonaws.com" ),
213+ # graceful fallback when neither is set
214+ ({}, None , "athena.amazonaws.com" ),
215+ # aws_domain extra changes the domain (AWS GovCloud / China / ISO partitions)
216+ (
217+ {"region_name" : "cn-north-1" , "aws_domain" : "amazonaws.com.cn" },
218+ None ,
219+ "athena.cn-north-1.amazonaws.com.cn" ,
220+ ),
221+ # aws_domain still applied when region falls back
222+ ({"aws_domain" : "amazonaws.com.cn" }, None , "athena.amazonaws.com.cn" ),
223+ ],
224+ )
225+ def test_get_openlineage_database_info_region_extraction (self , extras , hook_region , expected_authority ):
226+ conn = Connection (conn_type = "athena" , schema = "default" , extra = extras )
227+ hook = self ._make_hook (conn , hook_region )
228+ info = hook .get_openlineage_database_info (conn )
229+ assert info .authority == expected_authority
230+
231+ def test_get_openlineage_database_info_returns_expected_fields (self ):
232+ """Snapshot of the DatabaseInfo shape so accidental changes are caught."""
233+ conn = Connection (
234+ conn_type = "athena" ,
235+ schema = "default" ,
236+ extra = {"region_name" : "us-east-1" },
237+ )
238+ hook = self ._make_hook (conn )
239+ info = hook .get_openlineage_database_info (conn )
240+ assert info .scheme == "awsathena"
241+ assert info .authority == "athena.us-east-1.amazonaws.com"
242+ assert info .database == "AwsDataCatalog"
243+ assert info .is_information_schema_cross_db is True
244+ assert info .information_schema_columns == self .EXPECTED_INFORMATION_SCHEMA_COLUMNS
245+
246+ def test_get_openlineage_database_info_custom_catalog (self ):
247+ conn = Connection (
248+ conn_type = "athena" ,
249+ schema = "default" ,
250+ extra = {"region_name" : "us-east-1" , "catalog" : "MyCatalog" },
251+ )
252+ hook = self ._make_hook (conn )
253+ info = hook .get_openlineage_database_info (conn )
254+ assert info .database == "MyCatalog"
255+
256+ def test_get_openlineage_database_dialect_returns_trino (self ):
257+ conn = Connection (conn_type = "athena" , extra = {"region_name" : "us-east-1" })
258+ hook = self ._make_hook (conn )
259+ assert hook .get_openlineage_database_dialect (conn ) == "trino"
260+
261+ @pytest .mark .parametrize (
262+ ("connection_schema" , "expected_schema" ),
263+ [
264+ ("mydb" , "mydb" ),
265+ (None , "default" ),
266+ ("" , "default" ),
267+ ],
268+ )
269+ def test_get_openlineage_default_schema (self , connection_schema , expected_schema ):
270+ conn = Connection (
271+ conn_type = "athena" ,
272+ schema = connection_schema ,
273+ extra = {"region_name" : "us-east-1" },
274+ )
275+ hook = self ._make_hook (conn )
276+ assert hook .get_openlineage_default_schema () == expected_schema
0 commit comments