Skip to content

Commit ef9283b

Browse files
unit tests for imp methods
Signed-off-by: varun-edachali-dbx <varun.edachali@databricks.com>
1 parent a0aa023 commit ef9283b

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

tests/unit/test_sea_http_client.py

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
import json
2+
import unittest
3+
from unittest.mock import patch, Mock, MagicMock
4+
import pytest
5+
6+
from databricks.sql.backend.sea.utils.http_client import SeaHttpClient
7+
from databricks.sql.auth.retry import CommandType
8+
from databricks.sql.auth.authenticators import AuthProvider
9+
from databricks.sql.types import SSLOptions
10+
from databricks.sql.exc import RequestError
11+
12+
13+
class TestSeaHttpClient:
14+
@pytest.fixture
15+
def mock_auth_provider(self):
16+
auth_provider = Mock(spec=AuthProvider)
17+
auth_provider.add_headers = Mock(return_value=None)
18+
return auth_provider
19+
20+
@pytest.fixture
21+
def ssl_options(self):
22+
return SSLOptions(
23+
tls_verify=True,
24+
tls_trusted_ca_file=None,
25+
tls_client_cert_file=None,
26+
tls_client_cert_key_file=None,
27+
tls_client_cert_key_password=None,
28+
)
29+
30+
@pytest.fixture
31+
def sea_http_client(self, mock_auth_provider, ssl_options):
32+
with patch(
33+
"databricks.sql.backend.sea.utils.http_client.HTTPSConnectionPool"
34+
) as mock_pool:
35+
client = SeaHttpClient(
36+
server_hostname="test-server.databricks.com",
37+
port=443,
38+
http_path="/sql/1.0/warehouses/abc123",
39+
http_headers=[("User-Agent", "test-agent")],
40+
auth_provider=mock_auth_provider,
41+
ssl_options=ssl_options,
42+
)
43+
# Replace the real pool with a mock
44+
client._pool = Mock()
45+
return client
46+
47+
def test_get_command_type_from_path(self, sea_http_client):
48+
"""Test the _get_command_type_from_path method with various paths and methods."""
49+
# Test statement execution
50+
assert (
51+
sea_http_client._get_command_type_from_path("/statements", "POST")
52+
== CommandType.EXECUTE_STATEMENT
53+
)
54+
55+
# Test statement cancellation
56+
assert (
57+
sea_http_client._get_command_type_from_path(
58+
"/statements/123/cancel", "POST"
59+
)
60+
== CommandType.OTHER
61+
)
62+
63+
# Test statement deletion (close operation)
64+
assert (
65+
sea_http_client._get_command_type_from_path("/statements/123", "DELETE")
66+
== CommandType.CLOSE_OPERATION
67+
)
68+
69+
# Test get statement status
70+
assert (
71+
sea_http_client._get_command_type_from_path("/statements/123", "GET")
72+
== CommandType.GET_OPERATION_STATUS
73+
)
74+
75+
# Test session close
76+
assert (
77+
sea_http_client._get_command_type_from_path("/sessions/456", "DELETE")
78+
== CommandType.CLOSE_SESSION
79+
)
80+
81+
# Test other paths
82+
assert (
83+
sea_http_client._get_command_type_from_path("/other/endpoint", "GET")
84+
== CommandType.OTHER
85+
)
86+
assert (
87+
sea_http_client._get_command_type_from_path("/other/endpoint", "POST")
88+
== CommandType.OTHER
89+
)
90+
91+
@patch(
92+
"databricks.sql.backend.sea.utils.http_client.SeaHttpClient._get_auth_headers"
93+
)
94+
def test_make_request_success(self, mock_get_auth_headers, sea_http_client):
95+
"""Test successful _make_request calls."""
96+
# Setup mock response
97+
mock_response = Mock()
98+
mock_response.status = 200
99+
mock_response.json.return_value = {"result": "success"}
100+
mock_response.__enter__ = Mock(return_value=mock_response)
101+
mock_response.__exit__ = Mock(return_value=None)
102+
103+
# Setup mock auth headers
104+
mock_get_auth_headers.return_value = {"Authorization": "Bearer test-token"}
105+
106+
# Configure the pool's request method to return our mock response
107+
sea_http_client._pool.request.return_value = mock_response
108+
109+
# Test GET request without data
110+
result = sea_http_client._make_request("GET", "/test/path")
111+
112+
# Verify the request was made correctly
113+
sea_http_client._pool.request.assert_called_with(
114+
method="GET",
115+
url="/test/path",
116+
body=b"",
117+
headers={
118+
"Content-Type": "application/json",
119+
"User-Agent": "test-agent",
120+
"Authorization": "Bearer test-token",
121+
},
122+
preload_content=False,
123+
retries=sea_http_client.retry_policy,
124+
)
125+
126+
# Check the result
127+
assert result == {"result": "success"}
128+
129+
# Test POST request with data
130+
test_data = {"query": "SELECT * FROM test"}
131+
result = sea_http_client._make_request("POST", "/statements", test_data)
132+
133+
# Verify the request was made with the correct body
134+
expected_body = json.dumps(test_data).encode("utf-8")
135+
sea_http_client._pool.request.assert_called_with(
136+
method="POST",
137+
url="/statements",
138+
body=expected_body,
139+
headers={
140+
"Content-Type": "application/json",
141+
"User-Agent": "test-agent",
142+
"Authorization": "Bearer test-token",
143+
"Content-Length": str(len(expected_body)),
144+
},
145+
preload_content=False,
146+
retries=sea_http_client.retry_policy,
147+
)
148+
149+
@patch(
150+
"databricks.sql.backend.sea.utils.http_client.SeaHttpClient._get_auth_headers"
151+
)
152+
def test_make_request_error_response(self, mock_get_auth_headers, sea_http_client):
153+
"""Test _make_request with error HTTP status."""
154+
# Setup mock response with error status
155+
mock_response = Mock()
156+
mock_response.status = 400
157+
mock_response.__enter__ = Mock(return_value=mock_response)
158+
mock_response.__exit__ = Mock(return_value=None)
159+
160+
# Setup mock auth headers
161+
mock_get_auth_headers.return_value = {"Authorization": "Bearer test-token"}
162+
163+
# Configure the pool's request method to return our mock response
164+
sea_http_client._pool.request.return_value = mock_response
165+
166+
# Test request with error response
167+
with pytest.raises(Exception) as excinfo:
168+
sea_http_client._make_request("GET", "/test/path")
169+
170+
assert "SEA HTTP request failed with status 400" in str(excinfo.value)
171+
172+
@patch(
173+
"databricks.sql.backend.sea.utils.http_client.SeaHttpClient._get_auth_headers"
174+
)
175+
def test_make_request_connection_error(
176+
self, mock_get_auth_headers, sea_http_client
177+
):
178+
"""Test _make_request with connection error."""
179+
# Setup mock auth headers
180+
mock_get_auth_headers.return_value = {"Authorization": "Bearer test-token"}
181+
182+
# Configure the pool's request to raise an exception
183+
sea_http_client._pool.request.side_effect = Exception("Connection error")
184+
185+
# Test request with connection error
186+
with pytest.raises(RequestError) as excinfo:
187+
sea_http_client._make_request("GET", "/test/path")
188+
189+
assert "Error during request to server" in str(excinfo.value)
190+
191+
def test_make_request_no_pool(self, sea_http_client):
192+
"""Test _make_request when pool is not initialized."""
193+
# Set pool to None to simulate uninitialized pool
194+
sea_http_client._pool = None
195+
196+
# Test request with no pool
197+
with pytest.raises(RequestError) as excinfo:
198+
sea_http_client._make_request("GET", "/test/path")
199+
200+
assert "Connection pool not initialized" in str(excinfo.value)

0 commit comments

Comments
 (0)