44import time
55from unittest .mock import MagicMock , Mock , patch
66
7+ import boto3
78import botocore .exceptions
9+ import botocore .session
810import pytest
911from dbt_common .exceptions import DbtRuntimeError
1012
@@ -200,7 +202,6 @@ def test_assume_role_installs_assumed_default_session(
200202 self ._stub_endpoint_and_channel (submitter , monkeypatch )
201203
202204 assumed_session = Mock ()
203- assumed_session ._session = Mock ()
204205 get_session = Mock (return_value = assumed_session )
205206 setup_default = Mock ()
206207 monkeypatch .setattr (
@@ -210,11 +211,46 @@ def test_assume_role_installs_assumed_default_session(
210211 monkeypatch .setattr (
211212 "dbt.adapters.athena.spark_connect.job.boto3.setup_default_session" , setup_default
212213 )
214+ monkeypatch .setattr (
215+ "dbt.adapters.athena.spark_connect.job.boto3.DEFAULT_SESSION" , None , raising = False
216+ )
213217
214218 submitter .submit ("x = 1" )
215219
216220 get_session .assert_called_once_with (mock_credentials )
217- setup_default .assert_called_once_with (botocore_session = assumed_session ._session )
221+ assert boto3 .DEFAULT_SESSION is assumed_session
222+ setup_default .assert_not_called ()
223+
224+ def test_assume_role_default_session_survives_s3_client_creation (
225+ self , mock_credentials , spark_connect_parsed_model , monkeypatch
226+ ):
227+ # Regression: re-wrapping the assumed session as the default double-
228+ # registers boto3's s3 client-class handler, so boto3.client("s3")
229+ # raises a duplicate upload_file injection.
230+ mock_credentials .assume_role_arn = "arn:aws:iam::123456789012:role/dbt"
231+ mock_pool = Mock ()
232+ mock_pool .acquire .return_value = "sid-1"
233+ submitter = self ._make_submitter (spark_connect_parsed_model , mock_credentials , mock_pool )
234+ self ._stub_endpoint_and_channel (submitter , monkeypatch )
235+
236+ base = botocore .session .Session ()
237+ base .set_config_variable ("region" , "us-east-1" )
238+ assumed_session = boto3 .session .Session (
239+ botocore_session = base ,
240+ aws_access_key_id = "AKIA_ASSUMED" ,
241+ aws_secret_access_key = "SECRET" ,
242+ aws_session_token = "TOKEN" ,
243+ )
244+ monkeypatch .setattr (
245+ "dbt.adapters.athena.spark_connect.job.get_boto3_session_from_credentials" ,
246+ Mock (return_value = assumed_session ),
247+ )
248+ monkeypatch .setattr (boto3 , "DEFAULT_SESSION" , None , raising = False )
249+
250+ submitter .submit ("x = 1" )
251+
252+ boto3 .client ("s3" , region_name = "us-east-1" )
253+ assert boto3 .DEFAULT_SESSION is assumed_session
218254
219255 def test_no_assume_role_leaves_default_session_untouched (
220256 self , mock_credentials , spark_connect_parsed_model , monkeypatch
@@ -227,18 +263,23 @@ def test_no_assume_role_leaves_default_session_untouched(
227263
228264 get_session = Mock ()
229265 setup_default = Mock ()
266+ sentinel = Mock ()
230267 monkeypatch .setattr (
231268 "dbt.adapters.athena.spark_connect.job.get_boto3_session_from_credentials" ,
232269 get_session ,
233270 )
234271 monkeypatch .setattr (
235272 "dbt.adapters.athena.spark_connect.job.boto3.setup_default_session" , setup_default
236273 )
274+ monkeypatch .setattr (
275+ "dbt.adapters.athena.spark_connect.job.boto3.DEFAULT_SESSION" , sentinel , raising = False
276+ )
237277
238278 submitter .submit ("x = 1" )
239279
240280 get_session .assert_not_called ()
241281 setup_default .assert_not_called ()
282+ assert boto3 .DEFAULT_SESSION is sentinel
242283
243284 def test_transient_error_retries_with_new_session (
244285 self , mock_credentials , spark_connect_parsed_model , monkeypatch
0 commit comments