@@ -14,6 +14,7 @@ jobs:
|
|||||||
- { os: 'ubuntu-latest', python-version: "3.10" }
|
- { os: 'ubuntu-latest', python-version: "3.10" }
|
||||||
- { os: 'ubuntu-latest', python-version: "3.11" }
|
- { os: 'ubuntu-latest', python-version: "3.11" }
|
||||||
- { os: 'macos-latest', python-version: "3.11" }
|
- { os: 'macos-latest', python-version: "3.11" }
|
||||||
|
- { os: 'windows-latest', python-version: "3.11" }
|
||||||
|
|
||||||
name: test (os=${{ matrix.entry.os }}, python=${{ matrix.entry.python-version }})
|
name: test (os=${{ matrix.entry.os }}, python=${{ matrix.entry.python-version }})
|
||||||
continue-on-error: ${{ matrix.entry.experimental || false }}
|
continue-on-error: ${{ matrix.entry.experimental || false }}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|||||||
- Added a utf-8 header to all .py files ([#557](https://github.com/opensearch-project/opensearch-py/pull/557))
|
- Added a utf-8 header to all .py files ([#557](https://github.com/opensearch-project/opensearch-py/pull/557))
|
||||||
- Added `samples`, `benchmarks` and `docs` to `nox -rs format` ([#556](https://github.com/opensearch-project/opensearch-py/pull/556))
|
- Added `samples`, `benchmarks` and `docs` to `nox -rs format` ([#556](https://github.com/opensearch-project/opensearch-py/pull/556))
|
||||||
- Added guide on the document lifecycle API(s) ([#559](https://github.com/opensearch-project/opensearch-py/pull/559))
|
- Added guide on the document lifecycle API(s) ([#559](https://github.com/opensearch-project/opensearch-py/pull/559))
|
||||||
|
- Added Windows CI ([#569](https://github.com/opensearch-project/opensearch-py/pull/569))
|
||||||
### Changed
|
### Changed
|
||||||
- Generate `tasks` client from API specs ([#508](https://github.com/opensearch-project/opensearch-py/pull/508))
|
- Generate `tasks` client from API specs ([#508](https://github.com/opensearch-project/opensearch-py/pull/508))
|
||||||
- Generate `ingest` client from API specs ([#513](https://github.com/opensearch-project/opensearch-py/pull/513))
|
- Generate `ingest` client from API specs ([#513](https://github.com/opensearch-project/opensearch-py/pull/513))
|
||||||
|
|||||||
@@ -183,7 +183,9 @@ class AIOHttpConnection(AsyncConnection):
|
|||||||
ssl_context.check_hostname = False
|
ssl_context.check_hostname = False
|
||||||
ssl_context.verify_mode = ssl.CERT_NONE
|
ssl_context.verify_mode = ssl.CERT_NONE
|
||||||
|
|
||||||
ca_certs = self.default_ca_certs() if ca_certs is None else ca_certs
|
if ca_certs is None:
|
||||||
|
ca_certs = self.default_ca_certs()
|
||||||
|
|
||||||
if verify_certs:
|
if verify_certs:
|
||||||
if not ca_certs:
|
if not ca_certs:
|
||||||
raise ImproperlyConfigured(
|
raise ImproperlyConfigured(
|
||||||
|
|||||||
@@ -138,6 +138,11 @@ class Connection(object):
|
|||||||
raise TypeError("Unsupported equality check for %s and %s" % (self, other))
|
raise TypeError("Unsupported equality check for %s and %s" % (self, other))
|
||||||
return self.__hash__() == other.__hash__()
|
return self.__hash__() == other.__hash__()
|
||||||
|
|
||||||
|
def __lt__(self, other: object) -> bool:
|
||||||
|
if not isinstance(other, Connection):
|
||||||
|
raise TypeError("Unsupported lt check for %s and %s" % (self, other))
|
||||||
|
return self.__hash__() < other.__hash__()
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return id(self)
|
return id(self)
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ from typing import Any
|
|||||||
import aiohttp
|
import aiohttp
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest.mark.structures import MarkDecorator
|
from _pytest.mark.structures import MarkDecorator
|
||||||
from mock import patch
|
from mock import MagicMock, patch
|
||||||
from multidict import CIMultiDict
|
from multidict import CIMultiDict
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
|
|
||||||
@@ -254,26 +254,29 @@ class TestAIOHttpConnection:
|
|||||||
== str(w[0].message)
|
== str(w[0].message)
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch("ssl.SSLContext.load_verify_locations")
|
@patch("ssl.SSLContext", return_value=MagicMock())
|
||||||
async def test_uses_given_ca_certs(
|
async def test_uses_given_ca_certs(self, ssl_context: Any, tmp_path: Any) -> None:
|
||||||
self, load_verify_locations: Any, tmp_path: Any
|
|
||||||
) -> None:
|
|
||||||
path = tmp_path / "ca_certs.pem"
|
path = tmp_path / "ca_certs.pem"
|
||||||
path.touch()
|
path.touch()
|
||||||
|
ssl_context.return_value.load_verify_locations.return_value = None
|
||||||
AIOHttpConnection(use_ssl=True, ca_certs=str(path))
|
AIOHttpConnection(use_ssl=True, ca_certs=str(path))
|
||||||
load_verify_locations.assert_called_once_with(cafile=str(path))
|
ssl_context.return_value.load_verify_locations.assert_called_once_with(
|
||||||
|
cafile=str(path)
|
||||||
|
)
|
||||||
|
|
||||||
@patch("ssl.SSLContext.load_verify_locations")
|
@patch("ssl.SSLContext", return_value=MagicMock())
|
||||||
async def test_uses_default_ca_certs(self, load_verify_locations: Any) -> None:
|
async def test_uses_default_ca_certs(self, ssl_context: Any) -> None:
|
||||||
|
ssl_context.return_value.load_verify_locations.return_value = None
|
||||||
AIOHttpConnection(use_ssl=True)
|
AIOHttpConnection(use_ssl=True)
|
||||||
load_verify_locations.assert_called_once_with(
|
ssl_context.return_value.load_verify_locations.assert_called_once_with(
|
||||||
cafile=Connection.default_ca_certs()
|
cafile=Connection.default_ca_certs()
|
||||||
)
|
)
|
||||||
|
|
||||||
@patch("ssl.SSLContext.load_verify_locations")
|
@patch("ssl.SSLContext", return_value=MagicMock())
|
||||||
async def test_uses_no_ca_certs(self, load_verify_locations: Any) -> None:
|
async def test_uses_no_ca_certs(self, ssl_context: Any) -> None:
|
||||||
|
ssl_context.return_value.load_verify_locations.return_value = None
|
||||||
AIOHttpConnection(use_ssl=True, verify_certs=False)
|
AIOHttpConnection(use_ssl=True, verify_certs=False)
|
||||||
load_verify_locations.assert_not_called()
|
ssl_context.return_value.load_verify_locations.assert_not_called()
|
||||||
|
|
||||||
async def test_trust_env(self) -> None:
|
async def test_trust_env(self) -> None:
|
||||||
con: Any = AIOHttpConnection(trust_env=True)
|
con: Any = AIOHttpConnection(trust_env=True)
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ class TestTransport:
|
|||||||
|
|
||||||
async def test_request_will_fail_after_X_retries(self) -> None:
|
async def test_request_will_fail_after_X_retries(self) -> None:
|
||||||
t: Any = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}],
|
[{"exception": ConnectionError(None, "abandon ship", Exception())}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ class TestTransport:
|
|||||||
|
|
||||||
async def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
async def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
||||||
t: Any = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}] * 2,
|
[{"exception": ConnectionError(None, "abandon ship", Exception())}] * 2,
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -381,7 +381,10 @@ class TestTransport:
|
|||||||
|
|
||||||
async def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
async def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
||||||
t: Any = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[
|
||||||
|
{"exception": ConnectionError(None, "abandon ship", Exception())},
|
||||||
|
{"data": CLUSTER_NODES},
|
||||||
|
],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
max_retries=0,
|
max_retries=0,
|
||||||
@@ -407,7 +410,10 @@ class TestTransport:
|
|||||||
) -> None:
|
) -> None:
|
||||||
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
||||||
t: Any = AsyncTransport(
|
t: Any = AsyncTransport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[
|
||||||
|
{"exception": ConnectionError(None, "abandon ship", Exception())},
|
||||||
|
{"data": CLUSTER_NODES},
|
||||||
|
],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
max_retries=3,
|
max_retries=3,
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class TestTransport(TestCase):
|
|||||||
|
|
||||||
def test_request_will_fail_after_X_retries(self) -> None:
|
def test_request_will_fail_after_X_retries(self) -> None:
|
||||||
t: Any = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}],
|
[{"exception": ConnectionError(None, "abandon ship", Exception())}],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -275,7 +275,7 @@ class TestTransport(TestCase):
|
|||||||
|
|
||||||
def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
def test_failed_connection_will_be_marked_as_dead(self) -> None:
|
||||||
t: Any = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}] * 2,
|
[{"exception": ConnectionError(None, "abandon ship", Exception())}] * 2,
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -349,7 +349,10 @@ class TestTransport(TestCase):
|
|||||||
|
|
||||||
def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
def test_sniff_on_fail_triggers_sniffing_on_fail(self) -> None:
|
||||||
t: Any = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[
|
||||||
|
{"exception": ConnectionError(None, "abandon ship", Exception())},
|
||||||
|
{"data": CLUSTER_NODES},
|
||||||
|
],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
max_retries=0,
|
max_retries=0,
|
||||||
@@ -366,7 +369,10 @@ class TestTransport(TestCase):
|
|||||||
) -> None:
|
) -> None:
|
||||||
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
sniff_hosts.side_effect = [TransportError("sniff failed")]
|
||||||
t: Any = Transport(
|
t: Any = Transport(
|
||||||
[{"exception": ConnectionError("abandon ship")}, {"data": CLUSTER_NODES}],
|
[
|
||||||
|
{"exception": ConnectionError(None, "abandon ship", Exception())},
|
||||||
|
{"data": CLUSTER_NODES},
|
||||||
|
],
|
||||||
connection_class=DummyConnection,
|
connection_class=DummyConnection,
|
||||||
sniff_on_connection_fail=True,
|
sniff_on_connection_fail=True,
|
||||||
max_retries=3,
|
max_retries=3,
|
||||||
|
|||||||
Reference in New Issue
Block a user