Skip to content

Commit

Permalink
feature: Add tests for Core package. (#57)
Browse files Browse the repository at this point in the history
* Update python.yaml

* Update release.yaml

* CP-2386 Add tests to Core.

* Revert "Update release.yaml"

This reverts commit ec93301.

* Update python.yaml
  • Loading branch information
joaomper-TE authored Oct 8, 2024
1 parent 71cf7d5 commit f7bb46b
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/python.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
# Initialize coverage data file
coverage erase
for module in $(find . -maxdepth 1 -type d -name "thousandeyes-sdk-*" ! -name "thousandeyes-sdk-core" | cut -c 3-); do
for module in $(find . -maxdepth 1 -type d -name "thousandeyes-sdk-*" | cut -c 3-); do
pip install -e $module
coverage run --source=$module -m pytest $module
# Move the .coverage file to a unique name
Expand Down
2 changes: 2 additions & 0 deletions thousandeyes-sdk-core/src/thousandeyes_sdk/core/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ def __deserialize(self, data, klass, models):
# convert str to class
if klass in self.NATIVE_TYPES_MAPPING:
klass = self.NATIVE_TYPES_MAPPING[klass]
elif klass == 'dict':
return data
else:
klass = getattr(models, klass)

Expand Down
124 changes: 124 additions & 0 deletions thousandeyes-sdk-core/test/test_api_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import pytest
import datetime
from unittest.mock import Mock, patch
from thousandeyes_sdk.core.api_client import ApiClient
from thousandeyes_sdk.core.configuration import Configuration
from thousandeyes_sdk.core import rest
from thousandeyes_sdk.core.exceptions import ApiException


@pytest.fixture
def api_client():
config = Configuration()
return ApiClient(configuration=config)


def test_api_client_initialization(api_client):
assert api_client.configuration is not None
assert isinstance(api_client.rest_client, rest.RESTClientObject)
assert api_client.default_headers == {}
assert api_client.cookie is None


def test_set_default_header(api_client):
api_client.set_default_header('X-Test-Header', 'test_value')
assert api_client.default_headers['X-Test-Header'] == 'test_value'


def test_user_agent_property(api_client):
api_client.user_agent = 'test-agent'
assert api_client.user_agent == 'test-agent'


def test_get_default():
default_client = ApiClient.get_default()
assert isinstance(default_client, ApiClient)


def test_set_default():
new_default = ApiClient()
ApiClient.set_default(new_default)
assert ApiClient.get_default() == new_default


def test_param_serialize(api_client):
method, url, headers, _, __ = api_client.param_serialize(
method='GET',
resource_path='/test/{id}',
path_params={'id': 1},
query_params={'aid': '12'},
header_params={'X-Test': 'test_value'}
)
assert method == 'GET'
print(url + "3")
assert url == api_client.configuration.host + '/test/1?aid=12'
assert headers['X-Test'] == 'test_value'


@patch('thousandeyes_sdk.core.rest.RESTClientObject.request')
def test_call_api(mock_request, api_client):
mock_response = Mock()
mock_response.data = b'{"dummyKey": "someValue"}'
mock_response.status = 200
mock_request.return_value = mock_response

response = api_client.call_api(
method='GET',
url='/tests',
body=None,
post_params=None,
_request_timeout=None
)
assert response.data == b'{"dummyKey": "someValue"}'
assert response.status == 200


@patch('thousandeyes_sdk.core.rest.RESTClientObject.request')
def test_call_api_exception(mock_request, api_client):
mock_request.side_effect = ApiException(status=404, reason="Not Found")
with pytest.raises(ApiException):
api_client.call_api(
method='GET',
url='/tests',
body=None,
post_params=None,
_request_timeout=None
)


def test_response_deserialize(api_client):
mock_response = Mock()
mock_response.data = b'{"dummyKey": "someValue"}'
mock_response.status = 200
mock_response.getheader.return_value = 'application/json'
mock_response.getheaders.return_value = {}

response = api_client.response_deserialize(
response_data=mock_response,
response_types_map={'200': 'dict'},
models={}
)
assert response.data == {"dummyKey": "someValue"}
assert response.status_code == 200


def test_sanitize_for_serialization(api_client):
data = {
'str': 'value',
'int': 1,
'float': 1.1,
'bool': True,
'datetime': datetime.datetime(2023, 1, 1),
'date': datetime.date(2023, 1, 1),
'list': [1, 2, 3],
'dict': {'key': 'value'}
}
sanitized = api_client.sanitize_for_serialization(data)
assert sanitized['str'] == 'value'
assert sanitized['int'] == 1
assert sanitized['float'] == 1.1
assert sanitized['bool'] is True
assert sanitized['datetime'] == '2023-01-01T00:00:00'
assert sanitized['date'] == '2023-01-01'
assert sanitized['list'] == [1, 2, 3]
assert sanitized['dict'] == {'key': 'value'}
48 changes: 48 additions & 0 deletions thousandeyes-sdk-core/test/test_api_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest
from pydantic import ValidationError
from thousandeyes_sdk.core.api_response import ApiResponse


def test_api_response_valid():
response = ApiResponse(
status_code=200,
headers={"Content-Type": "application/json"},
data={"key": "value"},
raw_data=b'{"key": "value"}'
)
assert response.status_code == 200
assert response.headers == {"Content-Type": "application/json"}
assert response.data == {"key": "value"}
assert response.raw_data == b'{"key": "value"}'


def test_api_response_missing_optional_headers():
response = ApiResponse(
status_code=200,
data={"key": "value"},
raw_data=b'{"key": "value"}'
)
assert response.status_code == 200
assert response.headers is None
assert response.data == {"key": "value"}
assert response.raw_data == b'{"key": "value"}'


def test_api_response_invalid_status_code():
with pytest.raises(ValidationError):
ApiResponse(
status_code="200", # Invalid type
headers={"Content-Type": "application/json"},
data={"key": "value"},
raw_data=b'{"key": "value"}'
)


def test_api_response_invalid_raw_data():
with pytest.raises(ValidationError):
ApiResponse(
status_code=200,
headers={"Content-Type": "application/json"},
data={"key": "value"},
raw_data="raw data" # Invalid type
)
43 changes: 43 additions & 0 deletions thousandeyes-sdk-core/test/test_thousandeyes_retry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import time
import pytest
from unittest.mock import Mock
from urllib3 import HTTPResponse
from thousandeyes_sdk.core.thousandeyes_retry import ThousandEyesRetry


def test_is_retry_on_429():
retry = ThousandEyesRetry()
assert retry.is_retry("GET", 429) is True


def test_is_retry_on_other_status():
retry = ThousandEyesRetry(status_forcelist=[500])
assert retry.is_retry("GET", 500) is True
assert retry.is_retry("GET", 404) is False


def test_get_retry_after_with_custom_header():
response = Mock(spec=HTTPResponse)
response.headers = {
"x-organization-rate-limit-reset": str(int(time.time()) + 100)}
retry = ThousandEyesRetry()
assert retry.get_retry_after(response) == pytest.approx(100, rel=1)


def test_get_retry_after_with_no_headers():
response = Mock(spec=HTTPResponse)
response.headers = {}
retry = ThousandEyesRetry()
assert retry.get_retry_after(response) is None


def test_parse_reset_header_valid():
retry = ThousandEyesRetry()
future_time = str(int(time.time()) + 100)
assert retry._parse_reset_header(future_time) == pytest.approx(100, rel=1)


def test_parse_reset_header_invalid():
retry = ThousandEyesRetry()
assert retry._parse_reset_header("invalid") is None
assert retry._parse_reset_header(None) is None

0 comments on commit f7bb46b

Please sign in to comment.