Skip to content

Commit 7a4fb28

Browse files
committed
test(connection, startup): support new startup message properties
1 parent ccb1473 commit 7a4fb28

File tree

5 files changed

+131
-0
lines changed

5 files changed

+131
-0
lines changed

test/integration/plugin/test_credentials_providers.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest # type: ignore
99

1010
import redshift_connector
11+
from redshift_connector import DriverInfo
1112

1213
conf = configparser.ConfigParser()
1314
root_path = os.path.dirname(os.path.dirname(os.path.abspath(os.path.join(__file__, os.pardir))))
@@ -160,3 +161,24 @@ def use_cached_temporary_credentials(idp_arg):
160161
# holds these
161162
assert len(redshift_connector.IamHelper.credentials_cache) == 1
162163
assert first_cred_cache_entry == redshift_connector.IamHelper.credentials_cache.popitem()
164+
165+
166+
@pytest.mark.skip
167+
# TODO: https://docs.aws.amazon.com/redshift/latest/dg/r_STL_CONNECTION_LOG.html plugin_name column character limit
168+
# TODO: causes field value cut-off
169+
@pytest.mark.parametrize("idp_arg", NON_BROWSER_IDP, indirect=True)
170+
def test_stl_connection_log_contains_plugin_name(idp_arg, db_kwargs):
171+
idp_arg["auto_create"] = True
172+
with redshift_connector.connect(**idp_arg) as conn:
173+
pass
174+
with redshift_connector.connect(**db_kwargs) as conn:
175+
with conn.cursor() as cursor:
176+
# verify stl_connection_log contains driver version as expected
177+
cursor.execute(
178+
"select top 1 1 from stl_connection_log where driver_version = '{}' and plugin_name = 'redshift_connector.plugin.{}'".format(
179+
DriverInfo.driver_full_name(), idp_arg["credentials_provider"]
180+
)
181+
)
182+
res = cursor.fetchone()
183+
assert res is not None
184+
assert res[0] == 1

test/integration/test_connection.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import configparser
22
import os
3+
import random
34
import socket
5+
import string
46
import struct
57
import sys
68

79
import pytest # type: ignore
810

911
import redshift_connector
12+
from redshift_connector import DriverInfo
1013
from redshift_connector.config import ClientProtocolVersion
1114

1215
conf = configparser.ConfigParser()
@@ -198,3 +201,49 @@ def test_client_protocol_version_invalid_warns_user(db_kwargs):
198201
del db_kwargs["cluster_identifier"]
199202
with pytest.warns(UserWarning):
200203
redshift_connector.Connection(**db_kwargs)
204+
205+
206+
def test_stl_connection_log_contains_driver_version(db_kwargs):
207+
with redshift_connector.connect(**db_kwargs) as conn:
208+
with conn.cursor() as cursor:
209+
# verify stl_connection_log contains driver version as expected
210+
cursor.execute(
211+
"select top 1 1 from stl_connection_log where driver_version = '{}'".format(
212+
DriverInfo.driver_full_name()
213+
)
214+
)
215+
res = cursor.fetchone()
216+
assert res is not None
217+
assert res[0] == 1
218+
219+
220+
def test_stl_connection_log_contains_os_version(db_kwargs):
221+
with redshift_connector.connect(**db_kwargs) as conn:
222+
with conn.cursor() as cursor:
223+
# verify stl_connection_log contains driver version as expected
224+
cursor.execute(
225+
"select top 1 1 from stl_connection_log where driver_version = '{}' and os_version = '{}'".format(
226+
DriverInfo.driver_full_name(), conn.client_os_version
227+
)
228+
)
229+
res = cursor.fetchone()
230+
assert res is not None
231+
assert res[0] == 1
232+
233+
234+
def test_stl_connection_log_contains_application_name(db_kwargs):
235+
# make some connection so this unique application name is logged
236+
mock_application_name: str = "".join(random.choice(string.ascii_letters) for x in range(10))
237+
db_kwargs["application_name"] = mock_application_name
238+
239+
with redshift_connector.connect(**db_kwargs) as conn:
240+
with conn.cursor() as cursor:
241+
# verify stl_connection_log contains driver version as expected
242+
cursor.execute(
243+
"select top 1 1 from stl_connection_log where driver_version = '{}' and application_name = '{}'".format(
244+
DriverInfo.driver_full_name(), mock_application_name
245+
)
246+
)
247+
res = cursor.fetchone()
248+
assert res is not None
249+
assert res[0] == 1

test/unit/test_connection.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import typing
22
from collections import deque
33
from decimal import Decimal
4+
from unittest.mock import patch
45

56
import pytest # type: ignore
67

@@ -310,3 +311,16 @@ def test_is_single_database_metadata(_input):
310311
mock_connection.parameter_statuses.append((b"datashare_enabled", param_status.encode()))
311312

312313
assert mock_connection.is_single_database_metadata == exp_val
314+
315+
316+
def test_client_os_version_is_present():
317+
mock_connection = Connection.__new__(Connection)
318+
assert mock_connection.client_os_version is not None
319+
assert isinstance(mock_connection.client_os_version, str)
320+
321+
322+
def test_client_os_version_is_not_present():
323+
mock_connection = Connection.__new__(Connection)
324+
325+
with patch("platform.platform", side_effect=Exception("not for you")):
326+
assert mock_connection.client_os_version == "unknown"

test/unit/test_driver_info.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import re
2+
3+
import pytest
4+
5+
from redshift_connector.utils import DriverInfo
6+
7+
8+
def test_version_is_not_none():
9+
assert DriverInfo.version() is not None
10+
11+
12+
def test_version_is_str():
13+
assert isinstance(DriverInfo.version(), str)
14+
15+
16+
def test_version_proper_format():
17+
version_regex = re.compile(r"^\d+(\.\d+){2,3}$")
18+
assert version_regex.match(DriverInfo.version())
19+
20+
21+
def test_driver_name_is_not_none():
22+
assert DriverInfo.driver_name() is not None
23+
24+
25+
def test_driver_short_name_is_not_none():
26+
assert DriverInfo.driver_short_name() is not None
27+
28+
29+
def test_driver_full_name_is_not_none():
30+
assert DriverInfo.driver_full_name() is not None
31+
32+
33+
def test_driver_full_name_contains_name():
34+
assert DriverInfo.driver_name() in DriverInfo.driver_full_name()
35+
36+
37+
def test_driver_full_name_contains_version():
38+
assert DriverInfo.version() in DriverInfo.driver_full_name()

test/unit/test_iam_helper.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ def test_set_iam_properties_fails_when_info_is_none(missing_param):
113113
assert "Invalid connection property setting" in str(excinfo.value)
114114

115115

116+
@pytest.mark.usefixtures("mock_set_iam_credentials")
117+
def test_set_iam_properties_fails_when_non_str_credential_provider():
118+
keywords: typing.Dict = {"credentials_provider": 1}
119+
with pytest.raises(InterfaceError) as excinfo:
120+
IamHelper.set_iam_properties(**get_set_iam_properties_args(**keywords))
121+
assert "Invalid connection property setting" in str(excinfo.value)
122+
123+
116124
ssl_mode_descriptions: typing.List[typing.Tuple[typing.Optional[str], str]] = [
117125
("verify-ca", "verify-ca"),
118126
("verify-full", "verify-full"),

0 commit comments

Comments
 (0)